/* /css/viewer.css — 視聴者側の無彩色トーン (ワイヤー水準・2026-09-29 P1)。
   計画 = docs/planning/viewer-plain-look-plan-2026-09-29.md / 棚卸し = docs/notes/viewer-plain-look-p0-2026-09-29.md
   決定: D1 無彩色 (LIVE の赤だけ残す) / D2 ティッカーは残して平らに / D3 画像ロゴのまま / D4 プロフィールカード → ヘッダ。

   使い方: <body class="v-plain"> の面で、styles.css / index.css / shell.css の**後**に読む。
   その面では bubblegum.css と js/neon-init.js を読まない (bubblegum は 204/334 ルールが
   !important で、上から詳細度では勝てないため = P0 §1)。
   ショートは <body class="v-shorts"> で shorts.css / login-modal.css の後に読む (2026-10-01 P4-d)。
   効くのはトークンと、.v-shorts を併記したモーダル・年齢確認の規則だけ (黒い再生面は shorts.css が持つ)。

   ⚠ styles.css / bubblegum.css / neon-init.js / dashboard.css は書き換えない
     (ダッシュボードの broadcaster/live.html・lovense-settings.html も読むため)。
   ⚠ 値はダッシュボード (dashboard.css の --d-*) と同じにして同じトーンに見せるが、
     dashboard.css は参照しない (向こうの変更に引きずられないよう値だけ写す)。
   ⚠ !important は「影・光彩を消す一括指定」だけに使う。display には使わない
     (hidden 属性と JS の style.display を負かさない = hidden-vs-display の罠)。
     例外はトースト (2026-10-06) だけ — app.js が色を style に直書きしていて、!important でしか上書きできないため。 */

/* ── トークン: styles.css の :root (ネオン配色) を無彩色に読み替える ──
   2026-10-01 P4-d: ショート (<body class="v-shorts">) にも同じトークンを当てる。ショートは黒い再生面のまま (E1) で
   v-plain の外枠・地・影の一括消しは要らないが、共有のログインモーダル (login-modal.css の --b-*) と
   18 歳以上の確認 (age-gate.css) は他の視聴者面と同じ見た目にしたいので、トークンと下のモーダル・年齢確認の規則だけを共有する。
   地の色・字・字間は v-plain だけ (下の body.v-plain) */
body.v-plain, body.v-shorts {
  --v-bg: #f5f5f8;
  --v-side: #fbfbfd;
  --v-card: #ffffff;
  --v-ink: #23232a;
  --v-ink2: #5a5a66;
  --v-ink3: #8a8a96;
  --v-line: #dcdce4;
  --v-hover: #eeeef2;
  --v-live: #c0392b;

  /* styles.css の変数 (--pink 252 箇所・--cyan 88 箇所ほか) */
  --bg-0: var(--v-bg); --bg-1: var(--v-side); --bg-2: var(--v-card);
  --ink: var(--v-ink); --ink-dim: var(--v-ink2); --ink-mute: var(--v-ink3);
  --pink: var(--v-ink); --pink-glow: var(--v-ink2); --blood: var(--v-ink);
  /* ⚠ :root の --primary: var(--pink) は :root の時点でピンクに確定して継がれるので、読み替えた --pink を
     拾わない (index.css のランキング期間タブが桃色のまま残った)。対応する別名もここで定義し直す */
  --primary: var(--v-ink); --primary-light: var(--v-ink2); --primary-dark: var(--v-ink);
  --cyan: var(--v-ink2); --cyan-dim: var(--v-ink3);
  --yellow: var(--v-ink); --purple: var(--v-ink2); --lime: #3a6b4a;
  --bg-main: var(--v-bg); --bg-sidebar: var(--v-side); --bg-card: var(--v-card);
  --bg-hover: var(--v-hover); --bg-input: #fff; --bg-dark: var(--v-ink);
  --text-primary: var(--v-ink); --text-secondary: var(--v-ink2); --text-muted: var(--v-ink3); --text-light: #fff;
  --border-light: var(--v-line); --border-medium: #c8c8d2;
  --live: var(--v-live); --scheduled: var(--v-ink2); --danger: var(--v-live);
  --shadow-sm: none; --shadow-md: none; --shadow-lg: none;
  --glow-pink: none; --glow-cyan: none; --glow-gold: none;
  --crt-line: transparent;
  /* shell.css / home.css が fallback 付きで読む bubblegum の変数 */
  --b-ink: var(--v-ink); --b-ink2: var(--v-ink2); --b-ink3: var(--v-ink3);
  --b-pink: var(--v-ink); --b-pinkS: var(--v-hover); --b-card: var(--v-card);
  --b-border-thin: 1px solid var(--v-line); --b-border: 1px solid var(--v-line);
  /* 2026-09-30 P4-a: 共有ログインモーダル (login-modal.css・ダッシュボードも読むので書き換えない) の入力欄の地。
     未定義だと fallback の淡いピンク #fff8fb に落ちる。v-plain の面で var(--b-bg) を使うのはこの入力欄だけ */
  --b-bg: #fff;
  /* 同じく「新規登録」(.login-secondary) の文字色。未定義だと fallback の濃いピンク #d6075e */
  --b-pinkD: var(--v-ink);
  /* 2026-10-01 P4-d: 登録後の案内 (.login-hint・本番の Firebase で新規登録した直後に出る) の線。
     未定義だと fallback の淡いピンク #ffa4c4 のまま残っていた (P4-a の取り残し) */
  --b-pinkE: var(--v-line);
  /* モーダル・ボタンのずらした影。v-plain は下の一括指定で消えるが、ショートには一括指定が無い */
  --b-shadow-lg: none; --b-shadow-sm: none;
}
body.v-plain {
  background: var(--v-bg);
  color: var(--v-ink);
  font-family: 'M PLUS Rounded 1c', 'Zen Maru Gothic', "Hiragino Sans", "Yu Gothic UI", "Meiryo", system-ui, sans-serif;
  letter-spacing: normal;
}
html:has(> body.v-plain) { background: #f5f5f8; }
body.v-plain::before, body.v-plain::after { content: none; display: none; }
.v-plain .seed-rain, .v-plain .crt-overlay { display: none; }
/* ネオンの光彩は styles.css の各所に直書きされているので一括で消す (見た目だけ・display は触らない) */
.v-plain, .v-plain * { text-shadow: none !important; }
.v-plain *:not(:focus-visible) { box-shadow: none !important; }
/* 2026-10-02: 上の一括指定が届かない光彩の取り残し (#948 の所見 3・10-02 の一巡の ⑥)。styles.css は書き換えない。
   ① filter の drop-shadow (styles.css の 13 規則: ロゴ・ルビーの図・サイドのアイコンほか)。
      ⚠ filter は一括で消さない — 光彩ではない filter (utilities.css の blur(20px)) まで消えてしまう。
      詳細度は styles.css の各規則以上にする (ルビーの図は .nav-item-icon img[src*=…] 等 (0,2,1) があるので body. を付ける) */
.v-plain .logo-banner-img,
body.v-plain img[src*="ruby.svg"],
.v-plain .nav-item-icon, .v-plain .nav-item.active .nav-item-icon,
.v-plain .sidebar-menu a svg, .v-plain .sidebar-menu a.active svg,
.v-plain .empty-favorites svg, .v-plain .pinned-icon, .v-plain .hamster-loader img,
.v-plain .chat-stamp-img, .v-plain .chat-gift-img, .v-plain .settings-section-title svg { filter: none; }
/* ② ::before / ::after の 2px の線とその光彩 (`*` は疑似要素に当たらないので一括指定が効かない)。
   モーダルの上端・法的ページのモーダル・設定の節・告知板・カード・ネオンの看板 */
.v-plain .modal-content::before, .v-plain .legal-modal::before, .v-plain .settings-section::before,
.v-plain .notice-board::before, .v-plain .card::before, .v-plain .card::after, .v-plain .stream-card::before,
.v-plain .neon-sign::before, .v-plain .neon-sign::after { content: none; display: none; }
/* ③ 入力欄のフォーカス。一括指定は :focus-visible を残す (フォーカスの印のため) ので、styles.css の
   input:focus / .chat-input:focus / .login-input:focus のピンクの影がそのまま出ていた。
   影は消し、印は .form-input:focus と同じ墨の線にする (枠の色を変えない入力欄で、印が無くならないように)。
   ⚠ 詳細度 (0,2,2): 下の .v-plain .yob-field input など (0,2,1) の枠の色に負けないように body. を付ける */
body.v-plain input:focus, body.v-plain textarea:focus, body.v-plain select:focus { border-color: var(--v-ink); box-shadow: none; }
/* 2026-10-06: styles.css の入力欄の既定 (黒に近い紫の地 #0a0310・淡いピンクの線・Space Mono) が、ページ側で上書きして
   いない素の <textarea> / <select> に残る (見本の要素で実測)。今の 10 面の実在の入力欄は地と線については上書き済み
   (staging で 0 件・書体は下の規則で揃える) なので、これは備え。詳細度は styles.css の textarea / select (0,0,1) と
   同じに保つ (:where で .v-plain を数えない) —
   ページ側のクラス付きの規則には負けるので、既存の入力欄の見た目は変わらない。
   ⚠ input[type=text] などは含めない: styles.css 側が (0,1,1) で、同じ詳細度で上書きすると、ページ側の同じ詳細度の
   規則 (先に読む watch.css など) まで負かしてしまうため */
:where(.v-plain) textarea, :where(.v-plain) select { background: #fff; color: var(--v-ink); border-color: var(--v-line); border-radius: 0; font-family: inherit; }
/* 2026-10-06 (オーナー判断 2「他に合わせて」): styles.css が本文以外の書体を当てている規則 (セレクタ 135 個) を、
   v-plain の面ではまとめて打ち消し、本文の書体 (body.v-plain の M PLUS Rounded 1c ほか) を継がせる。
   #969 で旧デザインの Space Mono の 85 個 (入力欄 19 種類・ラベル・補足・サイドの見出し・フッター・ボタン・チャットの時刻・
   取引の日付・配信者のタグなど。Space Mono には和字が無く、日本語は端末の既定の等幅で出ていた)、続けて残りの 50 個
   (VT323・Monoton・Rubik Mono One・Zen Kaku Gothic New ほか。見出しの和字・ルビー管理の金額・無料でもらう方法・
   チャットのスタンプ／プレゼントの金額・法的モーダルの題と見出しなど) を足した。プロトも欄・本文とも本文の書体。
   - セレクタは styles.css の「inherit 以外の font-family / font を持つ規則」のセレクタを、最初に出た順にそのまま並べる
     (視聴者の面で使わないものも含めて全部。足し漏れは scripts/faulttest/viewer-plain-font.test.mjs が書体名に依らず落とす)。
     body は並べない (body.v-plain が本文の書体を持つ)
   - 詳細度は .v-plain (0,1,0) ＋ :is() の中のいちばん強いもの (.top-bar .logo・.empty-count .k などの (0,2,0)) = (0,3,0)。
     50 個を足しても中の最大は (0,2,0) のままで変わらない。:is() は中のどれに当たっても最大の詳細度で数えるので、
     元の規則 (どれも (0,2,0) 以下) に読み込み順に関係なく勝つ。font-family だけを書く (地・線・角・字間は触らない)。
     ページ側で同じ要素に別の書体を (0,3,0) 以下で書いても、ここが勝つ (2026-10-06 時点で、ページ側の CSS に inherit 以外の書体は無い)
   - 実測 (2026-10-06・静的配信の 10 面＋後から描かれる要素の見本): Space Mono 0 件・それ以外の要素の書体の変化 0 件。
     残り 50 個の実測はこのファイルの末尾近くの「本文以外の書体の残り」の節
   - .toast は styles.css が !important なので、下のトーストの規則で !important を付けて打ち消す */
.v-plain :is(.seed-rain span, .top-bar .logo, .version-badge, .crumbs .lead, .crumbs .page, .live-chip, .seedbox .v, .seedbox .l, .btn-header-logout, .btn-logout, .user-points-row, .user-points-link, .user-points-link-btn, .nav-section-title, .sidebar-badge, .open-badge, .sign-open, .sign-name, .sign-sub, .sign-stars, .btn, .btn-primary, .btn-point-purchase, .btn-point-purchase.primary, .card-header h2, .section-title, .section-title .ja, .section-link, .section-action, .ticker-label, .ticker-track, .notice-date, .news-date, .notice-tag, .news-tag, .news-arrow, .stream-viewers, .stream-time, .status-badge, .badge, .ribbon-label, .neon-sign, .empty-title, .empty-burrow-title, .empty-sub, .empty-burrow-sub, .empty-count .k, .empty-count .v, .empty-transactions, .sched-day .dow, .sched-day .date, .sched-day .pill, .sched-empty-note .tag, .refresh, .form-label, .form-input, input[type="text"], input[type="email"], input[type="password"], input[type="number"], input[type="search"], input[type="datetime-local"], input[type="date"], textarea, select, .form-hint, .modal-title, .chat-message-time, .chat-input, .ranking-position, .ranking-desc, th, .hamster-loader-text, .login-box h1, .login-box .subtitle, .home-link, .admin-badge, .dashboard-tab, .live-tab-placeholder h2, .control-drawer-toggle, .control-drawer-header h2, .control-drawer-section-title, .widget-field-pct, .widget-overlay-telop, .widget-list-compact-type, .widget-editor-opacity-val, .widget-editor-color-text, .widget-editor-rotation-val, .widget-editor-rotation-num, .live-current-scene-badge, .widget-row-pos, .broadcaster-version-chip, .broadcaster-header h1, .free-method-points, .footer-burrow, .toast, .market-product-type-badge, .market-product-purchased-badge, .market-product-price, .market-product-sales, .cast-count, .filter-btn, .ranking-tab, .ranking-period-tab, .product-detail-title, .product-detail-price, .product-detail-thumbnail-label, .product-detail-hero-empty, .product-detail-preview-notice, .product-detail-image-count, .product-hero-counter, .broadcaster-product-price, .broadcaster-tag, .broadcaster-social-btn, .chat-time, .chat-stamp-cost, .chat-gift-cost, .transaction-date, .transaction-amount, .empty-history, .login-title, .signup-title, .login-input, .signup-input, .btn-login, .btn-signup, .login-divider, .btn-mobile-login, .confirm-title, .settings-section-title, .legal-modal-title, .legal-modal-body h1, .legal-modal-body h2, .legal-modal-body h3, .legal-modal-body form label) { font-family: inherit; }
/* 2026-10-06 (オーナー判断「上書き」): トースト。共有の app.js (書き換えない) の App.showToast は、色・角丸・影を style に
   直書きしている (エラー #dc3545・成功 #28a745・警告 #f39c12・通常 #333・角丸 8px)。インラインは !important でしか
   上書きできないので、ここは上の「影・光彩を消す一括指定」以外の !important の例外 (トーストだけ)。
   見た目はプロト .prototoast (墨の地・白・12px・角なし)。エラーだけ E2 の赤 (LIVE と同じ #c0392b) にする
   (割り込みの通知 = role=alert と対で、目でも区別できるように)。
   ショート (.v-shorts) には当てない: shorts.html は app.js を読まず、トーストを出す経路が無い (2026-10-06 実測) */
body.v-plain .toast {
  background: var(--v-ink) !important; color: #fff !important; border-radius: 0 !important;
  box-shadow: none !important; font-size: 12px !important; padding: 8px 14px !important;
  /* 2026-10-06: styles.css の .toast が !important で付けている Space Mono・字間・白い枠線も外す (プロト .prototoast は無い) */
  font-family: inherit !important; letter-spacing: normal !important; border: none !important;
}
body.v-plain .toast.toast-error { background: var(--v-live) !important; }
/* 2026-10-07 (計画 D1・残りの一覧 G4): 演出の文字 (shell-auth.js の showHimataneAnimation =「+N ログインボーナス」
   「アカウント作成!」「-N ルビー」。utilities.css の .u-c-e91f68ab が赤い太字) を、墨の地に白い字の札にする (上のトースト・
   プロト .prototoast と同じ形)。⚠ 字だけを墨にすると、視聴では画面の中央 = 黒い映像の上に重なって読めない (墨と黒で 1.35:1。
   影は上の一括指定で消えている)。札なら明るい地でも暗い地でも読める (白と墨で 15.6:1)。
   GIF (inline の img) の下に置くので inline-block にはしない (横に並ぶ)。display:table で字の幅に縮め、margin auto で中央に。
   GIF を残すか (O12) とは別。詳細度 (0,2,0) > utilities.css (0,1,0)。ダッシュボード (broadcaster.js) の同じクラスは v-plain の外 */
.v-plain .u-c-e91f68ab { color: #fff; background: var(--v-ink); padding: 4px 10px; display: table; margin: 4px auto 0; }
.v-plain a { color: inherit; }

/* ── ヘッダ ── */
.v-plain .top-bar {
  background: #fafafc; border-bottom: 1px solid var(--v-line);
  backdrop-filter: none; -webkit-backdrop-filter: none; padding: env(safe-area-inset-top, 0px) 16px 0;
}
.v-plain .top-bar::after, .v-plain .top-bar .logo::after { content: none; display: none; }
/* styles.css の .top-bar .logo は縁取りの装飾フォント (Monoton) で、中の版表示 (.version-badge) がそれを継ぐ */
.v-plain .top-bar .logo { color: var(--v-ink); font-family: inherit; font-size: 13px; letter-spacing: normal; }
.v-plain .logo-banner-img { height: 34px; width: auto; display: block; }
.v-plain .version-badge { color: var(--v-ink3); font-family: inherit; letter-spacing: normal; }
.v-plain .top-bar-actions { gap: 10px; }
/* NOW STREAMING (home.js が配信中だけ出す) — 平らな札 */
.v-plain .b-now-badge { background: #fff; border: 1px solid var(--v-line); color: var(--v-ink); font-size: 11px; padding: 2px 8px; border-radius: 0; }
.v-plain .b-now-badge svg { display: none; }
.v-plain .b-now-badge { white-space: nowrap; }
.v-plain .b-now-dot { background: var(--v-live); }
/* スマホ幅: ログイン中はヘッダにベル・残高・再取得・アバター・☰ が並ぶので、札は赤い点だけ・「ルビー」の字は出さない
   (375px で「配/信/中」が縦に折れた・staging 実測 2026-09-30)。札そのものの表示は home.js が切り替えるので中身だけ隠す */
@media (max-width: 768px) {
  .v-plain .b-now-badge > span:first-child { display: none; }
  .v-plain .b-now-badge { padding: 0; border: 0; background: none; }
  .v-plain .b-now-badge .b-now-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; }
  .v-plain .vh-ruby small { display: none; }
}
/* 未ログイン: ヘッダのログイン (D4)。モバイル専用ボタンは同じ役なので出さない */
.v-plain .btn-mobile-login { display: none; }
.v-plain .btn-mobile-menu { background: none; border: 0; color: var(--v-ink); font-size: 18px; padding: 4px 8px; }
.v-plain .vh-login { display: flex; align-items: center; gap: 8px; }
.v-plain .vh-login .login-error:empty { display: none; }
.v-plain .vh-login .login-error { font-size: 11px; color: var(--v-live); }
/* ログイン中: 💎 残高 + 再取得 + アバター (メニュー) */
.v-plain #userSection { display: none; } /* JS (app.js / shell-auth.js) が style.display で出す */
.v-plain .vh-me { display: flex; align-items: center; gap: 6px; position: relative; }
/* 2026-10-08 (O11): 💎 はルビー面へのリンク (<a>)。下線を出さない */
.v-plain .vh-ruby { display: inline-flex; align-items: center; gap: 4px; font-size: 13px; font-weight: 700; color: var(--v-ink); padding: 2px 4px; text-decoration: none; }
.v-plain .vh-ruby img { width: 16px; height: 16px; }
.v-plain .vh-ruby small { font-size: 9px; font-weight: 400; color: var(--v-ink3); }
.v-plain .vh-refresh { display: inline-flex; padding: 2px; color: var(--v-ink3); }
.v-plain .vh-avbtn { display: inline-flex; padding: 0; border-radius: 50%; }
.v-plain #userAvatar { width: 28px; height: 28px; border-radius: 50%; overflow: hidden; display: flex; align-items: center; justify-content: center; background: var(--v-hover); }
.v-plain #userAvatar img, .v-plain #userAvatar svg { width: 28px; height: 28px; object-fit: cover; }
.v-plain .vh-menu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 200; min-width: 180px;
  background: #fff; border: 1.5px solid var(--v-ink); padding: 4px 0;
}
.v-plain .vh-menu-name { padding: 8px 12px; font-size: 12px; font-weight: 700; border-bottom: 1px solid #eeeef2; }
.v-plain .vh-menu a, .v-plain .vh-menu button {
  display: block; width: 100%; text-align: left; padding: 8px 12px; font: inherit; font-size: 12px;
  color: #3a3a44; background: none; border: 0; border-bottom: 1px solid #eeeef2; cursor: pointer; text-decoration: none;
}
.v-plain .vh-menu a:hover, .v-plain .vh-menu button:hover { background: var(--v-hover); }
.v-plain .vh-menu #headerLogoutBtn { color: var(--v-live); border-bottom: 0; }

/* ── サイド ── */
.v-plain .sidebar { background: var(--v-side); border-right: 1px solid var(--v-line); padding: 12px 10px 40px; }
.v-plain .sidebar::before { content: none; display: none; }
.v-plain .sidebar-nav .nav-section { gap: 1px; }
/* 見出しは日本語だけ (英字の小見出しを出さない = プロト) */
.v-plain .nav-section-title { font-size: 0; letter-spacing: normal; margin: 14px 0 6px; padding: 0 4px; color: var(--v-ink3); }
.v-plain .nav-section-title::before, .v-plain .nav-section-title::after { content: none; display: none; }
.v-plain .nav-section-title .ja { font-size: 11px; margin: 0; color: var(--v-ink3); letter-spacing: normal; }
.v-plain .sidebar-nav .nav-item {
  background: none; border: 0; border-radius: 3px; color: #3a3a44;
  font-size: 13px; font-weight: 400; padding: 7px 6px; letter-spacing: normal;
}
.v-plain .sidebar-nav .nav-item:hover { background: var(--v-hover); color: var(--v-ink); transform: none; }
.v-plain .sidebar-nav .nav-item.active { background: var(--v-ink); color: #fff; font-weight: 700; }
.v-plain .nav-item-icon { color: inherit; }
.v-plain .nav-item.active .nav-item-icon { color: #fff; background: none; }
.v-plain .shell-sub-live { background: var(--v-live); }

/* ── 本文 ── */
.v-plain .main-content { background: transparent; padding: 16px 22px 60px; }
.v-plain .section-header { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 10px; border: 0; padding: 0; }
.v-plain .section-header::before, .v-plain .section-header::after { content: none; display: none; }
/* 見出しは日本語だけ (「ON AIR」「SHORTS」等の英字を出さない = プロト)。英字はテキストノードなので文字サイズ 0 で消す */
.v-plain .section-title { font-size: 0; font-weight: 700; letter-spacing: normal; color: var(--v-ink); font-family: inherit; }
/* 和字の見出しの太さ: styles.css の .section-title .ja は旧書体 Zen Kaku Gothic New に合わせた 900 (極太)。
   プロトの見出し (proto.css .sec > header b = 15px・b の太字 700) に揃える (2026-10-06) */
.v-plain .section-title .ja { font-size: 15px; font-weight: 700; letter-spacing: normal; margin: 0; color: var(--v-ink); }
.v-plain .section-title::before, .v-plain .section-title::after { content: none; display: none; }

/* ── ボタン (dashboard.css の .dbtn と同じ見え方) ── */
.v-plain .btn { border-radius: 0; font-family: inherit; letter-spacing: normal; font-size: 12px; transform: none; }
.v-plain .btn-primary, .v-plain .btn-login { background: var(--v-ink); color: #fff; border: 1px solid var(--v-ink); border-radius: 0; }
.v-plain .btn-secondary, .v-plain .btn-signup, .v-plain .outline { background: #fff; color: var(--v-ink); border: 1px solid var(--v-ink); border-radius: 0; }
.v-plain .btn-login, .v-plain .btn-signup { font-size: 12px; padding: 6px 12px; font-family: inherit; cursor: pointer; }
.v-plain .btn:hover, .v-plain .btn-login:hover, .v-plain .btn-signup:hover { opacity: 0.85; transform: none; }

/* ── モーダル (ログイン / 新規登録 / プロフィール編集) ── */
.v-plain .modal-overlay { background: rgba(35, 35, 42, 0.45); }
.v-plain .modal-content { background: #fff; color: var(--v-ink); border: 1.5px solid var(--v-ink); border-radius: 0; }
.v-plain .modal-header { border-bottom: 1px solid #eeeef2; }
.v-plain .modal-title { color: var(--v-ink); font-size: 15px; font-family: inherit; letter-spacing: normal; }
.v-plain .modal-close { color: var(--v-ink2); background: none; border: 0; }
.v-plain .form-label { color: var(--v-ink2); font-size: 12px; }
.v-plain .form-input { background: #fff; color: var(--v-ink); border: 1px solid var(--v-line); border-radius: 0; }
.v-plain .form-input:focus { border-color: var(--v-ink); outline: none; }
.v-plain .form-hint { color: var(--v-ink3); }
.v-plain .modal-error { color: var(--v-live); }
.v-plain .modal-actions { border-top: 1px solid #eeeef2; }
.v-plain .modal-or-divider { color: var(--v-ink3); }
.v-plain .modal-or-divider::before, .v-plain .modal-or-divider::after { background: var(--v-line); }
.v-plain .modal-signup-row { border-top: 1px solid #eeeef2; color: var(--v-ink2); }
/* 共有ログインモーダル <dialog class="livestream-login-modal"> (openViewerLogin・P4 の面が読む login-modal.css)。
   login-modal.css はダッシュボードも読むので書き換えず、色は上の --b-* の読み替えで、幕と角だけここで上書きする (2026-09-30 P4-a)。
   2026-10-01 P4-d: ショート (.v-shorts) のいいね → ログインも同じモーダルなので、同じ規則を当てる */
.v-plain .livestream-login-modal, .v-shorts .livestream-login-modal { border: 1.5px solid var(--v-ink); border-radius: 0; }
.v-plain .livestream-login-modal::backdrop, .v-shorts .livestream-login-modal::backdrop { background: rgba(30, 30, 36, 0.45); }
.v-plain .livestream-login-modal .login-field input,
.v-plain .livestream-login-modal .login-google,
.v-plain .livestream-login-modal .login-primary,
.v-plain .livestream-login-modal .login-secondary,
.v-plain .livestream-login-modal .login-hint,
.v-shorts .livestream-login-modal .login-field input,
.v-shorts .livestream-login-modal .login-google,
.v-shorts .livestream-login-modal .login-primary,
.v-shorts .livestream-login-modal .login-secondary,
.v-shorts .livestream-login-modal .login-hint { border-radius: 0; }
/* エラーは赤 (--b-pinkD / --b-pinkE の読み替えだと黒・灰になる) */
.v-plain .livestream-login-modal .login-error,
.v-shorts .livestream-login-modal .login-error { color: var(--v-live); background: #fff; border: 1px solid var(--v-live); border-radius: 0; }
/* ショートには v-plain の「影を一括で消す」指定が無いので、:hover で浮かせる影 (login-modal.css の 3px 3px 0) をここで消す。
   login-modal.css の規則 (0,4,0) より強くするため :not(:disabled) まで書く */
.v-shorts .livestream-login-modal .login-google:hover:not(:disabled),
.v-shorts .livestream-login-modal .login-primary:hover:not(:disabled),
.v-shorts .livestream-login-modal .login-secondary:hover:not(:disabled) { box-shadow: none; }
.v-plain .modal-link-btn { color: var(--v-ink); }
.v-plain .btn-login-google { background: #fff; color: var(--v-ink); border: 1px solid var(--v-line); border-radius: 0; }
/* 2026-10-07 (計画 D1・残りの一覧 G3): ヘッダの 💎 から開く「ルビー購入（準備中）」のモーダル (app.js の showPointPurchaseModal)。
   ⚠ app.js・utilities.css はダッシュボードも読むので書き換えず、ここで上書きする。行き先 (O11) は変えない。
   枠は上の .modal-content と同じ角 0・墨の線。中の「準備中」の箱 (.u-c-a5b6cd1f・橙のグラデーション・角丸) は、ルビー管理の
   同じ札 (points.css の #purchaseSection .coming-soon-banner) と同じ破線の箱・墨の字にし、中の字の大きさもそれに揃える
   (題 15px・本文 12px)。「無料でルビーを獲得する」(.u-c-96141a64) は .v-plain .btn / .btn-primary で墨の地・角 0 になって
   いるが、utilities.css の角丸 8px を直接打ち消しておく。
   幕 (#pointPurchaseModal.point-purchase-modal-overlay・app-runtime.css の黒 50%) も、ほかの v-plain のモーダルの幕
   (.modal-overlay・年齢確認・法務) と同じ墨 45% にそろえる。
   詳細度: app-runtime.css・utilities.css の規則はどれも (0,1,0) で、ここは (0,2,0) 以上 = 読み込み順に依らず勝つ */
.v-plain .point-purchase-modal-overlay { background: rgba(35, 35, 42, 0.45); }
.v-plain .point-purchase-modal { background: #fff; color: var(--v-ink); border: 1.5px solid var(--v-ink); border-radius: 0; }
.v-plain .point-purchase-modal-header { border-bottom: 1px solid #eeeef2; }
.v-plain .point-purchase-modal-close { border-radius: 0; }
.v-plain .point-purchase-modal .u-c-a5b6cd1f { background: #fafafc; border: 1px dashed #c8c8d2; border-radius: 0; color: var(--v-ink); padding: 20px; }
.v-plain .point-purchase-modal .u-c-017d22a2 { font-size: 15px; }
.v-plain .point-purchase-modal .u-c-2e69da2b { font-size: 12px; color: var(--v-ink2); opacity: 1; }
.v-plain .point-purchase-modal .u-c-96141a64 { border-radius: 0; }

/* ── 年齢確認 ① 18 歳以上の確認 (age-gate.js が後から読む age-gate.css を ID で上書き) ──
   ⚠ age-gate.js / age-gate.css はダッシュボードの broadcaster/live.html も読むので書き換えない。
   .v-plain を前に付けて詳細度を上げる (後から読まれても勝つ)。見た目はプロトの年齢確認①と同じ。
   2026-10-01 P4-d: ショート (.v-shorts) を直接開いた人にも同じ確認が出る (age-gate.js) ので、同じ規則を当てる。
   ショートには影の一括消しが無いので、札の影 (age-gate.css の 0 8px 32px) もここで消す */
.v-plain #age-gate-overlay, .v-shorts #age-gate-overlay { background: rgba(35, 35, 42, 0.92); font-family: inherit; }
.v-plain #age-gate-card, .v-shorts #age-gate-card { background: #fff; color: var(--v-ink); border: 1.5px solid var(--v-ink); border-radius: 0; padding: 32px 28px; box-shadow: none; }
.v-plain #age-gate-logo, .v-shorts #age-gate-logo { color: var(--v-ink); font-size: 16px; letter-spacing: normal; margin-bottom: 14px; }
/* 2026-10-08 (オーナー決定・残りの一覧 O12): ロゴのハムスターの GIF は出さない (文字だけ)。要素は共有の age-gate.js が
   作るので、ここで隠す (age-gate.css の #age-gate-logo-img (1,0,0) に .v-plain の分で勝つ。age-gate.css に !important は無い) */
.v-plain #age-gate-logo-img, .v-shorts #age-gate-logo-img { display: none; }
.v-plain #age-gate-warning, .v-shorts #age-gate-warning { color: var(--v-ink2); font-size: 13px; margin-bottom: 20px; }
.v-plain #age-gate-enter, .v-plain #age-gate-leave,
.v-shorts #age-gate-enter, .v-shorts #age-gate-leave { border-radius: 0; font-size: 13px; padding: 12px 0; font-family: inherit; }
.v-plain #age-gate-enter, .v-shorts #age-gate-enter { background: var(--v-ink); color: #fff; border: 1px solid var(--v-ink); }
.v-plain #age-gate-enter:hover, .v-shorts #age-gate-enter:hover { background: #3a3a44; }
.v-plain #age-gate-leave, .v-shorts #age-gate-leave { background: #fff; color: var(--v-ink); border: 1px solid var(--v-ink); }
.v-plain #age-gate-leave:hover, .v-shorts #age-gate-leave:hover { background: var(--v-hover); }

/* ── 年齢確認 ② 生年入力 (dialog / age-yob-gate.js) ── */
.v-plain .live-yob-gate { background: #fff; color: var(--v-ink); border: 1.5px solid var(--v-ink); border-radius: 0; }
.v-plain .live-yob-gate::backdrop { background: rgba(35, 35, 42, 0.45); }
.v-plain .yob-card h2 { font-size: 15px; color: var(--v-ink); font-family: inherit; }
.v-plain .yob-field input { background: #fff; color: var(--v-ink); border: 1px solid var(--v-line); border-radius: 0; }
.v-plain .yob-error { color: var(--v-live); }

/* ── ティッカー (D2: 残して平らな 1 行) ──
   2026-09-30 オーナー「INFO がちょっと太い・上下の空白を調整」: styles.css の高さ 40px → 28px。
   流れる文字は styles.css の VT323 16px のままだった (下の span の font-family: inherit が .ticker-track の
   VT323 を継いでいた = staging 実測) → track ごと本文の字・12px にして、帯の太さを文字に合わせる */
.v-plain .ticker { height: 28px; background: #fff; border: 1px solid var(--v-line); border-radius: 0; margin-bottom: 16px; }
.v-plain .ticker-label { background: var(--v-ink); color: #fff; font-family: inherit; font-size: 10px; letter-spacing: normal; padding: 0 10px; }
.v-plain .ticker-track { font-family: inherit; font-size: 12px; letter-spacing: normal; }
.v-plain .ticker-track span, .v-plain .ticker-track b, .v-plain .ticker-track em, .v-plain .ticker-track i { color: var(--v-ink2); font-style: normal; font-family: inherit; }
.v-plain .ticker-track b { color: var(--v-ink); }

/* ── 通知 (notifications.js のベルとポップオーバー) ──
   ⚠ ベル #notifBell は notifications.js が .btn-header-logout のクラスで描く (ログアウトと同じ見た目の流用) */
.v-plain .btn-header-logout {
  background: #fff; color: var(--v-ink); border: 1px solid var(--v-line); border-radius: 0;
  padding: 4px 8px; font-size: 12px; font-family: inherit; letter-spacing: normal; cursor: pointer;
}
.v-plain .notif-panel { background: #fff; color: var(--v-ink); border: 1.5px solid var(--v-ink); border-radius: 0; }
.v-plain .notif-item { color: var(--v-ink); border-bottom: 1px solid #eeeef2; }
.v-plain .notif-item:hover { background: var(--v-hover); }
.v-plain .notif-empty { color: var(--v-ink3); }
/* 2026-10-07 (計画 D1・残りの一覧 G2): 未読バッジ・未読の点・「全て既読」の色。notifications.js の桃色のインラインを
   クラスに替え、色はここで付ける。見た目はプロト (proto-ui2.js の notificationsHtml・proto.css:196-208):
   未読の点 = LIVE と同じ赤 (proto.css:207 の #c0392b = --v-live)・「全て既読」= 白地に灰の線の四角いボタン (proto.css:197)・
   未読行の地なし (プロトは太字と点だけ。.notif-item.is-unread は印だけで、ここでは地を付けない)。
   件数のバッジはプロトに無い — 残すかは判断待ち (O10) なので残し、墨にする (赤は LIVE だけ = D1)。
   詳細度 (0,2,0)。styles.css ほかに .notif-badge / .notif-dot / .notif-readall の規則は無い */
.v-plain .notif-badge { background: var(--v-ink); color: #fff; }
.v-plain .notif-dot { background: var(--v-live); }
.v-plain .notif-readall {
  background: #fff; color: var(--v-ink2); border: 1px solid #d0d0d8; border-radius: 0;
  padding: 3px 8px; font-size: 11px; cursor: pointer;
}
/* 2026-10-16 (オーナー決定: お知らせはトップの帯とベルの両方): パネルの本人宛ての一覧の上の「運営からのお知らせ」の段
   (notifications.js の renderNotices)。行は <button class="notif-notice">。見た目は本人宛ての行 (.notif-item) に揃える:
   未読 = 太字と赤い点 (点は .notif-dot = LIVE と同じ赤・既読の行では隠す)・地なし。種類の札は灰の線の四角、
   重要・メンテナンス (.is-loud) は墨の地に白い字。本文は 2 行で畳み、押すと全文 (.is-open)。改行は pre-wrap で保つ。
   ⚠ 段の箱 (.notif-notices) は hidden 属性で出し入れするので display を書かない (hidden-vs-display の罠) */
.v-plain .notif-notices { border-bottom: 1px solid var(--v-line); }
.v-plain .notif-notices-h { padding: 8px 12px 2px; font-size: 11px; font-weight: 700; color: var(--v-ink3); }
.v-plain .notif-notice {
  display: block; width: 100%; text-align: left; background: none; border: 0; border-bottom: 1px solid #eeeef2; border-radius: 0;
  padding: 8px 12px 10px; font: inherit; color: var(--v-ink); cursor: pointer;
}
.v-plain .notif-notice:last-child { border-bottom: 0; }
.v-plain .notif-notice:hover { background: var(--v-hover); }
.v-plain .notif-notice-head { display: flex; align-items: center; gap: 6px; min-width: 0; }
.v-plain .notif-notice .notif-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
.v-plain .notif-notice:not(.is-unread) .notif-dot { display: none; }
.v-plain .notif-notice-type { flex: 0 0 auto; font-size: 10px; font-weight: 700; line-height: 16px; padding: 0 5px; border: 1px solid #d0d0d8; color: var(--v-ink2); }
.v-plain .notif-notice.is-loud .notif-notice-type { background: var(--v-ink); border-color: var(--v-ink); color: #fff; }
.v-plain .notif-notice-title { flex: 1; min-width: 0; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v-plain .notif-notice.is-unread .notif-notice-title { font-weight: 700; }
.v-plain .notif-notice-body {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden;
  margin-top: 3px; font-size: 12px; line-height: 1.5; color: var(--v-ink2); white-space: pre-wrap; overflow-wrap: anywhere;
}
.v-plain .notif-notice.is-open .notif-notice-title { white-space: normal; overflow-wrap: anywhere; }
.v-plain .notif-notice.is-open .notif-notice-body { display: block; -webkit-line-clamp: unset; line-clamp: none; overflow: visible; }
.v-plain .notif-notice-when { display: block; margin-top: 2px; font-size: 11px; color: var(--v-ink3); }

/* ── フッター (法務 5 本・ADR-14 D8) ── */
.v-plain .footer-burrow { background: transparent; border-top: 1px solid var(--v-line); color: var(--v-ink3); }
.v-plain .footer-burrow::before { content: none; display: none; }
.v-plain .footer-burrow-link { color: var(--v-ink2); }
.v-plain .footer-burrow-link:hover { color: var(--v-ink); }

/* ── 独立面の部品: 色だけ無彩色に (配置をプロトへ寄せるのは P3)。styles.css の直書きのグラデーション・rgba を打ち消す ── */
.v-plain .ranking-period-tab { background: #fff; color: var(--v-ink2); border: 1px solid var(--v-line); border-radius: 0; }
.v-plain .ranking-period-tab:hover { color: var(--v-ink); border-color: var(--v-ink); background: #fff; }
.v-plain .ranking-period-tab.active { background: var(--v-ink); color: #fff; border-color: var(--v-ink); }
.v-plain .ranking-grid { background: #fff; border: 1px solid var(--v-line); border-radius: 0; }
.v-plain .ranking-empty, .v-plain .ranking-empty-title, .v-plain .ranking-empty-sub { color: var(--v-ink2); }
.v-plain .cast-card { background: #fff; border: 1px solid var(--v-line); border-radius: 0; }
.v-plain .cast-card:hover { border-color: var(--v-ink); transform: none; }
.v-plain .cast-avatar { border: 1px solid var(--v-line); background: var(--v-hover); }
.v-plain .cast-name { color: var(--v-ink); }
.v-plain .cast-search-input { background: #fff; color: var(--v-ink); border: 1px solid var(--v-line); border-radius: 0; }
.v-plain .filter-btn { background: #fff; color: var(--v-ink2); border: 1px solid var(--v-line); border-radius: 0; }
.v-plain .filter-btn.active { background: var(--v-ink); color: #fff; border-color: var(--v-ink); }
.v-plain .live-chip { background: #fff; color: var(--v-ink2); border: 1px solid var(--v-line); border-radius: 0; }
.v-plain .live-chip.active { background: var(--v-ink); color: #fff; border-color: var(--v-ink); }
.v-plain .live-chip .dot { background: var(--v-live); }

/* ── 配信カード (app.js の .stream-card・トップ①とライブ一覧) = プロト card.scard ──
   ⚠ app.js はダッシュボードの broadcaster/live.html も読むので書き換えない。見た目だけここで当てる */
.v-plain .card.stream-card { display: block; background: #fff; border: 1px solid var(--v-line); border-radius: 0; transform: none; overflow: hidden; padding: 0; }
/* styles.css の .card::before / ::after はネオンの線 (カード上下の 2px のグラデーション) */
.v-plain .card.stream-card::before, .v-plain .card.stream-card::after { content: none; display: none; }
.v-plain .card.stream-card:hover { border-color: var(--v-ink); transform: none; }
.v-plain .stream-thumbnail { aspect-ratio: 16 / 9; background: #e2e2e8; border-radius: 0; border: 0; position: relative; overflow: hidden; }
.v-plain .stream-thumbnail > img { width: 100%; height: 100%; object-fit: cover; display: block; }
.v-plain .stream-thumbnail-auto { background: #e2e2e8; }
/* 自動サムネ = アバターを中央に丸く (styles.css と同じ寸法)。
   ⚠ styles.css は箱を display: grid (place-items: center) にしており、行が auto だと画像の height: 55% が
   枠の高さに解決されず、画像の元寸 (308px) で枠からはみ出していた (staging 実測・2026-09-30)。
   flex の中央寄せにすると % が枠の高さに解決される (81px = 55%・中央を実測) */
.v-plain .stream-thumbnail .stream-thumbnail-auto { display: flex; align-items: center; justify-content: center; }
.v-plain .stream-thumbnail .stream-thumbnail-auto img { width: auto; height: 55%; aspect-ratio: 1 / 1; border-radius: 50%; object-fit: cover; }
/* サムネに重ねたアバターは出さない (プロトはメタ行のアバターだけ) */
.v-plain .stream-icon-container { display: none; }
.v-plain .stream-status { top: 6px; left: 6px; gap: 4px; }
.v-plain .status-badge { border-radius: 0; font-size: 10px; font-weight: 700; padding: 2px 6px; letter-spacing: 0.02em; border: 0; font-family: inherit; }
.v-plain .status-badge.live { background: var(--v-live); color: #fff; }
.v-plain .status-badge.paid { background: var(--v-ink); color: #fff; }
.v-plain .status-badge.scheduled { background: var(--v-ink2); color: #fff; }
.v-plain .stream-info { padding: 8px; color: var(--v-ink2); background: #fff; }
.v-plain .stream-title { color: var(--v-ink); font-family: inherit; font-size: 12px; font-weight: 700; letter-spacing: normal; }
.v-plain .stream-meta, .v-plain .stream-time { color: var(--v-ink2); font-size: 11px; }
.v-plain .streamer-avatar { border: 0; background: none; }
.v-plain .streamer-avatar img { border: 0; border-radius: 50%; }
.v-plain .streamer-name { color: var(--v-ink2); }

/* ── トップ (index.html・P2) = プロト index.html ① 今配信中 → ② 新着ショート → ③ 登録チャンネルのショート → ④ チャンネル ── */
.v-plain .home-page > section { margin-bottom: 26px; }
/* 「すべて見る →」はプロトに無いが、一覧へ移る導線なので残し、控えめな文字リンクにする */
.v-plain .home-page .section-header .btn {
  background: none; border: 0; padding: 2px 0; font-size: 12px; color: var(--v-ink2); text-decoration: underline; text-underline-offset: 3px;
}
.v-plain .home-page .section-header .btn:hover { color: var(--v-ink); opacity: 1; }
/* 運営からのお知らせの帯 (js/notice-banner.js・ティッカーの下・① の前。2026-10-16 オーナー決定: トップの帯とベルの両方に出す)。
   段 (#homeNoticeSection) は hidden で出し入れする (home.css の .home-page section[hidden] が消す)。段そのものに display を書かない。
   帯 = 白地に灰の線・種類の札は灰の線の四角。重要・メンテナンス (.is-loud) は墨の地に白い字 (トースト・ティッカーの札と同じ墨。
   赤は LIVE だけ = D1)。本文は改行を保ち (pre-wrap)、3 行に収まらないときは畳んで「全文を表示」(.home-notice-more) を出す */
.v-plain .home-page > #homeNoticeSection { margin-bottom: 16px; }
.v-plain .home-notice { display: flex; align-items: flex-start; gap: 10px; background: #fff; color: var(--v-ink); border: 1px solid var(--v-line); padding: 10px 12px; }
.v-plain .home-notice-main { flex: 1; min-width: 0; }
.v-plain .home-notice-head { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.v-plain .home-notice-type { flex: 0 0 auto; font-size: 10px; font-weight: 700; line-height: 16px; padding: 0 6px; border: 1px solid #d0d0d8; color: var(--v-ink2); }
.v-plain .home-notice-title { min-width: 0; font-size: 13px; font-weight: 700; overflow-wrap: anywhere; }
.v-plain .home-notice-body { margin: 4px 0 0; font-size: 12px; line-height: 1.6; color: var(--v-ink2); white-space: pre-wrap; overflow-wrap: anywhere; }
.v-plain .home-notice-body.is-clamped { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3; overflow: hidden; }
.v-plain .home-notice.is-long .home-notice-body { cursor: pointer; }
.v-plain .home-notice-more { margin-top: 2px; padding: 0; background: none; border: 0; border-radius: 0; font-size: 11px; color: var(--v-ink2); text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.v-plain .home-notice-close { flex: 0 0 auto; padding: 0 2px; background: none; border: 0; border-radius: 0; font-size: 18px; line-height: 1; color: var(--v-ink2); cursor: pointer; }
.v-plain .home-notice-close:hover, .v-plain .home-notice-more:hover { color: var(--v-ink); }
.v-plain .home-notice.is-loud { background: var(--v-ink); color: #fff; border-color: var(--v-ink); }
.v-plain .home-notice.is-loud .home-notice-type { background: #fff; border-color: #fff; color: var(--v-ink); }
.v-plain .home-notice.is-loud .home-notice-body,
.v-plain .home-notice.is-loud .home-notice-more,
.v-plain .home-notice.is-loud .home-notice-close,
.v-plain .home-notice.is-loud .home-notice-close:hover,
.v-plain .home-notice.is-loud .home-notice-more:hover { color: #fff; }
/* ② ③ ショート (9:16) = プロト card.shcard */
.v-plain .home-shorts-strip { gap: 10px; padding: 0 0 6px; }
.v-plain .home-short { flex-basis: 130px; color: var(--v-ink); }
.v-plain .home-short-thumb { border: 0; border-radius: 0; background: #e2e2e8; }
.v-plain .home-short-live { border-radius: 0; background: var(--v-live); font-size: 9px; padding: 2px 6px; letter-spacing: normal; }
.v-plain .home-short-upcoming { border-radius: 0; background: var(--v-ink); font-size: 9px; padding: 2px 6px; }
.v-plain .home-short-meta { margin-top: 5px; }
.v-plain .home-short-name { font-size: 11px; color: var(--v-ink); }
.v-plain .home-short-caption { font-size: 11px; color: #3a3a44; }
@media (max-width: 768px) { .v-plain .home-short { flex-basis: 112px; } }
/* ④ チャンネル (丸アバター) = プロト cell.chcell */
.v-plain .home-channel-avatar { max-width: 64px; }
.v-plain .home-channel-avatar img { border: 0; background: #e2e2e8; }
.v-plain .home-channel.is-live .home-channel-avatar img { outline: 2px solid var(--v-live); outline-offset: 2px; }
.v-plain .home-channel-live { border-radius: 0; background: var(--v-live); font-size: 9px; font-weight: 700; letter-spacing: normal; line-height: 14px; padding: 0 5px; }
/* 2026-09-30 オーナー判断 A: LIVE 札はアバターの**上端**へ。下端は上位 3 の帯「3位・月」(rank-frames.js) の場所で、
   配信中かつ上位 3 の人は札が帯に縦 10px 重なって帯の文字が隠れていた (ローカル実測)。
   枠の有無にかかわらず同じ位置にして、ホーム④の中で札の位置をそろえる (home.css の bottom: -4px を打ち消す) */
.v-plain .home-channel-live { top: -4px; bottom: auto; }
.v-plain .home-channel-name { font-size: 11px; font-weight: 400; color: #3a3a44; }
.v-plain .home-channel:hover .home-channel-avatar img { transform: none; }
/* 読み込み中 (ハムスターの GIF) は残す。文言だけ色を合わせる */
.v-plain .hamster-loader-text { color: var(--v-ink3); font-family: inherit; }

/* ══ P3 (2026-09-30): 独立面の配置をプロトへ ══════════════════════════════════════════════
   プロト live.html / channels.html / ranking.html / subscriptions.html / likes.html と同じ並び。
   行の形は同日 ADR-14 D4・D7 を改訂して採用 (オーナー判断 F1=A)。P3 で見送った「最終配信 N 日前」・
   ランキングの紹介文と上位 3 の枠は「P3 の続き」で入れた (P4 計画 §7)。チャンネル一覧のジャンルの
   チップは**不採用** (ADR-14 D7 どおり検索欄のまま)。 */

/* ── チャンネル / 登録チャンネル = プロト chrow (1 列の横長の行) ── */
.v-plain .cast-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; border-top: 1px solid #eeeef2; }
.v-plain .cast-card {
  display: flex; align-items: center; gap: 14px; padding: 12px 8px; min-height: 0;
  background: none; border: 0; border-bottom: 1px solid #eeeef2; border-radius: 0; text-decoration: none; color: inherit;
}
.v-plain .cast-card:hover { background: #fafafc; border-color: #eeeef2; }
.v-plain .cast-avatar { width: 64px; height: 64px; flex: 0 0 64px; border: 0; border-radius: 50%; overflow: hidden; background: #e2e2e8; margin: 0; }
.v-plain .cast-avatar img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
.v-plain .cast-info {
  flex: 1; min-width: 0; display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 12px; align-items: center; text-align: left;
}
.v-plain .cast-name { grid-column: 1; font-size: 14px; font-weight: 700; color: var(--v-ink); display: flex; align-items: center; gap: 6px; min-width: 0; }
.v-plain .cast-name-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v-plain .cast-bio {
  grid-column: 1; font-size: 12px; color: var(--v-ink2); margin: 2px 0 0; min-height: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; -webkit-line-clamp: unset; display: block;
}
/* 従の 1 行「配信中」/「最終配信 N 日前」/「まだ配信していません」= プロト chrow-sub (P3 の続き) */
.v-plain .cast-sub { grid-column: 1; font-size: 11px; color: var(--v-ink3); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 行に「チャンネル登録」ボタンは置かない (2026-10-06 オーナー判断・ADR-14 D7)。行のボタンの規則 (.fav-toggle) は撤去した。
   .btn-favorite は視聴ページの登録ボタン (登録済み = 白地に墨の線) が使う */
.v-plain .btn-favorite { background: #fff; color: var(--v-ink); border: 1px solid var(--v-ink); }
/* 行の LIVE 印 = プロトの「● LIVE」。channels.js / subscriptions.js は既存のユーティリティ u-c-e1be9604
   (赤い角丸の札) で描くので、JS は変えずに行の中だけ文字の印へ上書きする */
.v-plain .cast-name .u-c-e1be9604 { background: none; color: var(--v-live); font-size: 10px; font-weight: 700; padding: 0; margin: 0; border-radius: 0; white-space: nowrap; }
.v-plain .cast-name .u-c-e1be9604::before { content: "● "; }
.v-plain .cast-count { font-size: 12px; color: var(--v-ink3); margin: 0 0 6px; }
.v-plain .cast-search { gap: 8px; margin-bottom: 10px; }
.v-plain .cast-search-input { height: 32px; font-size: 12px; }
.v-plain .cast-search .btn { background: #fff; color: var(--v-ink); border: 1px solid var(--v-ink); font-size: 12px; letter-spacing: normal; font-family: inherit; }
@media (max-width: 768px) {
  .v-plain .cast-avatar { width: 48px; height: 48px; flex-basis: 48px; }
}

/* ── ランキング = プロト (順位の数字 → アバター → 名前 → ● LIVE の横長の行) ── */
.v-plain .ranking-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; background: none; border: 0; border-top: 1px solid #eeeef2; padding: 0; }
.v-plain .ranking-card {
  display: flex; align-items: center; gap: 14px; padding: 12px 8px; background: none; border: 0; border-bottom: 1px solid #eeeef2;
  border-radius: 0; text-decoration: none; color: inherit; transform: none;
}
.v-plain .ranking-card:hover { background: #fafafc; transform: none; }
/* 順位は数字だけ (金・銀・銅のグラデーションは使わない = プロト chrow-rank) */
.v-plain .ranking-no, .v-plain .ranking-no.gold, .v-plain .ranking-no.silver, .v-plain .ranking-no.bronze {
  flex: 0 0 28px; width: 28px; height: auto; text-align: center; font-size: 15px; font-weight: 700; color: var(--v-ink);
  background: none; border: 0; border-radius: 0; font-family: inherit;
}
.v-plain .ranking-avatar { width: 64px; height: 64px; flex: 0 0 64px; border: 0; border-radius: 50%; overflow: hidden; background: #e2e2e8; }
.v-plain .ranking-avatar img { image-rendering: auto; border-radius: 50%; }
.v-plain .ranking-name { flex: 1; min-width: 0; font-size: 14px; font-weight: 700; color: var(--v-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 名前・紹介 1 行・従の 1 行を縦に積む (P3 の続き・ADR-14 D4 改訂)。紹介の無い人は名前と従の 1 行 */
.v-plain .ranking-mid { flex: 1; min-width: 0; }
.v-plain .ranking-bio { font-size: 12px; color: var(--v-ink2); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v-plain .ranking-sub { font-size: 11px; color: var(--v-ink3); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v-plain .ranking-live { font-size: 10px; font-weight: 700; color: var(--v-live); background: none; border: 0; padding: 0; white-space: nowrap; }
.v-plain .ranking-period-tabs { gap: 0; margin-bottom: 8px; }
.v-plain .ranking-period-tab + .ranking-period-tab { border-left: 0; }
.v-plain #streamRankingDescription { font-size: 11px; color: var(--v-ink2); margin: 0 0 10px; }
@media (max-width: 768px) {
  .v-plain .ranking-avatar { width: 48px; height: 48px; flex-basis: 48px; }
}
/* 上位 3 の枠 (rank-frames.js) が付いた行のアバターは丸で切り抜かない — リングと「3位・週」の帯が
   箱の下へはみ出す (帯のはみ出しは 10px 未満 = 行の上下 12px の余白に収まる)。枠の無い行は従来どおり */
.v-plain .cast-avatar:has(.framed-av), .v-plain .ranking-avatar:has(.framed-av) { overflow: visible; background: none; }

/* ── ライブ一覧 = プロト (チップ → 16:9 のカード 4 列) ── */
.v-plain .live-genre-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.v-plain .live-chip { font-size: 11px; padding: 4px 10px; background: #eceef2; border: 1px solid #dcdce4; color: #5a5a66; }
.v-plain .live-chip.active { background: var(--v-ink); color: #fff; border-color: var(--v-ink); }

/* ── いいね履歴 = プロト shorts-grid.yt (9:16 の自動段組み) ── */
.v-plain .likes-grid { grid-template-columns: repeat(auto-fill, minmax(176px, 1fr)); gap: 16px; }
@media (max-width: 768px) { .v-plain .likes-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; } }
.v-plain .likes-state { color: var(--v-ink2); }

/* ── 空の状態 (ADR-14 絶対則 5: 文言 + 導線 1 つ) ── */
.v-plain .empty-favorites, .v-plain .ranking-empty { color: var(--v-ink2); padding: 40px 16px; text-align: center; }
.v-plain .empty-favorites svg, .v-plain .ranking-empty-icon { color: #c8c8d2; }
/* 2026-10-07 (残りの一覧 G5・09-19 判断 §6 #3「非正常系は共通部品 1 つ」): 空状態と読み込み失敗の共通部品 (js/v-empty.js の
   VEmpty.empty / VEmpty.failed)。見た目はプロト proto.css:158-160 の .empty / .et / .ea と同じ値 (破線 #c0c0cc・地 #fafafc・
   24px 16px・中央寄せ／題 13px #5a5a66／動作 12px・墨の字と墨の 1px の線・5px 14px)。値の一致は scripts/faulttest/viewer-empty.test.mjs が見る。
   - grid-column: 一覧の入れ物は段組みの grid が多い (配信カード 4 列・ショート・チャンネルの行) ので全幅にする
     (以前の空・失敗のユーティリティ u-c-d81b2e82 / u-c-c358bbab と同じ)。grid でない入れ物では効かない
   - 動作はリンク (a) とボタン (data-click の押下・button) の 2 種類。ボタンにも同じ見た目が付くよう、UA の地・角・字・行の高さを
     打ち消す (プロトは button { font: inherit; background: none } を全体に当てている = proto.css:9)
   - 詳細度 (0,2,0) は .v-plain a { color: inherit } (0,1,1) に勝つ。styles.css ほかに .v-empty の規則は無い
   ⚠ 視聴 (watch) の覆いとショートは ADR-15 で別に持つので、ここは使わない (watch.html が v-empty.js を読むのは通知のパネルのため) */
.v-plain .v-empty { grid-column: 1 / -1; border: 1px dashed #c0c0cc; background: #fafafc; padding: 24px 16px; text-align: center; }
.v-plain .v-empty-t { font-size: 13px; color: var(--v-ink2); margin: 0 0 8px; }
/* 補足の行 (2 行目以降)。プロト ranking.html の空の補足 (font-size:11px;color:#8a8a96・.et と同じ margin) */
.v-plain .v-empty-s { font-size: 11px; color: var(--v-ink3); margin: 0 0 8px; }
/* いいね履歴の入れ物 (likes.css の .likes-state の 40px 16px) は箱の外に余白を足すだけなので外す。他の面は入れ物の直下に箱が来る */
.v-plain .likes-state { padding: 0; }
/* 404 の面 (404.html の body.v-404) ではサイドに「選択中」を出さない。/live/xxx のような深いパスで来ると、shell.js と
   app.js の initSidebar がパスの前置きで .active を付ける (付け直しの時機は認証の初期化の後なので JS では外しきれない)。
   見た目だけを通常の項目 (上の .v-plain .sidebar-nav .nav-item・:hover) に戻す。styles.css の .nav-item.active の
   光彩 (box-shadow) も消す */
.v-plain.v-404 .sidebar-nav .nav-item.active { background: none; color: #3a3a44; font-weight: 400; border-color: transparent; box-shadow: none; text-shadow: none; }
.v-plain.v-404 .sidebar-nav .nav-item.active:hover { background: var(--v-hover); color: var(--v-ink); }
.v-plain.v-404 .nav-item.active .nav-item-icon { color: inherit; background: none; filter: none; }
.v-plain .v-empty-a {
  display: inline-block; font-size: 12px; color: var(--v-ink); border: 1px solid var(--v-ink); padding: 5px 14px;
  background: none; border-radius: 0; font-family: inherit; line-height: inherit; text-decoration: none; cursor: pointer;
}
/* 通知のパネル (notifications.js のベルの下の小さな箱) の中だけは、破線の箱にせずプロトの .notif-empty (proto.css:199 =
   枠・地なし・18px 12px・12px・#8a8a96) の見た目にする。部品は同じ VEmpty で、パネルの中の見た目だけを変える */
.v-plain .notif-panel .v-empty { border: 0; background: none; padding: 18px 12px; }
/* 2026-10-08 (オーナー決定 O22・O12): 読み込み中 (VEmpty.loading()) は文字だけ。枠線と地を消す。余白は空の箱と同じ
   (24px 16px) で、出し替えたときの高さの差は導線の 1 行分だけ (実測 71px → 導線つきの空 110px)。字は補足と同じ薄い墨 */
.v-plain .v-empty.is-loading { border-color: transparent; background: none; }
.v-plain .v-empty.is-loading .v-empty-t { color: var(--v-ink3); margin: 0; }
.v-plain .notif-panel .v-empty-t { font-size: 12px; color: var(--v-ink3); margin: 0; }

/* ══ 本文以外の書体の残り (2026-10-06・オーナー判断 2「他に合わせて」の続き) ═══════════════════════════════
   上の `.v-plain :is(…)` (styles.css の書体の規則の打ち消し) で届かない 2 つと、旧書体に合わせた大きさ・字間・太さ。
   固定の書体名は並べず inherit にする — v-plain は body.v-plain の書体、ショートは shorts.css の html, body の書体を継ぐ。
   実測 (2026-10-06・静的配信の 11 面 × 幅 1280 / 390・ヘッドレス Edge。法的モーダルとログインのモーダルを開き、styles.css の
   書体のセレクタごとの見本の要素を差し込んで計算済みスタイルを比べた): 本文と違う書体の要素 0 件 (直す前は面ごとに実物 26〜84 件)。
   書体が変わったのは 旧書体→本文 (見出しの和字・法的モーダル)・ログインのモーダル (26 要素)・UA 既定の部品 (ボタン・入力欄と
   その中の svg など) だけで想定外 0 件。大きさ・字間・太さが変わったのは見出しの和字と法的モーダルだけ。
   旧書体と組の字間 (#969 で書体だけ戻した Space Mono の規則のものを含む) は ④ で normal に戻す (実測は ④ の後の注記) */
/* ① 共有ログインモーダル (login-modal.css・ダッシュボードも読むので書き換えない)。font-family が
   var(--b-fontT, "Zen Maru Gothic", …) と var(--b-fontT, sans-serif) で、--b-fontT は bubblegum.css にしか無いので
   v-plain / ショートでは代わりの Zen Maru Gothic と sans-serif (題) のままだった。
   ⚠ 詳細度は login-modal.css と同じ ((0,1,0) と (0,1,1)) で、読み込み順で勝つ。モーダルを使う 5 面 (watch・points・settings・
     profile・shorts) はどれも login-modal.css の後に viewer.css を読む (検査が HTML の並びを見る) */
:where(.v-plain, .v-shorts) .livestream-login-modal,
:where(.v-plain, .v-shorts) .livestream-login-modal h2 { font-family: inherit; }
/* ② 書体の指定が無いボタン・入力欄は UA の既定 (Arial など) になる (ヘッダーの残高・チャットのタブ・閉じる ×・
   ログインのモーダルのボタン 3 つ・ショートのログインのモーダルの入力欄など)。プロトは button { font: inherit } (proto.css:9)。
   詳細度は (0,0,1) に保つ (:where で .v-plain を数えない) — ページ側のクラス付きの規則には負けるので、書体を決めている部品の
   見た目は変わらない。上の :where(.v-plain) textarea, select (素の欄の地と線) とは同じ inherit で食い違わない */
:where(.v-plain, .v-shorts) :is(button, input, select, textarea) { font-family: inherit; }
/* ③ 旧書体に合わせた大きさ・字間・太さ (プロトに対応が無いので、viewer.css の同類に揃える)。
   法的モーダル (legal-modal.js・フッターの法務 5 本)。styles.css は題を Monoton 1.2rem・字間 0.06em、本文の h1 / h2 を
   Monoton 1.3rem / 1.1rem・0.05em、h3 を Zen Kaku Gothic New 900・0.08em にしていた。プロトは法務面を作っていない
   (proto-age.js:28)。題と h1 / h2 はモーダルの題 (.v-plain .modal-title 15px・字間なし。プロトの通報モーダルの題
   proto.css:273 .rpcard h2 も 15px) に、h3 は 1 段下の見出し (settings.css .settings-section-title 14px・700) に揃える。
   h1 は legal-modal.js が外すので実際には出ない (styles.css の一覧に合わせて並べるだけ)。
   本文 (段落・箇条書き) は 13px (視聴者の面の本文の大きさ。styles.css の 0.92rem = 14.72px のままだと、h3 (14px) が本文より
   小さく、h2 (15px) も本文とほぼ同じになり、見出しの段が大きさで分からなかった・2026-10-06 のレビュー)。15 / 14 / 13 の段にする */
.v-plain .legal-modal-body { font-size: 13px; }
/* 法的モーダルの地と線 (2026-10-06 に見つけた以前からの不具合・develop と同じ)。styles.css の .legal-modal は暗い紫の
   グラデーション (#1a0528 → #0a0210) の地のままで、v-plain では文字の色 (--ink・--pink など) が墨に読み替わるので、規約・
   プライバシーポリシーなどの本文と見出しが暗い地に墨で、ほとんど読めなかった (実測: 地の画像 linear-gradient(rgb(26,5,40) …)・
   文字 rgb(35,35,42))。ほかのモーダル (上の .v-plain .modal-overlay / .modal-content / .modal-header / .modal-close) と同じ
   白地・墨の線・薄い膜にする */
.v-plain .legal-modal-overlay { background: rgba(35, 35, 42, 0.45); backdrop-filter: none; -webkit-backdrop-filter: none; }
.v-plain .legal-modal { background: #fff; color: var(--v-ink); border: 1.5px solid var(--v-ink); border-radius: 0; box-shadow: none; }
.v-plain .legal-modal::before { display: none; }
.v-plain .legal-modal-header { border-bottom: 1px solid #eeeef2; }
.v-plain .legal-modal-title { color: var(--v-ink); }
.v-plain .legal-modal-close, .v-plain .legal-modal-close:hover { background: none; border: 0; border-radius: 0; box-shadow: none; color: var(--v-ink2); }
.v-plain .legal-modal-body p, .v-plain .legal-modal-body li { color: var(--v-ink); }
.v-plain .legal-modal-body a, .v-plain .legal-modal-body a:hover { color: var(--v-ink); text-decoration: underline; }
.v-plain .legal-modal-body hr { border-top: 1px solid var(--v-line); }
.v-plain .legal-modal-body code { background: var(--v-hover); color: var(--v-ink); }
.v-plain .legal-modal-title { font-size: 15px; letter-spacing: normal; }
.v-plain .legal-modal-body h1, .v-plain .legal-modal-body h2 { font-size: 15px; letter-spacing: normal; }
.v-plain .legal-modal-body h3 { font-size: 14px; font-weight: 700; letter-spacing: normal; }
/* ルビー管理の金額 (.transaction-amount)・無料でもらう方法 (.free-method-points)・チャットのスタンプ／プレゼントの金額
   (.chat-stamp-cost / .chat-gift-cost) は、大きさ・太さを points.css / watch.css がもう決めていて (14px・700 / 12px /
   0.75rem)、旧書体 VT323 に合わせた styles.css の 1.1rem / 1rem / 0.95rem は効いていない。字間も持たない。
   なので書体だけを上の一覧で揃え、ここでは足さない (ページ側の判断を viewer.css で二重に持たない) */
/* ④ 旧書体に合わせた字間 (利用者の範囲「旧書体に合わせた字間もプロトに揃える」)。プロトの字間は、proto.css の配信カードの
   LIVE の札の .02em と、proto-age.css の年齢確認のロゴの .04em だけ (ロゴは上の #age-gate-logo で既に normal)。styles.css が旧書体と組にして付けた字間を、v-plain の面で normal に戻す。
   上の書体の一覧では字間を触らない (Space Mono の 85 個は #969 で書体だけ戻したので、ヘッダーのログイン 0.14em・欄のラベル 0.15em・
   フッター 0.1〜0.15em・タブ 0.12em などが残っていた)。対象は次の A・B・C の 3 つで、旧書体と関係のない規則の字間は触らない。
   ⚠ 字間は継がれるので、対象の要素の中の部品 (欄のラベルの「*」・補足の中のリンク・フッターの行など) も一緒に normal になる
   A: 旧書体の規則 (上の書体の一覧と同じ「inherit 以外の font / font-family を持つ規則」) の中の letter-spacing (0 / normal 以外)。
      セレクタはその規則のものを styles.css の順にそのまま並べる (97 個。足し漏れは viewer-plain-font.test.mjs が落とす)。
      詳細度は上の書体の一覧と同じ (0,3,0) で、元の規則 (どれも (0,2,0) 以下) に順番に関係なく勝つ。letter-spacing だけを書く。
      除外 (検査が理由ごと持つ): .status-badge — viewer.css が LIVE・有料・配信予定の札に 0.02em を付けている ((0,2,0)。根拠は
      プロトの配信カードの LIVE の札 proto.css:84 で、視聴画面の札にも同じ値を当てている。一覧に入れると (0,3,0) で潰れる) ／ .toast — styles.css が !important なので上のトーストの規則が normal !important で外す ／
      body — body.v-plain が letter-spacing: normal を持つ */
.v-plain :is(.top-bar .logo, .version-badge, .crumbs .lead, .crumbs .page, .live-chip, .seedbox .l, .btn-header-logout, .btn-logout, .user-points-row, .nav-section-title, .open-badge, .sign-open, .sign-name, .sign-sub, .sign-stars, .btn, .btn-primary, .btn-point-purchase, .btn-point-purchase.primary, .card-header h2, .section-title, .section-title .ja, .section-link, .section-action, .ticker-label, .ticker-track, .notice-date, .news-date, .notice-tag, .news-tag, .stream-viewers, .stream-time, .badge, .ribbon-label, .neon-sign, .empty-title, .empty-burrow-title, .empty-sub, .empty-burrow-sub, .empty-count .k, .sched-day .dow, .sched-day .pill, .sched-empty-note .tag, .refresh, .form-label, .form-hint, .modal-title, .chat-message-time, .ranking-desc, th, .hamster-loader-text, .login-box h1, .login-box .subtitle, .home-link, .admin-badge, .dashboard-tab, .live-tab-placeholder h2, .control-drawer-toggle, .control-drawer-header h2, .control-drawer-section-title, .widget-list-compact-type, .live-current-scene-badge, .broadcaster-version-chip, .broadcaster-header h1, .footer-burrow, .market-product-type-badge, .market-product-purchased-badge, .market-product-price, .market-product-sales, .cast-count, .filter-btn, .ranking-tab, .ranking-period-tab, .product-detail-title, .product-detail-thumbnail-label, .product-detail-hero-empty, .product-detail-preview-notice, .product-detail-image-count, .product-hero-counter, .broadcaster-tag, .broadcaster-social-btn, .chat-time, .transaction-date, .empty-history, .login-title, .signup-title, .btn-login, .btn-signup, .login-divider, .btn-mobile-login, .confirm-title, .settings-section-title, .legal-modal-title, .legal-modal-body h1, .legal-modal-body h2, .legal-modal-body h3, .legal-modal-body form label) { letter-spacing: normal; }
/* B: 旧書体の要素 (A の 1 段のセレクタ: .btn-login など) を、別の規則がより強いセレクタで指して付けている字間
   (ヘッダー／サイドのログイン。#loginSection を含むものは (1,1,0) で、A の (0,3,0) では勝てない = ヘッダーの「ログイン」
   「新規登録」の 0.14em はここから来ていた)。.v-plain を前に付けて (1,2,0) にする。styles.css のその規則をそのまま並べる */
.v-plain :is(#loginSection .login-title, .sidebar .login-title, #loginSection .btn-login, #loginSection .btn-signup, .sidebar .btn-login, .sidebar .btn-signup, #loginSection .login-divider, .sidebar .login-divider) { letter-spacing: normal; }
/* C: 自分では書体を持たず、旧書体の部品の中で使う前提で字間を付けている部品。フッター (shell.js の .footer-burrow >
   .footer-burrow-links > .footer-burrow-link) は .footer-burrow が Space Mono で、リンクの 0.15em はその字面に合わせた値。
   プロトのフッター (proto-age.css:26-27 .legallinks) は字間なし。これは A・B と違って書体の規則からは機械的に拾えないので、
   検査は明示の一覧として持つ。⚠ .footer-burrow-copy は styles.css に規則 (0.15em) があるが、いまの shell.js の著作表示は
   クラスの無い div で、A の .footer-burrow から normal を継いで直っている。ここに並べるのは、クラスが付いたときの予防 */
.v-plain :is(.footer-burrow-link, .footer-burrow-copy) { letter-spacing: normal; }
/* ④ の実測 (2026-10-06・静的配信の 11 面 × 幅 1280 / 390・ヘッドレス Edge。④ の前の viewer.css と比べた): 字間が変わったのは
   A に当たる要素 (欄のラベル・補足・フッター・生年入力のボタン・絞り込み・期間のタブ・件数など、面ごとに実物 12〜15)、
   B (ヘッダーの「ログイン」「新規登録」の 2)、C (フッターのリンク 5)、それを継ぐ中の要素 (6〜8) だけで、想定外 0 件。
   書体・太さ・大きさの変化 0 件。本文と違う書体 0 件のまま。直した後も normal 以外の字間は .status-badge の 0.02em (意図) と
   ショートの札 (shorts.css・v-plain ではない) だけ。B を外すとヘッダーのボタンが 0.14em に戻り、.status-badge を A に入れると
   0.02em が潰れることも実ページで確かめた */
