/* components.css — 部品の骨組み。og/og.js の Web Components は自分の中身を
   インラインの style で描く（ハンドオフの React 実装をそのまま踏襲）ので、
   ここに置くのは (1) custom element 自体を透明化する display:contents、
   (2) 個々のコンポーネントでは表現しづらい「画面の組み立て」側の構造だけ。 */

og-button, og-fab, og-icon-button, og-avatar, og-status-tag, og-media-card,
og-setting-row, og-stat-card, og-task-card, og-task-row, og-track, og-waveform,
og-ai-note, og-checkbox, og-field, og-pill-picker, og-search-field, og-segmented,
og-toggle, og-screen-header, og-sidebar-item, og-tabbar, og-modal, og-sheet {
  display: contents;
}

/* ── アプリの外枠 ─────────────────────────────────────────────────── */

#og-app {
  background: var(--bg);
  color: var(--ink);
}

.og-frame {
  position: relative;
  overflow: hidden;
  background: var(--bg);
  color: var(--ink);
  display: flex;
  flex-direction: column;
}

/* モバイル：390×844、フルスクリーンではビューポート全体を使う。
   高さを固定し、ページ自体はスクロールさせない（スクロールは中の og-scroll だけ）。

   高さは --app-h（app.js が visualViewport から入れる）を正とする。
   100dvh はソフトキーボードが出ると縮み、閉じても戻りきらないことがあり、
   下端に浮いている TabBar と FAB が上にずれたまま残る。 */
.og-frame--mobile {
  width: 100%;
  height: 100vh;
  height: 100dvh;
  height: var(--app-h, 100dvh);
}

/* 本文列。既定（narrow / wide だが panel 無し）ではこれ1枚が枠いっぱいに
   広がるだけで、見た目は前と1pxも変わらない ── タブバー・帯・FAB はこの中に
   いて、position:absolute の基準もここ（position:relative）に取る。 */
.og-mobile-col {
  position: relative;
  flex: 1;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* wide+panel（iPad 横など。判定は app.js の PANEL の1本、属性は data-og-panel）:
   本文列の右に #og-panel-slot（.og-panel、400px）を並べる。デスクトップの
   枠（.og-frame--desktop + #og-panel-slot）と同じ組み方 ── パネルの中身
   （overlays.js present）は端末を区別せず、置き場だけが変わる。 */
html[data-og-panel="1"] .og-frame--mobile {
  flex-direction: row;
}

/* 画面いちばん上の safe-area 帯。ノッチ / Dynamic Island の下に本文が
   潜らないぶんだけ背を持つ。中身は空 ── 時刻や電波アイコンは OS が描くので、
   アプリ側では描かない。safe-area の無い環境（PC ブラウザ）では 0px になる。

   status-bar-style=default では上端の inset を OS 側が取るので --safe-top は
   0px になり、この帯が消える。すると本文が上端いちばん際まで来て、
   **iOS が上端に掛ける半透明のぼかしに文字が入り込む**（実機で、いちばん上の
   カードの見出しがぼやけて読めなくなっていた）。

   そこで safe-area とは別に**下限の余白**を持たせる。safe-area があるときは
   その上に足す ── 足しても24pxで、見出しの位置が少し下がるだけ。
   ここを1か所直せば、5枚のタブ全部（TASKS / CAL / REC / LOAD / MORE）に効く。 */
.og-statusbar {
  height: calc(var(--safe-top, 0px) + var(--top-buffer, 24px));
  flex: none;
}

/* デスクトップ：サイドバー固定232px / 可変ボード / 400pxパネル。
   高さを viewport に固定し、動くのはボード（og-main の中）と
   詳細パネルの本文だけ ── サイドバーとパネルのヘッダ・フッタは動かない。 */
.og-frame--desktop {
  width: 100%;
  height: 100vh;
  height: 100dvh;
  flex-direction: row;
}

.og-sidebar {
  width: var(--sidebar-w);
  flex: none;
  min-height: 0;
  /* 盤面（--bg）との段差で境界を作る。罫は引かない。
     右の .og-panel が既に --surface なので、左右の固定シェルが対になる。 */
  background: var(--surface);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
/* 頭は「名乗り」と「畳む／開く」の1行。バーガーの的（44px）に上下 16px を
   足して 76px ── 名乗りだけだったころ（20px + 36px + 20px）と同じ背。
   左の 18px は名乗りの位置を1pxも動かさないため、右の 6px は 56px の
   レールに畳んだときバーガーが中央（6 + 44 + 6）に来るため。 */
.og-sidebar__head { padding: 16px 6px 16px 18px; display: flex; align-items: center; gap: 8px; }
.og-sidebar__brand { min-width: 0; flex: 1; }
.og-sidebar__kicker { display: block; font: 600 10px var(--font-mono); letter-spacing: .14em; color: var(--ink-3); }
.og-sidebar__wordmark { display: block; margin-top: 6px; font: 800 20px/1 var(--font-sans); letter-spacing: -.045em; color: var(--ink); }
/* バーガー。地は敷かず、hover でだけ --bg-2 が出る（サイドバーの他の
   押しどころ ── 足・KEYS ── と同じ作法）。字は ICON.menu（≡）。 */
.og-sidebar__burger {
  width: 44px; height: 44px; flex: none;
  display: flex; align-items: center; justify-content: center;
  border: 0; border-radius: var(--r-btn); background: none; color: var(--ink-2);
  cursor: pointer;
  transition: background var(--dur-tap) var(--ease-linear);
}
.og-sidebar__burger:hover { background: var(--bg-2); }
.og-sidebar__burger-glyph { font: 400 17px/1 var(--font-mono); }

/* ── 畳んだ左ナビ（レール 56px）─────────────────────────────────────
   隠すのではなく痩せる。残るのは バーガー・PJ の駒 10px と件数・`?`・IN。
   語彙は1つも増やさない（色も塗りも展開時と同じ）。
   デスクトップ枠にしか .og-sidebar は無いので、モバイルには1pxも効かない。 */
.og-sidebar--rail { width: var(--sidebar-w-rail); }
.og-sidebar--rail .og-sidebar__head { padding-left: 6px; padding-right: 6px; }
.og-sidebar--rail .og-sidebar__brand { display: none; }
/* KEYS の表は「キー・意味」の2列で 232px を前提にしている。56px では読めない
   ので出さない（app.js の toggleKeys が、開くときは先にレールを戻す）。 */
.og-sidebar--rail .og-sidebar__keys { display: none; }
.og-sidebar--rail .og-sidebar__keys-toggle { padding: 0; justify-content: center; }
/* 足は「IN」1枚だけ残す。32px の丸を2枚（+ gap）並べると 56px に入らない。 */
.og-sidebar--rail .og-sidebar__foot { padding: 16px 0; justify-content: center; gap: 0; }
.og-sidebar--rail .og-sidebar__foot og-avatar + og-avatar { display: none; }
/* KEYS と SETTINGS の語（どちらも .og-sidebar__foot-label）は落とす。 */
.og-sidebar--rail .og-sidebar__foot-label { display: none; }
.og-sidebar__foot {
  margin-top: auto;
  padding: 16px 18px;
  display: flex;
  gap: 10px;
  align-items: center;
  /* 地は敷かない。親（.og-sidebar）の --surface が透ける ── hover の
     --bg-2 との段差はそれで保たれる。 */
  background: none;
  border: 0;
  width: 100%;
  cursor: pointer;
  text-align: left;
  transition: background var(--dur-tap) var(--ease-linear);
}
.og-sidebar__foot:hover { background: var(--bg-2); }
.og-sidebar__foot-label { font: 400 11px var(--font-mono); color: var(--ink-3); }

/* デスクトップ本文の列。.og-main（下）と再生中の帯を縦に並べるためだけの1枚。
   .og-main 自身には手を入れない ── 5画面（Tasks / Calendar / Recordings /
   Documents / Analytics）の骨組みが .og-main の flex 列にぶら下がっているので、
   あそこを列から外すと並びが一斉に崩れる。帯が無いとき（#og-player-slot が空）は
   高さ 0 なので、.og-main の見え方は1pxも変わらない。 */
.og-main-col {
  flex: 1;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
/* 帯は縮まない。縮むのは上の本文のほう。 */
.og-main-col > #og-player-slot { flex: none; }

.og-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

/* マウント用の透明ラッパー。子（.og-panel / オーバーレイ）を親の flex に直結させ、
   詳細パネルが正しく viewport 高さいっぱいに伸びるようにする。 */
#og-panel-slot, #og-overlay-slot { display: contents; }

.og-panel {
  width: var(--panel-w);
  flex: none;
  min-height: 0;
  background: var(--surface);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: og-slide var(--dur-panel) var(--ease-out);
}

/* ── 見出し・ラベル ユーティリティ ───────────────────────────────── */
.og-section-kicker {
  padding: 20px 20px 8px;
  font: 600 10px var(--font-mono);
  letter-spacing: .14em;
  color: var(--ink-3);
}

/* ── MEMO カード（#171A21 固定・232px・ボード最上部） ─────────────── */
.og-memo-card {
  border-radius: var(--r-card);
  background: #171A21;
  color: #FFFFFF;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  height: 232px;
  cursor: pointer;
}
.og-memo-card__kicker {
  flex: none;
  min-width: 0;
  overflow: hidden;
  display: flex;
  align-items: center;
  gap: 7px;
  font: 600 9px var(--font-mono);
  letter-spacing: .12em;
  opacity: .75;
}
.og-memo-card__dot { width: 6px; height: 6px; flex: none; background: currentColor; }
/* 盤面のメモは全部出す（枚数で切らない）。4枚を超えたら丈を詰める ──
   232px のまま8枚並ぶと、盤面がメモの壁になってタスクが1枚も見えなくなる。 */
.og-memo-card--compact { height: 150px; padding: 13px; gap: 7px; }
.og-memo-card--compact .og-memo-card__lede { font: 400 14px/1.34 var(--font-sans); }
.og-memo-card__lede {
  flex: 1;
  min-width: 0;
  min-height: 0;
  font: 400 16px/1.38 var(--font-sans);
  letter-spacing: -.01em;
  overflow: hidden;
  /* 折り返す先を持たない語（URL・長い品番）で札の外へ逃げる。縦にだけ伸ばす。 */
  overflow-wrap: anywhere;
  /* 書いた人の改行を畳まない（HTML の既定は空白に潰す）。丈は固定なので、
     行数が増えたぶんは overflow: hidden で切られる。 */
  white-space: pre-wrap;
  text-wrap: pretty;
}
/* kicker の中の「畳む」升（views/tasks.js の memoCard）。
   **字のほうを切って、升は必ず残す** —— 長い kicker の日にだけ畳めなくなる、
   という当たり外れを作らない。指で押すので、行（20px）より一回り大きくする。 */
.og-memo-card__kicker-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.og-memo-card__kicker .og-memo-row__mark { width: 26px; height: 26px; }

.og-memo-card__foot {
  margin-top: auto;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font: 600 9px var(--font-mono);
  letter-spacing: .12em;
  opacity: .75;
}

/* デスクトップ：ボード上の横長 MEMO */
.og-memo-card--wide {
  height: auto;
  flex-direction: row;
  align-items: center;
  gap: 22px;
  padding: 20px 22px;
}
.og-memo-card--wide .og-memo-card__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 10px; }
.og-memo-card--wide .og-memo-card__lede { flex: none; }
.og-memo-card--wide .og-memo-card__looked { font: 400 13px/1.5 var(--font-sans); opacity: .7; text-wrap: pretty; }

/* ── INBOX 行 ─────────────────────────────────────────────────────── */
.og-inbox-row {
  border-radius: var(--r-card);
  padding: 14px;
  display: flex;
  align-items: flex-start;
  gap: 12px;
}
.og-inbox-row__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 7px; cursor: pointer; }
.og-inbox-row__kicker { font: 600 9px var(--font-mono); letter-spacing: .12em; opacity: .85; }
.og-inbox-row__title { font: 700 17px/1.2 var(--font-sans); letter-spacing: -.02em; text-wrap: pretty; overflow-wrap: anywhere; }
.og-inbox-row__said { font: 400 12px/1.45 var(--font-sans); opacity: .9; text-wrap: pretty; }
.og-inbox-row__actions { display: flex; flex-direction: column; gap: 6px; flex: none; }

/* 担当・期日（割り振り済みのカードだけに出す。空欄は足さない） */
.og-inbox-row__meta { display: flex; align-items: center; gap: 8px; margin-top: 1px; }
.og-inbox-row__due { font: 600 10px var(--font-mono); letter-spacing: .1em; opacity: .82; }

/* ── BOARD（2カラム） ─────────────────────────────────────────────── */
.og-board {
  padding: 14px 20px 0;
  display: flex;
  align-items: flex-start;
  gap: 12px;
}
.og-board__col { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 12px; }

/* デスクトップの盤面は**モバイルと同じ組み方**（views/tasks.js の boardBody）。
   status で3列に割るのをやめたので、ここに専用の格子は要らない ──
   列は JS が数だけ替えて作る（モバイル2本・デスクトップ3本）。 */

/* ── DONE グループ ────────────────────────────────────────────────── */
/* 折りたたみ見出しの骨格。DONE のために書いたが、REC / CAL / DOC でも
   同じものを使う。中身は DONE のときのまま ── 別名を併記しただけなので、
   いま .og-done-group-head を使っている3画面は1pxも動かない。 */
.og-done-group-head, .og-group-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 18px 0 8px; cursor: pointer;
}
.og-done-group-label, .og-group-head__label { font: 600 10px var(--font-mono); letter-spacing: .14em; color: var(--ink-3); }
.og-done-group-count, .og-group-head__count { font: 600 10px var(--font-mono); letter-spacing: .1em; color: var(--ink-3); }
/* 行は罫で区切らず、札にする（盤面の TODO 札と同じ語彙）。
   左右 20px は親（tasks.js の wrap）が持っているので、ここは札の内側だけ。 */
.og-done-row {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; border-radius: var(--r-card); background: var(--surface);
}
.og-done-row + .og-done-row { margin-top: 8px; }
.og-done-row__undo {
  width: 20px; height: 20px; flex: none; padding: 0; border: 0; border-radius: var(--r-check);
  background: var(--ink); color: var(--on-ink); font: 700 10px var(--font-sans);
  display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.og-done-row__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; cursor: pointer; }
.og-done-row__title { font: 600 14px var(--font-sans); color: var(--ink-2); text-decoration: line-through; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.og-done-row__meta { font: 400 10px var(--font-mono); color: var(--ink-3); }

/* ── ARCHIVE（メモ）：DONE と同じ骨格。ただし打ち消し線は持たない ─────────
   閉じたタスクは「終わった仕事」だが、メモは終わったのではなく降りただけ。 */
.og-memo-row {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; border-radius: var(--r-card); background: var(--surface);
}
.og-memo-row + .og-memo-row { margin-top: 8px; }
/* 降りたメモは沈める（終わったのではなく降りただけ、を面の高さで言う）。 */
.og-memo-row--archived { background: var(--bg-2); }
.og-memo-row__mark {
  width: 20px; height: 20px; flex: none; padding: 0; border-radius: var(--r-check);
  /* og.js の OgCheckbox と同じ作法。off は枠ではなく「沈んだ升」。 */
  border: 0; background: var(--bg-2); color: transparent;
  font: 700 10px var(--font-sans); display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.og-memo-row__mark--on { background: var(--ink); color: var(--on-ink); }
/* アーカイブ済みの行そのものが --bg-2 に沈むので、升は1段濃くしないと消える。 */
.og-memo-row--archived .og-memo-row__mark { background: var(--neutral-mid); }
/* signal と解消済みは押せない（アーカイブはサーバの領分）。押せないものは薄くする。 */
.og-memo-row__mark[disabled] { cursor: default; opacity: .45; }
.og-memo-row__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; cursor: pointer; }
.og-memo-row__title {
  font: 600 14px var(--font-sans); color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.og-memo-row--archived .og-memo-row__title { color: var(--ink-3); }
.og-memo-row__meta { font: 400 10px var(--font-mono); color: var(--ink-3); }

/* ── 混雑度の4段（0=空 → 3=過多）──────────────────────────────────
   plan.js の見込みの山・凡例・衝突が共有する（暦の日マスは WAVE に吸収されて
   無くなった）。段は塗りのトークン4本で書き、**関数側に色もテーマ分岐も持たせない**
   （--accent-soft / --accent-mid はテーマで暗い側へ反転する）。
   文字色まで持たせてあるので、消費側は color を書かず継承に任せること。

   頂点は --accent であって --ink ではない。暦では --ink は「今日」の語彙で、
   いちばん忙しい日を黒く塗ると今日と読み違える（設計元の CALENDAR も
   予定なし #E9E9E9 → 少 #FFEDE1 → 多 #FFD5BB、今日だけ #0B0C0D）。
   **いまこの4段を使うのは PLAN の「見込みの山」だけ**（週バケットの全PJ合算）。
   暦の日マス（CAL）は容量が入った回に .og-load--N（上限比）へ移した
   —— 同じ濃さが「件数」と「上限比」の2つを意味していて、CAL で薄い日が
   LOAD では真っ黒、が起きうる状態だった（docs/17_PAGE_CONSOLIDATION.md D9-B）。 */
.og-heat--0 { background: var(--bg-2);        color: var(--ink-3); }
.og-heat--1 { background: var(--accent-soft); color: var(--accent-hi); }
.og-heat--2 { background: var(--accent-mid);  color: var(--ink); }
.og-heat--3 { background: var(--accent);      color: var(--on-accent); }

/* ── 負荷率の4段（capacity_hours に対する割合）──────────────────────
   .og-heat--N が「これから何が重なるか（見込みの山）」なのに対し、こちらは
   「その日に何時間乗っているか ÷ 1日の上限」。**段の基準が違うのでクラスを
   分ける** ── 同じ名前で基準だけ替えると、duesheet.js と plan.js の意味が黙って変わる。
   LOAD の月ヒート・期日ピッカー（duesheet.js）は**すべてこちら**。

   段は GET /api/capacity がサーバ側で決めて返す（level 0-3）。閾値は画面に無い。
   頂点が --ink なのは「超過は1〜2マスしか出ない」から ── 暦のマスでは
   --ink は「今日」の語彙でもあるが、今日は塗りではなく outline で示すので衝突しない。 */
.og-load--0 { background: var(--bg-2);       color: var(--ink-2); }
.og-load--1 { background: var(--accent-mid); color: var(--ink); }
.og-load--2 { background: var(--accent);     color: var(--on-accent); }
.og-load--3 { background: var(--ink);        color: var(--on-ink); }
/* 土日は段を付けない（level: null）。上限を台帳が知らないので判定をしない。
   地は0段と同じで、文字だけ落として「数えていない日」に見せる。 */
.og-load--rest { background: var(--bg-2);    color: var(--ink-3); }

/* ── せり上がる暦（期日を変えるときだけ生える）───────────────────────
   常設しない。掴んでいるあいだだけ body 直下に生えて、終われば DOM ごと消える
   （og.js の confirmDialog と同じ作法）。**盤面は暗くしない** ── スクリムを
   敷かないので、暦の外はそのまま触れる。 */
.og-due-sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  display: flex; flex-direction: column;
  /* 左右は 14px。盤面の 20px だと 375px 幅で日のセルが 42.7px にしかならず、
     44px（--tap-min）を割る。14px なら 44.4px。 */
  padding: 0 14px calc(14px + var(--safe-bottom, 0px));
  height: min(560px, calc(var(--app-h, 100dvh) - 96px));
  background: var(--surface);
  border-radius: var(--r-sheet) var(--r-sheet) 0 0;
  transform: translateY(100%);
  transition: transform var(--dur-sheet) var(--ease-rise);
}
.og-due-sheet--on { transform: translateY(0); }

/* つまみ。**下スワイプで閉じられることを触る前に見せる**ための「物」なので
   --neutral-mid（agents/design.md §2-1 の「線が要る3つ」の1つ）。
   押せる部品ではないので tap-min は要らない ── 掴む面は見出し全体が受ける。 */
.og-due-grip {
  flex: none; align-self: center;
  width: 36px; height: 4px; margin: 8px 0 2px;
  border-radius: 999px; background: var(--neutral-mid);
}

/* 掴む面。ここから始めた指は最初の1pxで追従する（duesheet.js の attachSwipeDown）。
   touch-action: none にしないと、iOS が先にスクロールとして持っていく。 */
.og-due-sheet { touch-action: none; }

.og-due-head { flex: none; padding: 14px 0 12px; display: flex; align-items: flex-start; gap: 12px; }
.og-due-head__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.og-due-head__title {
  font: 700 13px var(--font-sans); color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* 行き先の読み。**min-height を必ず置く** ── 文言が付いたり消えたりで
   シートが跳ねる。 */
.og-due-head__read { min-height: 16px; font: 600 11px var(--font-mono); color: var(--ink-2); }
.og-due-head__cancel {
  flex: none; height: 44px; padding: 0 16px; border: 0; border-radius: var(--r-knob);
  background: var(--bg-2); color: var(--ink-2);
  font: 700 10px var(--font-mono); letter-spacing: .14em; cursor: pointer;
}

/* 6週ぶんを常に描く（行数を可変にすると月をまたぐたびにシートの背が跳ねる）。
   幅は固定しない ── 1fr に任せれば 375 / 390 / 430 のどれでも 44px を超える。 */
/* 暦の上の月（2026-09-05）。6 週ぶんしか見えないので、送った先が何月かは数字だけでは
   読めない。見出しの語彙は WAVE と同じ mono・大文字。罫線は引かない。 */
.og-due-month {
  flex: none; padding: 0 0 8px;
  font: 700 11px/1 var(--font-mono); letter-spacing: .12em; color: var(--ink-2);
}
/* 26 週ぶんを組んで 6 週ぶんだけ見せる（wave.js ではなく `duesheet.js` の SPAN_WEEKS）。
   `touch-action: pan-y` は**この器だけ**に効かせる ── シートは `touch-action: none`
   （下スワイプで閉じる面）なので、そのままだと指で送れない。`overscroll-behavior:
   contain` で、端まで送った指が背後の盤面へ抜けない。 */
.og-due-grid {
  flex: 1; min-height: 0;
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
  column-gap: 6px; row-gap: 6px;
  align-content: start;
  overflow-y: auto; overscroll-behavior: contain; touch-action: pan-y;
}
.og-due-cell { display: flex; flex-direction: column; align-items: stretch; gap: 3px; }

/* 日は**縦長の楕円**。罫線ゼロ。塗りは .og-load--N が持つ。 */
.og-due-day {
  height: 60px; width: 100%; padding: 11px 0 12px; border: 0;
  border-radius: var(--r-knob);
  display: flex; flex-direction: column; align-items: center; justify-content: space-between;
  cursor: pointer; outline-offset: 2px;
  transition: background var(--dur-heat) linear;
}
.og-due-day__dow { font: 600 9px/1 var(--font-mono); letter-spacing: .08em; opacity: .72; }
.og-due-day__num { font: 600 15px/1 var(--font-sans); letter-spacing: -.01em; }
.og-due-day--today .og-due-day__num { font-weight: 700; }
/* 印の帯は**窓に節目が1つでもあれば全マスに置く**（cal.js と同じ理由 ──
   ある日だけ置くと、その行のマスだけ背が伸びて升目が揃わない）。 */
.og-due-day__marks { height: 5px; display: flex; align-items: center; justify-content: center; gap: 3px; }
.og-due-day__marks span { width: 5px; height: 5px; flex: none; }
.og-due-day[disabled] { opacity: .35; pointer-events: none; }

/* 楕円の外・下の注記。「いま」「休 · 5.9h」「超過」だけ。 */
.og-due-note {
  height: 11px; text-align: center; white-space: nowrap;
  font: 600 9px/11px var(--font-mono); color: var(--ink-3);
}
.og-due-note--now { color: var(--ink); }
.og-due-note--over { color: var(--accent); }

/* 掴んでいる札。**影は使わない**ので outline で持ち上げる。 */
.og-card--lifted { outline: 2px solid var(--ink); outline-offset: 2px; transform: translateY(-1px); }
.og-moving { user-select: none; -webkit-user-select: none; cursor: grabbing; }
.og-due-ghost {
  position: fixed; z-index: 31; pointer-events: none; opacity: .85;
  border-radius: var(--r-card); overflow: hidden;
}

/* 確定の報せ。タブバーと再生バーの上に出す。 */
.og-due-hint {
  position: fixed; z-index: 32;
  left: 14px; right: 14px;
  bottom: calc(var(--tabbar-bottom, 14px) + 56px + 12px + var(--player-h, 0px));
  display: flex; align-items: center; gap: 12px;
  padding: 6px 6px 6px 16px;
  border-radius: var(--r-knob);
  background: var(--ink); color: var(--on-ink);
  animation: og-rise var(--dur-swap) var(--ease-rise) both;
}
.og-due-hint__text {
  flex: 1; min-width: 0; font: 600 11px var(--font-mono); letter-spacing: .04em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.og-due-hint__undo {
  flex: none; height: 40px; padding: 0 16px; border: 0; border-radius: var(--r-knob);
  background: var(--accent); color: var(--on-accent);
  font: 700 10px var(--font-mono); letter-spacing: .12em; cursor: pointer;
}

/* デスクトップは右の板として出す（盤面と詳細パネルの構成を崩さない）。
   暦は body 直下に生えるので `.og-frame--desktop` の子孫では捕まらない。
   JS が枠を見て、シート自身に修飾子を付ける。 */
.og-due-sheet--desktop {
  left: auto; top: 0; width: var(--panel-w);
  height: auto; border-radius: 0;
  padding: 0 20px calc(14px + var(--safe-bottom, 0px));
  transform: translateX(14px); opacity: 0;
  transition: transform var(--dur-panel) var(--ease-rise), opacity var(--dur-panel) var(--ease-rise);
}
.og-due-sheet--desktop.og-due-sheet--on { transform: translateX(0); opacity: 1; }

/* ── 日のシートの行（WAVE の日のシート。旧 CAL のアジェンダ）──────────
   左右 20px を padding から margin へ移すのがこの変更の肝。親（旧 cal.js の
   agendaHost）は水平 padding を持っていなかったので、margin にしないと
   札が画面端にべったり付く。親に padding を足すと、同じ親に並ぶ見出しや
   og-empty のインライン padding と二重取りになる。
   WAVE の日のシート（.og-wave-day）は器が 20px を持つので、そこでは 0 に戻す
   （末尾の .og-wave-* を見よ）。 */
.og-agenda-row {
  display: flex; gap: 14px;
  margin: 0 20px; padding: 14px 16px;
  border-radius: var(--r-card); background: var(--surface); cursor: pointer;
}
.og-agenda-row + .og-agenda-row { margin-top: 8px; }
.og-agenda-row__time { width: 56px; flex: none; display: flex; flex-direction: column; gap: 2px; }
.og-agenda-row__rail { width: 4px; flex: none; }
.og-agenda-row__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.og-agenda-row__chip {
  font: 600 9px var(--font-mono); letter-spacing: .12em; padding: 5px 8px;
}

/* ── REC ライブラリ行 ─────────────────────────────────────────────── */
.og-rec-row {
  display: flex; gap: 14px;
  margin: 0 20px; padding: 14px 16px;
  border-radius: var(--r-card); background: var(--surface); cursor: pointer;
}
.og-rec-row + .og-rec-row { margin-top: 8px; }
.og-rec-row__len { width: 56px; flex: none; display: flex; flex-direction: column; gap: 3px; }
.og-rec-row__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.og-rec-row__title { font: 700 17px/1.25 var(--font-sans); letter-spacing: -.015em; color: var(--ink); text-wrap: pretty; }
.og-rec-row__tags { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

/* ── DOC の一覧行 ─────────────────────────────────────────────────
   他の一覧行（done / memo / agenda / rec）と同じ札。左右 20px は margin。 */
/* **幅を明示する。** この行だけ `<button>` で、隣の一覧行（.og-inbox-row /
   .og-memo-row）は `<div>`。ブロックは親いっぱいに伸びるが、フォーム部品の
   `width: auto` は **shrink-to-fit** なので、ボタンだけが中の文字数ぶんの幅に
   なる ── 題の長いファイルほど札が広い、という不揃いが出ていた。
   左右の余白は margin が持っているので、その 40px を引いた幅を与える。 */
.og-doc-row {
  display: flex; align-items: center; gap: 14px;
  box-sizing: border-box; width: calc(100% - 40px);
  border: 0; text-align: left; cursor: pointer;
  margin: 0 20px; padding: 12px 16px;
  border-radius: var(--r-card); background: var(--surface);
}
.og-doc-row + .og-doc-row { margin-top: 8px; }
/* デスクトップは余白をクラスの外（.og-scroll 側）が持つので、margin を戻して全幅。 */
.og-frame--desktop .og-doc-row { margin-left: 0; margin-right: 0; width: 100%; }

/* ── 横断検索のヒット行 ───────────────────────────────────────────── */
.og-search-hit {
  display: flex; flex-direction: column; gap: 4px;
  min-height: 44px; box-sizing: border-box; justify-content: center;
  padding: 10px 14px;
  border-radius: var(--r-card); background: var(--surface);
}
.og-search-hit + .og-search-hit { margin-top: 8px; }

/* ── ACTIVITY タイムライン ────────────────────────────────────────── */
.og-thread-entry { position: relative; display: flex; gap: 12px; padding-bottom: 18px; }
/* 面の境界ではなく「物」の線（発言をつなぐレール）。塗りのトークンで持つ。 */
.og-thread-entry__rail { position: absolute; left: 5px; top: 20px; bottom: 0; width: 1px; background: var(--neutral-mid); }
.og-thread-entry__dot { width: 12px; height: 12px; flex: none; margin: 5px 6px 0 0; border-radius: 50%; z-index: 1; }
.og-thread-entry__body { display: flex; flex-direction: column; gap: 5px; min-width: 0; padding-top: 3px; }
.og-thread-entry__head { font: 600 10px var(--font-mono); letter-spacing: .1em; }
/* 折り返す場所の無い一続きの文字（URL・型番）もここで折る。
   横スクロールは閉じてあるので（base.css）、折らないとそのぶんが切れて読めない。 */
.og-thread-entry__text { font: 400 14px/1.5 var(--font-sans); color: var(--ink); text-wrap: pretty; overflow-wrap: anywhere; }

/* ── 全面アクセントの面（旧 PROJ。いまはどの画面も使っていない） ─────── */
.og-accent-screen { flex: 1; background: var(--accent); color: var(--on-accent); display: flex; flex-direction: column; min-height: 0; overflow: auto; }
/* オレンジ全面の上では --bg-2 が使えない（地がテーマ非追従の --accent）。
   段差は「同じ橙を黒側へ寄せた塗り」＋ 2px の隙間で作る。--accent-hi は使わない
   ── ライトでは暗く・ダークでは明るくなり、役割が反転する。 */
.og-proj-row {
  flex: none; width: 100%; border: 0;
  background: color-mix(in srgb, var(--accent) 88%, black);
  margin-top: 2px;
  color: var(--on-accent); padding: 18px 20px 20px; display: flex; align-items: flex-start; gap: 14px;
  text-align: left; cursor: pointer;
}

/* ── TRANSCRIPT 行 ────────────────────────────────────────────────── */
/* 札にはしない。transcript.js が「再生中＝--accent-soft / 再生済み＝--bg-2」の
   塗りで既に状態を語っており、白い札を重ねるとその塗りが読めなくなる。
   会議1本で数十〜百行あるので、角丸と隙間を足すとスクロール量も増える。 */
.og-transcript-line { display: flex; gap: 12px; padding: 12px 0; }
.og-transcript-line__at { width: 44px; flex: none; font: 400 11px var(--font-mono); color: var(--ink-3); padding-top: 3px; }
.og-transcript-line__chip { flex: none; width: 26px; height: 26px; display: flex; align-items: center; justify-content: center; font: 700 9px var(--font-sans); }
.og-transcript-line__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.og-transcript-line__name { font: 600 9px var(--font-mono); letter-spacing: .12em; }
.og-transcript-line__text { font: 400 14px/1.5 var(--font-sans); color: var(--ink); text-wrap: pretty; }

/* ── ソースファイル検索ハイライト ─────────────────────────────────── */
.og-source-body { font: 400 13px/1.6 var(--font-mono); color: var(--ink-2); text-wrap: pretty; overflow-wrap: anywhere; }
.og-source-hit { background: var(--accent-soft); color: var(--accent); }

/* ── FAB / TabBar の固定位置 ──────────────────────────────────────── */
/* 下端固定。TabBar（--tabbar-bottom, 背 44px）の上に 16px 空けて置く。
   TabBar を下げても上げても、この式なら間隔は 16px のまま動かない。
   --tabbar-bottom はホームインジケータの逃げ幅（--safe-bottom）を含む。 */
.og-fab-slot {
  position: absolute;
  right: calc(20px + var(--safe-right, 0px));
  /* 帯（--player-h）が出ている間は、その分だけ丸ごと上へ逃がす。
     帯が無いときは 0px なので、従来と1px も変わらない。 */
  bottom: calc(var(--tabbar-bottom, 14px) + 44px + 16px + var(--player-h, 0px));
  z-index: 5;
}

/* 再生中の帯（モバイル）。TabBar（背 44px）の上に 10px 空けて置く。
   TabBar が position:absolute で浮いている以上、帯を枠の流れに置くと
   同じ位置に降りて下に潜るので、こちらも枠に対して絶対で置く。
   z-index はタブバー(4)より上、FAB と同じ 5 ── DOM 順で FAB が後に来るので、
   万一重なっても FAB が上に出る。帯が空のときは高さ 0 で、何も邪魔しない。 */
.og-player-slot {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(var(--tabbar-bottom, 14px) + 44px + 10px);
  z-index: 5;
}

/* ── フォームのラベル（THE ONE SENTENCE など） ────────────────────── */
.og-form-block { display: flex; flex-direction: column; gap: 8px; }
.og-form-label { font: 600 10px var(--font-mono); letter-spacing: .12em; color: var(--ink-2); }
/* 角は落とす（--r-btn = 10px）。同じフォームの中で、通知の <select> と
   ボタンだけが丸く、文字を打つ欄だけ角のままだと、欄が「別の様式のもの」に見える。 */
.og-textarea {
  /* outline: none は残す。base.css:63-70 の :focus-visible が (0,1,1) で常に勝つ。 */
  border: 0; background: var(--bg-2); color: var(--ink);
  font: 400 15px/1.6 var(--font-sans); padding: 12px 14px; border-radius: var(--r-btn);
  outline: none; resize: none; width: 100%;
}
/* 素の <input> に og-field と同じ枠を与える（DUE の日付欄がこれを使う）。
   font-size は 16px を下回らせない ── iOS は 16px 未満の入力欄を押した瞬間に
   画面を寄せる。寸法が決まっているこの画面では、寄ったぶんが戻らない。 */
.og-input {
  border: 0; background: var(--bg-2); color: var(--ink);
  font: 400 16px var(--font-sans); border-radius: var(--r-btn); outline: none;
  /* 幅は入れ物に従わせる。datetime-local は中身（年月日時分＋ピッカー）から
     最小幅を主張するので、min-width を 0 に落とさないと横へはみ出す。 */
  width: 100%; max-width: 100%; min-width: 0;
  /* ★iOS は datetime-local を**ネイティブの部品**として描き、指定した幅ではなく
     中身に合わせて広げる。スマホだと期日の枠だけが右へ伸び、上下の欄と縁が
     揃わない（Chrome の縮小表示では再現しない ── あちらは指定どおりに描く）。
     appearance を落として、ただの箱として描かせる。押せば端末のピッカーは出る。
     PROJECT の <select>（overlays.js の OVERLAY）が既に同じ手を使っている。 */
  appearance: none;
  -webkit-appearance: none;
}

/* appearance を落とすと iOS は日付の値を箱の中央に置く。左に戻して、
   上下のテキスト欄と行頭を揃える。 */
.og-input::-webkit-date-and-time-value { text-align: left; }

/* ── 空状態 ───────────────────────────────────────────────────────── */
.og-empty { padding: 26px 0; font: 400 14px/1.5 var(--font-sans); color: var(--ink-3); text-wrap: pretty; }
.og-lede { font: 400 13px/1.5 var(--font-sans); color: var(--ink-2); text-wrap: pretty; overflow-wrap: anywhere; }

/* ── ドライブ接続行（STORAGE） ────────────────────────────────────── */
.og-drive-note { font: 400 12px/1.5 var(--font-sans); color: var(--ink-2); text-wrap: pretty; }
.og-mono-path { font: 400 11px var(--font-mono); color: var(--ink-3); word-break: break-all; }

/* デスクトップの横長 MEMO は本文が 20px（原本 dc.html 940行）。
   モバイルの 16px/1.38/-.01em をそのまま使うと、原本より弱く見える。 */
.og-memo-card--wide .og-memo-card__lede {
  font: 400 20px/1.4 var(--font-sans);
  letter-spacing: -.015em;
}
.og-memo-card--wide .og-memo-card__kicker {
  letter-spacing: .14em;
  opacity: .8;
}

/* 枠は画面いっぱいに使う。
   ここに 1560px の上限を置いていたのは、何も止めるものが無いと本文が端から端まで
   伸びて読めなくなるからだった。いまは読むもの（メモ・一覧の行・設定の列）を
   --measure-* で個別に止めているので、枠まで縮める必要がない。
   縮めると、広い画面でサイドバーも盤面も窓の縁に届かず、左右に隙間が空く
   （1733px の画面で左右 86px ずつ）。地の色は同じなので帯には見えないが、
   アプリが窓の真ん中に浮いて見える。 */
.og-frame--desktop {
  width: 100%;
}

/* ══════════════════════════════════════════════════════════════════════
   デスクトップの整え直し

   下の規則はすべて `.og-frame--desktop` の中でしか効かない。モバイルの枠は
   `.og-frame--mobile` なので、ここに何を足しても 390px 側の絵は動かない。
   直しているのは3つだけ：
     (1) 左右の余白を --dt-pad に揃える（16 / 20 / 28 / 48px が混在していた）
     (2) モバイルにあってデスクトップに無かった導線を置ける場所をつくる
     (3) 1560px まで伸びたときに文章と行が横に間延びするのを止める
   ══════════════════════════════════════════════════════════════════════ */

/* ── 画面の見出し帯。5画面で同じ余白・同じ罫にする ─────────────────── */
.og-dt-head {
  flex: none;
  padding: 22px var(--dt-pad) 18px;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px;
}
.og-dt-head__actions { flex: none; display: flex; align-items: center; gap: 10px; }

/* 見出しの下に置く帯（ビュー切替・絞り込み・並べ替え）。頭は見出しと揃える。 */
.og-dt-strip { flex: none; padding: 14px var(--dt-pad) 2px; }

/* 一覧の行を読み幅で止める。中身は左寄せのまま、右端だけが近づく。 */
.og-dt-measure { max-width: var(--measure-row); }

/* MEMO の札は盤面の列の中に、タスクと同じ流れで並ぶ（デスクトップも同じ）。
   盤面の上に専用の帯は持たない ── 帯にすると、盤面に辿り着く前に画面の
   4割が埋まり、しかも本文が1100px 伸びて1行が読み切れない。 */


/* BOARD 以外（LIST / DONE / INBOX）の本体 */
.og-dt-list {
  flex: 1;
  min-height: 0;
  overflow: auto;
  padding: 14px var(--dt-pad) 40px;
}
/* 一覧の中身。**1040px の列を1本**から「入る本数だけ並べる列」へ変えた。
   読み幅の規則（--measure-row）は捨てていない ── 掛ける先を「器」から
   **1本の行**へ移しただけで（下の max-width）、1本しか置けない幅では今までと
   同じ 1040px で止まる。前例は LOAD の .og-dt-load（auto-fit の grid）。

   下限は **800px**。ここは一度 560px にしていて、それは「2 列に割れる最小」で
   あって「題が読める幅」ではなかった ── 実測（実台帳 31 件）で 1440 の展開が
   563px の 2 列に落ち、題の箱が 934 → 457px に半減して **31 件中 5 件**が黙って
   ellipsis で切れた。さらに 1280 でレールに畳むと 992px 1 列（切れ 0）→ 576px
   2 列（切れ 1/2）で、**本文を広げるための操作が読み幅を半分にする**という
   逆立ちが起きていた（agents/design.md §5「黙って切らない」）。
   800px なら 2 列に割れるのは盤面 1616px 以上のときだけで、1920 の展開
   （1622 → 803px × 2・題の箱 697px）と 1920 のレール（1798 → 891px × 2）が
   それに当たる。実測でどちらも切れ 0。1280 / 1440 はレールでも展開でも 1 列
   （＝いままでどおり 1040px 上限）に留まるので、「畳んだら読み幅が縮む」も消える。
   min(100%, …) は器が 800px を下回る段（1280 で右パネルを開いた 582px など）で
   横に溢れさせないための保険。

   縦読みの columns: 2 ではなく grid にしてあるのは、j / k の送り
   （app.js の listNav は DOM 順に .og-dt-list__inner の直下を拾う）と
   目の順（左→右→次の行）を一致させるため。
   **モバイルはこの器を通らない**（tasks.js の renderMobile が自前の flex を組む）。 */
.og-dt-list__inner {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 800px), 1fr));
  gap: 8px 16px;
  align-content: start;
}
/* 読み幅は**行そのもの**に掛ける。トラック側に max を書くと auto-fit の
   本数計算がその max（1040px）で行われ、1142px の盤面でも1列にしかならない
   （実測でそうなった）── 本数は下限 560px で数え、行の伸びはここで止める。
   og-task-row は display: contents なので、器ではなく中の面に当たる必要がある。 */
.og-dt-list__inner > *,
.og-dt-list__inner > og-task-row > * { max-width: var(--measure-row); }
/* TODAY ✓ の帯と「何も無い」の知らせは列に割らない ── 絞りは一覧ぜんぶに
   掛かるものなので、片方の列の頭に置くと「左の列だけの条件」に見える。 */
.og-dt-list__inner > :first-child,
.og-dt-list__inner > .og-empty { grid-column: 1 / -1; }

/* ── 日のシートの行（デスクトップ）。WAVE の右パネルでは .og-wave-day が margin を
   0 に戻す（末尾）。 ── */
.og-frame--desktop .og-agenda-row {
  margin-left: var(--dt-pad);
  margin-right: var(--dt-pad);
  max-width: var(--measure-row);
}

/* ── REC：一覧の行を読み幅で止める ────────────────────────────────── */
/* デスクトップは親（rec.js のスクローラ）が dt-pad を持っている。札は外余白を戻すだけ。 */
.og-frame--desktop .og-rec-row {
  margin-left: 0;
  margin-right: 0;
}

/* ── 全面アクセントの面：他の画面と同じ余白にし、行を読み幅で止める ─────
   見出しと帯（div）は読み幅で切る。行（button）は切らない ── 行を切ると
   区切りの罫まで途中で終わり、オレンジの地の上に線が浮いて見える。
   行は幅いっぱいのまま、右の余白を膨らませて中身だけを読み幅に収める。
   （padding の % は親＝.og-accent-screen の幅を指す） */
.og-frame--desktop .og-accent-screen > div { max-width: var(--measure-row); }
.og-frame--desktop .og-proj-row {
  padding-left: var(--dt-pad);
  padding-right: max(var(--dt-pad), 100% - var(--measure-row));
  gap: 32px;
}

/* ── 設定パネル：見出しの罫と行の罫を同じ1列に収める ──────────────────
   more.js の行は 20px 固定（モバイルの余白）で組まれている。パネル側で
   8px 足して 28px にし、見出しと頭を揃える。 */
.og-dt-settings { max-width: var(--measure-panel); display: flex; flex-direction: column; min-height: 0; }
.og-dt-settings__body { padding-left: 8px; padding-right: 8px; }

/* ── サイドバー：いま設定を見ていることが分かるようにする ───────────── */
.og-sidebar__foot--active { background: var(--bg-2); }
.og-sidebar__foot--active .og-sidebar__foot-label { color: var(--ink); }

/* ── Markdown（DOC のプレビュー） ─────────────────────────────────────
   成果物は章と表と強調で書かれている。素のテキストで出すとその区別が全部
   潰れるので、読むための階段をここで付ける。文字の幅は --measure-text に
   任せる（doc.js 側で掛ける）。 */
.og-md-h { color: var(--ink); letter-spacing: -.02em; margin: 26px 0 10px; }
.og-md-h:first-child { margin-top: 0; }
.og-md-h1 { font: 800 22px/1.25 var(--font-sans); }
.og-md-h2 {
  font: 800 17px/1.3 var(--font-sans);
  /* 罫が消えたぶんの重さを余白で補う（.og-md-h の 10px に +4px）。 */
  padding-bottom: 6px; margin-bottom: 14px;
}
.og-md-h3 { font: 700 14px/1.35 var(--font-sans); }
.og-md-h4, .og-md-h5, .og-md-h6 {
  font: 700 10px var(--font-mono); letter-spacing: .12em; color: var(--ink-3);
}
.og-md-p { font: 400 14px/1.8 var(--font-sans); color: var(--ink-2); margin: 0 0 14px; }
.og-md-strong { font-weight: 800; color: var(--ink); }
.og-md-em { font-style: italic; }
.og-md-strike { color: var(--ink-3); }
.og-md-code {
  font: 400 12px/1.5 var(--font-mono); color: var(--ink);
  background: var(--bg-2); padding: 1px 5px; border-radius: 3px;
  /* 長いパスが1語で入る。箱を割らずに折る。 */
  overflow-wrap: anywhere;
}
.og-md-a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
/* 開けない行き先（http/mailto 以外）は線を引かない。押せないことを見せる。 */
.og-md-a--dead { color: var(--ink-3); text-decoration: none; }
.og-md-pre {
  margin: 0 0 16px; padding: 12px 14px; background: var(--bg-2);
  overflow-x: auto;
}
.og-md-pre code { font: 400 12px/1.65 var(--font-mono); color: var(--ink-2); white-space: pre; }
.og-md-list { margin: 0 0 14px; padding-left: 22px; }
.og-md-list .og-md-list { margin: 6px 0 2px; }
.og-md-li { font: 400 14px/1.75 var(--font-sans); color: var(--ink-2); margin-bottom: 6px; }
.og-md-li::marker { color: var(--ink-3); }
.og-md-quote {
  /* 引用の帯は「物」。塗りの箱にすると .og-md-pre と見分けが付かない。 */
  margin: 0 0 16px; padding: 2px 0 2px 14px; border-left: 3px solid var(--neutral-mid);
}
.og-md-quote .og-md-p:last-child { margin-bottom: 0; }
/* <hr> は「罫線という意味」そのもの。塗りのバーで置き換える
   （1px の --bg-2 だとライトで #E9E9E9 on #F4F4F4 になって実質見えない）。 */
.og-md-hr { border: 0; height: 2px; background: var(--neutral-mid); margin: 22px 0; }
/* 表だけを箱の中で流す。面ごと横に動かさない。 */
.og-md-tablewrap { overflow-x: auto; margin: 0 0 18px; }
.og-md-table { border-collapse: collapse; width: 100%; }
.og-md-th {
  font: 600 10px var(--font-mono); letter-spacing: .1em; color: var(--ink-3);
  padding: 8px 12px; white-space: nowrap; background: var(--bg-2);
}
.og-md-td {
  font: 400 13px/1.6 var(--font-sans); color: var(--ink-2);
  padding: 9px 12px; vertical-align: top;
}
/* 罫の代わりに1行おきの塗り。md.js / docx.js とも <tbody> を出すので両方に効く。 */
.og-md-table tbody tr:nth-child(even) .og-md-td { background: var(--bg-2); }
.og-md-td .og-md-strong { color: var(--ink); }


/* ══════════════════════════════════════════════════════════════════════
   画面をまたいで使い回す共有クラス

   ここから下は **まだどの .js からも呼ばれていない**。既存の画面は1pxも
   動かない ── 動き出すのは、各画面のインライン style をこのクラスへ
   寄せたあとから。寄せる側が使う置き場としてだけ、先に置く。

   寸法はすべて**モバイルを正**にする（左右 20px ＝ 面の本文の余白）。
   デスクトップは `.og-frame--desktop .og-xxx` で左右だけ 0 に落とす ──
   あちらは入れ物（.og-dt-list / .og-dt-head）が既に --dt-pad を持って
   いるので、ここで 20px を足すと二重になる。上書きはクラスごとに1本ずつ
   書く。既にある .og-rec-row の1本（上方）はあの行にしか効かない。
   ══════════════════════════════════════════════════════════════════════ */

/* ── 折りたたみ見出しの ▸ ─────────────────────────────────────────────
   more.js / cal.js / doc.js / tasks.js が同じ7プロパティを別々のインライン
   style で書いていた。開いている状態は --open で表す ── 角度を JS が
   その場で計算せず、クラスが在るか無いかだけで決まるようにする。 */
.og-group-head__caret {
  flex: none;
  display: inline-block;
  font: 400 15px var(--font-mono);
  color: var(--ink-3);
  transform: rotate(0deg);
  transition: transform var(--dur-swap) var(--ease-rise);
}
.og-group-head__caret--open { transform: rotate(90deg); }

/* ── REC の見出し（ライブラリ一覧の上に載る折りたたみ）───────────────
   padding は 14px 20px。左右を 0 で書くとモバイルで行（.og-rec-row の
   16px 20px）と頭が揃わないうえ、下のデスクトップ上書き（0）が
   「もともと 0」になって何も打ち消さない規則に化ける。

   罫は持たない。行（.og-rec-row）が --surface の札になったので、見出しは
   「札の外に立つ見出し」になった。旧: 行が border-top を持つため、見出しを
   border-bottom に揃えると1本の線が2本に見えた ── その回避策ごと不要になった。 */
.og-group-head--rec {
  padding: 14px 20px;
}
.og-frame--desktop .og-group-head--rec { padding-left: 0; padding-right: 0; }

/* 畳んである列・件数が0の列。見出しごと一段落とす。 */
.og-group-head--muted,
.og-group-head--muted .og-group-head__label,
.og-group-head--muted .og-group-head__count { color: var(--ink-3); }

/* ── 告知（サーバが返した but/注意書きを、面の頭に1枚だけ置く）─────────
   一覧の札（--surface）より**一段沈めた** --bg-2 のトレイにして、地の段差で
   「本文ではない」ことを示す。枠は持たない。
   器を持たない案は採らない ── 使う場所5つのうち4つが --surface のシート／
   パネルの中（overlays.js の3つと plan.js）で、塗りが無いと完全に溶ける。 */
.og-notice { padding: 0 20px; }
.og-notice__body {
  border: 0;
  background: var(--bg-2);
  border-radius: var(--r-card);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.og-notice__kicker { font: 600 10px var(--font-mono); letter-spacing: .12em; color: var(--ink-3); }
.og-notice__text {
  font: 400 13px/1.55 var(--font-sans); color: var(--ink-2);
  text-wrap: pretty; overflow-wrap: anywhere;
}
.og-frame--desktop .og-notice { padding-left: 0; padding-right: 0; }

/* ── 札を並べる帯（絞り込みの候補・タグ）──────────────────────────────
   折り返す。390px で横に溢れても .og-scroll が黙って切るだけなので、
   1行に収めようとしない。 */
.og-chip-row {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
  padding: 0 20px;
}
.og-frame--desktop .og-chip-row { padding-left: 0; padding-right: 0; }

/* ── 絞り込みパネル（見出しの下に開く面）───────────────────────────── */
.og-filter-panel {
  padding: 12px 20px 16px;
  /* 開く面なので「浮いた面」＝ --surface。--bg-2 にしてはいけない ──
     中の og-chip の非選択が --bg-2 で、同色になって消える。 */
  background: var(--surface);
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.og-filter-panel__group { display: flex; flex-direction: column; gap: 8px; }
.og-filter-panel__label { font: 600 10px var(--font-mono); letter-spacing: .12em; color: var(--ink-3); }
.og-frame--desktop .og-filter-panel { padding-left: 0; padding-right: 0; }

/* ── いま掛かっている絞り込み（畳んだあとも残す帯）────────────────────
   札も「解除」も押せる。押せるものは 44px を下回らせない ── 指で外せない
   絞り込みは、掛かっていないのと同じくらい困る。 */
.og-active-filters {
  padding: 10px 20px;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.og-active-filters__chip {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 44px; padding: 0 12px;
  border: 0; border-radius: var(--r-btn);
  background: var(--bg-2); color: var(--ink-2);
  font: 600 10px var(--font-mono); letter-spacing: .1em;
  cursor: pointer;
}
.og-active-filters__clear {
  min-height: 44px; padding: 0 4px;
  border: 0; background: none; color: var(--accent);
  font: 600 10px var(--font-mono); letter-spacing: .12em;
  cursor: pointer;
}
.og-frame--desktop .og-active-filters { padding-left: 0; padding-right: 0; }

/* ── モバイルの見出し帯と、その下の面切替の帯 ──────────────────────────
   デスクトップの .og-dt-head / .og-dt-strip と同じ役目のモバイル版。
   別名にしてあるのは余白の出所が違うから ── あちらは --dt-pad、
   こちらは面の 20px。 */
.og-mb-head {
  flex: none;
  /* 見出しの帯は全画面で同じ寸法（TASKS の型）。18px/12px だと REC の見出しだけ
     10px 下がって始まっていた。 */
  padding: 10px var(--gutter-mobile) 14px;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
}
.og-mb-strip {
  flex: none;
  padding: 0 20px 12px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.og-frame--desktop .og-mb-head { padding-left: 0; padding-right: 0; }
.og-frame--desktop .og-mb-strip { padding-left: 0; padding-right: 0; }

/* ── 面の本文 ─────────────────────────────────────────────────────────
   og-scroll を**置き換えない**。併記して使う： class="og-scroll og-mb-body"
   横の締め（base.css の overflow-x: hidden !important）とスクロールバーの
   見た目は og-scroll 側に乗っている。ここで overflow の一括指定を書くと
   x も一緒に上書きしてしまうので、縦だけに触れる。 */
.og-mb-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

/* ── 検索の当たり ─────────────────────────────────────────────────────
   サーバは html.escape 済みの snippet に <mark> を入れて返す（UI 側が
   html: を使う唯一の経路）。なのに mark への指定が1つも無く、ブラウザ既定の
   黄色地・黒文字のまま出ていた ── ダークでも黄色で、そこだけ別のアプリに
   見える。同じ役目の .og-source-hit と見え方を揃える。

   **素の `mark` には書かない。** `<mark>` が入るのは search.js の
   `.og-search-snippet` ただ1つ（`html:` を使う唯一の経路がそこだけ）なので、
   要素セレクタで全体に効かせる理由が無い。素で書くと、この先どこかが
   `<mark>` を使った瞬間に**触った覚えのない色が付く**。 */
.og-search-snippet mark { background: var(--accent-soft); color: var(--accent); }

/* ── PDF のテキスト層（幾何） ─────────────────────────────────────────
   出典: pdfjs-dist@6.2.108 の web/pdf_viewer.css の `.textLayer` 系。
   ビューア一式（web/pdf_viewer.mjs / .css）は同梱していない（経緯は
   static/vendor/README.md）が、**テキスト層の座標はあのファイルにしかない**
   ので、該当の規則だけここへ写した。

   これは「見た目」ではなく**幾何**である。--total-scale-factor /
   --text-scale-factor と span の position:absolute / white-space:pre /
   transform: rotate() scaleX() scale() が無いと、選択と検索のための
   透明な文字が canvas のグリフと**ずれる**。
   よって Orange Grid のトークンで置き換えない。数値も「整えない」。

   写すにあたって変えたもの / 変えなかったもの:
   - 入れ子（`&` / `:is()`）は**展開して**素の CSS にした。このリポジトリには
     ビルド工程が無く、ブラウザがこのファイルを直接読むため。
   - **自分で付ける**クラス（器の .textLayer）だけ .og-pdf-textlayer に改名した。
   - **pdf.js が付ける**クラス（markedContent / endOfContent /
     textLayerImages / textLayerImagePlaceholder）と、pdf.js が style に書き込む
     CSS 変数（--total-scale-factor / --font-height / --scale-x / --rotate /
     --min-font-size）は**名前をそのままにした**。改名すると規則が当たらず、
     寸法がゼロになったり display:contents が効かなくなったりして黙って崩れる。
     素の名前が外へ漏れないよう、すべて .og-pdf-textlayer の下に閉じてある。
     （textLayerImages は TextLayer が器の中に append するので入れ子でよい。）

   写さなかったもの（**落としたことを黙っていないための一覧**）:
   - `.highlight` 系（find の当たり）… web/ の findController が付けるクラス。
     同梱していない。色も --hcm-highlight-filter も viewer.css 側にあった。
     この画面の検索の当たりは下の .og-pdf-hit を使う。
   - `.highlighting` のカーソル指定 … 蛍光ペンのエディタ用。
     --editorFreeHighlight-editing-cursor が viewer.css 側にあり、エディタも
     使わない。
   - `.editToolbar` 一式 … エディタのツールバー UI。images/*.svg ごと落とした。
   - `.selectionRendering` の ::selection … web/ の選択描画用。同梱していない。
   - `.textLayer.selecting ~ & section` … `.annotationLayer` の入れ子の断片。
     注釈層は出さないので当たる相手がいない。

   .og-pdf-textlayer--selecting と .endOfContent の要素は web/ の
   text_layer_builder が付けていたもので、それも同梱していない。
   **この画面の側（static/views/pdf.js）で付ける**こと。付けないと、
   最終行より下をドラッグしたときに選択が伸びない。 */

.og-pdf-textlayer {
  color-scheme: only light;

  position: absolute;
  text-align: initial;
  inset: 0;
  overflow: clip;
  opacity: 1;
  line-height: 1;
  letter-spacing: normal;
  word-spacing: normal;
  -webkit-text-size-adjust: none;
     -moz-text-size-adjust: none;
          text-size-adjust: none;
  forced-color-adjust: none;
  transform-origin: 0 0;
  caret-color: CanvasText;
  z-index: 0;

  --min-font-size: 1;
  --text-scale-factor: calc(var(--total-scale-factor) * var(--min-font-size));
  --min-font-size-inv: calc(1 / var(--min-font-size));
}

/* 元は `:is(span, br)`。展開してある。 */
.og-pdf-textlayer span,
.og-pdf-textlayer br {
  color: transparent;
  position: absolute;
  white-space: pre;
  cursor: text;
  transform-origin: 0% 0%;
  -webkit-user-select: text;
     -moz-user-select: text;
          user-select: text;
}

.og-pdf-textlayer > :not(.markedContent),
.og-pdf-textlayer .markedContent span:not(.markedContent) {
  z-index: 1;

  --font-height: 0;
  font-size: calc(var(--text-scale-factor) * var(--font-height));

  --scale-x: 1;
  --rotate: 0deg;
  transform: rotate(var(--rotate)) scaleX(var(--scale-x)) scale(var(--min-font-size-inv));
}

.og-pdf-textlayer .markedContent {
  display: contents;
}

.og-pdf-textlayer span[role="img"] {
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
  cursor: default;
}

.og-pdf-textlayer ::-moz-selection {
  background: rgba(0 0 255 / 0.25);
  background: color-mix(in srgb, AccentColor, transparent 50%);
  color: transparent;
}

.og-pdf-textlayer ::selection {
  background: rgba(0 0 255 / 0.25);
  background: color-mix(in srgb, AccentColor, transparent 50%);
  color: transparent;
}

.og-pdf-textlayer br::-moz-selection {
  background: transparent;
}

.og-pdf-textlayer br::selection {
  background: transparent;
}

.og-pdf-textlayer .endOfContent {
  display: block;
  position: absolute;
  inset: 100% 0 0;
  z-index: 0;
  cursor: default;
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
}

.og-pdf-textlayer.og-pdf-textlayer--selecting .endOfContent {
  top: 0;
}

/* 元は top-level の `.textLayerImages`。TextLayer が器の中へ append するので
   .og-pdf-textlayer の下に閉じてある（素の名前を外へ出さないため）。 */
.og-pdf-textlayer .textLayerImages {
  position: absolute;
  inset: 0;
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
}

.og-pdf-textlayer .textLayerImages canvas {
  position: absolute;
  transform-origin: 0% 0%;
}

/* ── 検索の当たり ─────────────────────────────────────────────────────
   .og-source-hit を流用しない。あれは文字色を**不透明にする**クラスで、
   テキスト層の span は color: transparent が前提。当てるとその語だけ
   二重に描かれて canvas のグリフとずれる。地だけ差して字は透明のまま。 */
.og-pdf-hit {
  background: var(--accent-soft);
  color: transparent;
}

/* ── MATRIX（期日 × PJ）─────────────────────────────────────────────
   行＝期日のまとまり／列＝PJ。交点に札そのものを積む（views/tasks.js）。

   **横へ流す専用の箱。** `.og-scroll` は base.css が overflow-x を潰している
   ので使えない（タブバーの `.og-tabbar__scroll` と同じ事情）。 */
.og-mx-scroll {
  overflow-x: auto;
  /* **`visible` と書かない。** 片方が visible 以外なら、もう片方も仕様で auto に
     化ける ── 実際 `overflow-y: visible` が auto になって縦の入れ子スクロールが
     生まれ、指がどちらの箱を送っているのか分からなくなっていた。
     高さは中身なりに伸びるので、hidden でも縦は切れない（縦送りは親の .og-scroll）。 */
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
}
.og-mx-scroll::-webkit-scrollbar { display: none; }

.og-mx { display: flex; flex-direction: column; width: max-content; }

/* **行は交互に塗る。** 横へ長く流す面なので、目が右へ渡るときに1行ぶん上下へ
   ずれる。罫は引かない（§1 の2番）ので、地の側で段を作る。
   gap を持たせると縞が途切れるので、行間は padding で取る。 */
.og-mx-row {
  display: flex; align-items: stretch; gap: var(--board-gap);
  padding: var(--board-gap) 0;
}
/* 見出しは縞に数えない。見出しが 1 本目なので、札の行は 2 本目から始まる
   ── `even` が「最初の札の行」。`:not()` を挟まないと、見出し行のほうが
   詳細度で負けて縞に化ける（実際そうなった）。 */
.og-mx-row:not(.og-mx-row--head):nth-of-type(even) {
  background: var(--bg-2);
  /* **左端だけ角を丸める。** 縞は右へ流れて画面の外まで続くので、右は切り口の
     まま。左は行の始まりで、そこだけ丸めると縞が「置かれた帯」に見える
     （四角のままだと地を切った線に見え、罫を引かない方針とぶつかる）。 */
  border-top-left-radius: var(--r-card);
  border-bottom-left-radius: var(--r-card);
}

/* 期日ラベル。**貼り付く側**なので、横へ流しても行が何かを見失わない。
   地を敷くのは、下を札が通り抜けるため（透けると字が読めない）。 */
/* 貼り付く側。**地は敷かない。** 行の地がそのまま透けるので、静止している
   あいだは敷いても敷かなくても同じ絵になる ── 敷かないほうが、行に掛けた
   フィレットを潰す心配も、縞と1pxずれる心配も無い。
   （横へ流しているあいだだけ、下を通る札がラベルの後ろに覗く。
   MAP は窓に収まるので流れない。MATRIX で読みにくければ `inherit` に戻す。） */
.og-mx-rowhead, .og-mx-corner {
  position: sticky; left: 0; z-index: 2;
  flex: none; width: var(--mx-label); box-sizing: border-box;
  background: transparent;
}
/* **縦組みにして桁を1字ぶんに落とす。** 横書きのままだと「それ以降」で 62px 要り、
   375px の窓ではそれだけで列が半分近く削れる。`writing-mode` は回転ではなく
   組み方向の指定なので、和字は立ったまま（読める向き）で、数字だけが横に寝る。 */
.og-mx-rowhead {
  writing-mode: vertical-rl;
  display: flex; flex-direction: row; align-items: center; justify-content: flex-start;
  gap: 6px; padding: 4px 0 0;
}
.og-mx-rowhead__name { font: 700 11px var(--font-mono); letter-spacing: .04em; color: var(--ink-2); white-space: nowrap; }
.og-mx-rowhead__n { font: 400 9px var(--font-mono); color: var(--ink-3); }
/* 期限切れだけは色そのものを替える（design.md §2-2「状態の強さ」の軸）。 */
.og-mx-rowhead--overdue .og-mx-rowhead__name { color: var(--overdue); }

/* PJ の見出し。行の中では一段沈めた欄として置く。 */
/* PJ の見出し。`overflow-y: hidden` の箱の中では top への sticky は効かない
   （その箱が縦に送られないため）ので、貼り付けようとしない。 */
.og-mx-row--head { background: var(--bg); padding: 0 0 4px; }
.og-mx-colhead {
  flex: none; width: var(--mx-col); box-sizing: border-box;
  display: flex; align-items: center; justify-content: space-between; gap: 6px;
  height: 22px; padding: 0 8px; border-radius: var(--r-knob);
  background: var(--bg-2);
  font: 700 9px var(--font-mono); letter-spacing: .1em; color: var(--ink-2);
}
.og-mx-colhead__n { font-weight: 400; color: var(--ink-3); }

/* 交点。札は盤面と同じものを積む（幅だけ列に合わせる）。 */
.og-mx-cell {
  flex: none; width: var(--mx-col); box-sizing: border-box;
  display: flex; flex-direction: column; gap: var(--board-gap);
  align-content: flex-start;
}

/* ── 幅のある窓（iPad 横・デスクトップ）: 列は「入るだけ広げる」──────────
   --mx-col（124px）は tokens.css が自分で「札のタイトルが2行で読める**最小**」と
   書いている値なので、デスクトップではそれを**下限**に降ろし、余った幅を列に配る。
   これまでは幅が増えても増えるのは右の余白だけで、1920 の窓では箱 1622px に対して
   中身が 932px 固定 ── 横を 690px 遊ばせながら縦にスクロールしていた。

   上限は --mx-col-max。広げ切ると1画面に入る PJ が減るので、そこで止める。
   PJ が増えて下限（124px）に張り付いたら、これまでどおり .og-mx-scroll が
   横へ流す ── その逃げ道を消さないために min-width を必ず残すこと。
   .og-mx の min-width: min-content が、その「入り切らないぶん」を箱に伝える
   （width: max-content のままだと上限側で行が器より広いまま固まる）。
   見出しの行と札の行は別の flex なので、**同じ寸法を両方に当てて**桁を合わせる。
   **段は枠ではなく幅で引く**（2026-09-05）。以前は `.og-frame--desktop` 配下に
   置いていたが、デスクトップの枠に入る条件は「幅」だけでなく**マウスがあること**
   （hover: hover / pointer: fine。app.js の MEDIA）── iPad は 1024px あっても
   `hover: none` を返すのでモバイルの枠のまま来る。結果、iPad の MATRIX は 124px 固定の
   列が左に寄り、**右が大きく余っていた**（実測 1024 で盤面 1008 に対し中身 542px、
   466px が空。依頼主 2026-09-05「matrix の画面が ipad で見た時、横幅いっぱいに
   ならない」）。列の幅は指かマウスかではなく窓の幅の話なので、`data-og-width`
   （≥700 で wide。デスクトップは必ずその内側）で引く。
   モバイル（narrow）はここに来ないので 124px 固定のまま。 */
html[data-og-width="wide"] .og-mx { width: auto; min-width: min-content; }
html[data-og-width="wide"] .og-mx-colhead,
html[data-og-width="wide"] .og-mx-cell {
  flex: 1 1 var(--mx-col); width: auto;
  min-width: var(--mx-col); max-width: var(--mx-col-max);
}

/* ══════════════════════════════════════════════════════════════════════
   WAVE — 日ごとの忙しさの帯（views/wave.js。docs/18_WAVE_AND_RESPONSIVE.md §2-1）

   行＝日（等高 --wave-row）、横＝忙しさ。左に日付のレール 56px、その右に曲線
   （裏に SVG 1 枚）、曲線に重ねて右寄せに札。**罫線は引かない** ── 帯の中で
   線が許されるのは上限の目盛り（SVG の line、--neutral-mid）1本だけ。
   幅の段は html[data-og-width] / .og-frame--desktop で分岐する（@media は書かない）。
   ══════════════════════════════════════════════════════════════════════ */

/* 凡例。PJ 色の点＋コードのピル列。行は 44px（指の的）、ピルは 32px（帯の中の部品）。
   .og-scroll は overflow-x を潰しているので、横に流す器はここで持つ。 */
.og-wave-legend-host { display: flex; align-items: center; min-height: 44px; }
.og-wave-legend {
  display: flex; align-items: center; gap: 6px;
  padding: 0 20px 8px; min-width: 0; max-width: 100%;
  overflow-x: auto; -ms-overflow-style: none; scrollbar-width: none;
}
.og-wave-legend::-webkit-scrollbar { display: none; }
.og-wave-pill {
  flex: none; height: 32px; padding: 0 12px 0 10px; border: 0; border-radius: var(--r-knob);
  background: var(--bg-2); color: var(--ink-2);
  font: 700 10px var(--font-mono); letter-spacing: .12em;
  display: flex; align-items: center; gap: 7px; cursor: pointer;
  transition: opacity var(--dur-swap) var(--ease-linear), background var(--dur-tap) var(--ease-linear);
}
/* 丸＝点（PJ の印は面の語彙で「点」）。 */
.og-wave-pill__dot { width: 8px; height: 8px; flex: none; border-radius: 50%; }
.og-wave-pill--on { background: var(--ink); color: var(--on-ink); }
.og-wave-pill--dim { opacity: .25; }
/* この窓に値の無い PJ。**消さずに沈める** ── 作ったばかりの PJ や、いま静かな PJ も
   絞り込みには要る（無いと「反映されていない」に見える）。境目は塗りの段で言う。 */
.og-wave-pill--quiet { color: var(--ink-3); }
.og-wave-pill--quiet .og-wave-pill__dot { opacity: .35; }
/* 先頭の `ALL`＝「絞り込みを外す」。点を持たないので左の余白を右とそろえる。 */
.og-wave-pill--all { padding: 0 12px; }
/* 選んでいる駒の `×`。外す口がその場にあると読めるように。 */
.og-wave-pill__x { margin-left: 1px; opacity: .7; font-size: 12px; line-height: 1; }
.og-wave-today {
  flex: none; height: 32px; padding: 0 12px; border: 0; border-radius: var(--r-knob);
  background: var(--bg-2); color: var(--ink-2);
  font: 700 10px var(--font-mono); letter-spacing: .12em; cursor: pointer;
}
/* 凡例が見出しの右に入る段（wide / desktop）は下の余白を持たない。 */
.og-mb-head .og-wave-legend, .og-dt-head .og-wave-legend { padding: 0; }

/* 日付のレールを長押ししているあいだだけ出る「その日の札」の板（2026-09-05。
   依頼主「wave の日付を長押しすると、長押ししている間はその日のタスクがリストで
   表示されるようにする。長押しをやめると元に戻る」）。
   **面ではなく帯の上の 1 枚**（present を通さない ── 覗きは行き先ではない）。
   罫線ゼロ・影ゼロの規則どおり、境は塗りの段（--surface）だけで語る。
   `pointer-events: none` ── 押しているのはレールで、この板は絵でしかない。 */
/* 丈（max-height）は **JS が置く**（wave.js の `placePeek`）── 送り箱の見えている
   高さは `60vh` とは限らない（見出し・凡例・タブ帯のぶん低い）。ここでは逃げの値
   だけ持つ。 */
.og-wave-peek {
  position: absolute; left: 56px; right: 0; z-index: 4; pointer-events: none;
  max-height: 60vh; overflow: hidden;
  display: flex; flex-direction: column; gap: 2px;
  padding: 10px 12px; border-radius: var(--r-card);
  background: var(--surface);
}
.og-wave-peek__head {
  font: 700 10px/1 var(--font-mono); letter-spacing: .12em; color: var(--ink-3);
  padding: 0 0 6px;
}
.og-wave-peek__row { display: flex; align-items: stretch; gap: 8px; padding: 4px 0; }
.og-wave-peek__rail { width: 3px; flex: none; border-radius: 2px; }
.og-wave-peek__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.og-wave-peek__main {
  font: 600 13px/1.3 var(--font-sans); color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.og-wave-peek__meta { font: 400 9px/1 var(--font-mono); letter-spacing: .08em; color: var(--ink-3); }
.og-wave-peek__empty { font: 400 12px var(--font-sans); color: var(--ink-3); }
/* 丈で切れて落とした行の数（wave.js の `trimPeek`）。黙って切らないための 1 行。 */
.og-wave-peek__more {
  font: 400 10px/1 var(--font-mono); letter-spacing: .08em; color: var(--ink-3);
  padding: 6px 0 0; flex: none;
}

/* 帯。SVG の基準（position: relative）。
   `overflow-anchor: none` は「窓を伸ばしたときの位置合わせを 2 か所でやらない」ため
   ── 行を上に足すと、ブラウザの scroll anchoring も scrollTop を直そうとする。
   ずれの手当ては wave.js（増えた行 × 行の高さ）1 か所に置く。 */
.og-wave-band { position: relative; overflow-anchor: none; }
.og-wave-svg { position: absolute; top: 0; pointer-events: none; display: block; }

/* 行は等高。札で伸ばさない（曲線の形を歪めないため）。 */
.og-wave-row {
  position: relative; height: var(--wave-row); display: flex; align-items: stretch;
  cursor: pointer;
}
/* 「選択中」は outline（レイアウトを動かさない輪郭）。今日は数字の塗りで語る。 */
.og-wave-row--selected { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: var(--r-btn); }

/* 日付のレール。曜日の頭文字（mono 10px）と日（17/700）。 */
.og-wave-rail {
  width: 56px; flex: none; position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
}
/* 曜日と日を括る器。**今日の塗りはここに付く**（下）。どの行にも置くので、
   今日でない行では見た目に出ない（地も枠も持たない）。 */
.og-wave-rail__stamp {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 1px; padding: 4px 5px; box-sizing: border-box;
}
.og-wave-rail__dow { font: 600 10px/1 var(--font-mono); letter-spacing: .08em; color: var(--ink-3); }
.og-wave-rail__num {
  font: 700 17px/22px var(--font-sans); letter-spacing: -.01em; color: var(--ink);
  min-width: 22px; height: 22px; text-align: center;
}
/* 土日は薄く。行の高さは同じ（判定はしない ── 上限を台帳が知らない日）。 */
.og-wave-row--rest .og-wave-rail__num { color: var(--ink-3); font-weight: 600; }
/* 今日は --ink 塗りの**縦楕円**（2026-09-05。依頼主「今日の部分は塗を縦長にして、
   曜日も一緒に入るように。縦楕円がいい」）。以前は数字だけを括る横長の錠剤で、
   曜日が塗りの外に残っていた ── 曜日まで括ると「今日」がレールの1つの粒として読める。
   32×41px（4+10+1+22+4）の縦長。**角は丸めるだけ**（`--r-btn` 10px。2026-09-05 ──
   依頼主「曜日の楕円が変なので、フィレットをかける方式に。他のボタンと同じような
   感じ」）。`border-radius: 50%` の真の楕円は 32×41 では上下が尖って見え、この画面の
   他の器（og-button / og-icon-button の `--r-btn`）と語が揃わなかった。
   41px は 2W の行（56px / narrow 48px）にどちらも収まる。塗りは暦の「今日」と同じ
   --ink ── 橙は全注意のときだけ（agents/design.md §3）。 */
.og-wave-row--today .og-wave-rail__stamp {
  background: var(--ink); border-radius: var(--r-btn); min-width: 32px;
}
.og-wave-row--today .og-wave-rail__dow,
.og-wave-row--today .og-wave-rail__num { color: var(--on-ink); }
/* 月の変わり目。行を挟まず、レールの上端に月名（mono 9px）。 */
.og-wave-rail__month {
  position: absolute; top: 2px; left: 0; width: 56px; text-align: center;
  font: 600 9px/1 var(--font-mono); letter-spacing: .12em; color: var(--ink-3);
}

/* 曲線の列。印（節目）はこの中に絶対で置く。 */
.og-wave-curve { flex: 1; min-width: 0; position: relative; }
/* 節目の印。**押せる**（タップ → 節目のシート、長押し → 暦）ので的は行の高さ ×
   44px 以上 ── 丸（10px）と名は表示で、的は左右 12px の余白と min-width が持つ
   （agents/design.md §4「10px の点をタップ対象にしない」）。`left` は丸の x のまま
   （margin-left で余白ぶん戻す）。行タップ（日のシート）はこの外だけ。 */
.og-wave-mark {
  position: absolute; top: 0; bottom: 0; z-index: 2; box-sizing: border-box;
  display: flex; align-items: center; gap: 5px; white-space: nowrap;
  padding: 0 12px; margin-left: -12px; min-width: 44px; cursor: pointer;
  touch-action: pan-y;
}
.og-wave-mark__dot { width: 10px; height: 10px; flex: none; border-radius: 50%; }
.og-wave-mark__label { font: 600 10px/1 var(--font-mono); letter-spacing: .06em; color: var(--ink-2); }
/* カンバスとの滑り（`カンバス 10/16`）。器のあるチップ = 所属あり（カンバスに項目がある）。 */
.og-wave-mark__chip {
  height: 16px; padding: 0 5px; border-radius: var(--r-knob);
  background: var(--bg-2); color: var(--ink-2); font: 600 10px/16px var(--font-mono); letter-spacing: .04em;
}
/* 右端で名が切れるときは丸の左へ折り返す。丸は同じ x に立つ（translateX で名の幅ぶん左へ）。 */
.og-wave-mark--flip { flex-direction: row-reverse; transform: translateX(calc(-100% + 34px)); }
/* 推定（inferred）は確実さの語彙 = 同色の不透明度 .45。 */
.og-wave-mark--inferred { opacity: .45; }
/* 掴んだ印（duesheet.js の og-card--lifted）。透明な的ではなく丸に輪郭を出す。 */
.og-wave-mark.og-card--lifted { outline: 0; transform: none; }
.og-wave-mark--flip.og-card--lifted { transform: translateX(calc(-100% + 34px)); }
.og-wave-mark.og-card--lifted .og-wave-mark__dot { outline: 2px solid var(--ink); outline-offset: 2px; }

/* 札の列。narrow は曲線に重ねる ── 置き場は**レールの右端から上限の目盛りまで**、
   つまり「上限（capacity_h）の内側」ちょうど。

   **なぜ右端ではなく内側か。** 実台帳（375。2026-09-04）で採寸すると、行の右 60%
   （曲線の x 86〜311 / 幅の 27〜98%）に札を置いたとき、上限の目盛りは幅の 71%
   ＝ 札の下 142px にあり、**3.02h/日 を超えた日の山はすべて札の下**に立っていた
   （64 日のうち 54 日 = 84%）。札のある 9 行では 9 行とも、山の頂の点
   （頂の x × 行の中央）が札の面に覆われていた ── いちばん読みたい山が、
   ちょうど札のある場所。押し出し（印の右端まで札の左端を押す）も効かず、
   9-07（44.3h）は札が 72px・題が **17px**（1 字）まで痩せて、山はなお下のまま。

   内側に移すと、札の右端＝上限の目盛りになる。**札の右にはみ出したぶんが超過**
   という読み方が 1 つ増え、超過の側（幅の 71〜100%）は空く。札の下に入るのは
   上限より軽い日の山だが、実台帳の札のある 9 行はすべて 17h 以上（上限の 2 倍超）で、
   **札の下に隠れる山は 0 行**になる。札の幅も 60%（225px）→ 71.4%（227.9px）で
   痩せない。

   **この「0 行」は、いまの台帳が過負荷だから成り立っている**（無条件の性質ではない。
   反証レビュー R-6）。札は曲線の x 0〜227.8 ＝ 負荷 0〜8.0h をちょうど覆うので、
   **上限以下の日に札が付いた瞬間、その日の山は 1px も見えなくなる**（右 60% に
   置いていたころは 3.0h までの日は見えていた）。いまの実台帳は 64 日中 49 日（77%）が
   上限超・最大 44.3h で、上限以下の日は 15 日ある ── 積み残しが片付いて平常に
   戻ったら、この置き方は逆に働く。**負荷の分布に依らない形は「曲線は全幅のまま、
   札の下に来たぶんだけ不透明度を落とす」**（clip で 2 層。曲線の「過去は .45」と
   同じ手）で、そちらへ移すときの入口はここ。docs/18 §2-1。

   1.4 は上限の目盛りの位置（views/wave.js の OVER_SCALE）。56px はレールの幅
   （.og-wave-rail）。どちらも片方を変えたらもう片方も。 */
.og-wave-cards {
  position: absolute; top: 0; left: 56px; bottom: 0;
  width: calc((100% - 56px) / var(--wave-over-scale)); z-index: 1;
  display: flex; flex-direction: column; justify-content: center;
  /* wide / desktop で flex の列になったとき、札の題（nowrap）の min-content に
     引きずられて 55% を超えて膨らまないように。narrow（absolute）では効かない。 */
  min-width: 0;
}
/* 札。**外側（.og-wave-card）は透明な的、面は __in。**
   面は --wave-card（26 / デスクトップ 22）のまま、的は**面 + 上下 1px**（28 / 24。
   反証レビュー F5 の決定）。26px の面そのものを的にすると、上下の外し・2 枚の隙間 2px を
   押したときに札ではなく日のシートが開く（agents/design.md §4「10px の点を
   タップ対象にしない」）。2 枚のときは行を 2 分（56 → 28 ずつ、48 → 24 ずつ）で
   ちょうど収まる。デスクトップの 24 を 28 に広げなかったのは、48 の行に 28 × 2 は
   入らず、隣の行や同じ行の相方と的が重なって**後の DOM が勝ち、片方の的が 20 に減る**
   （実測）── 重ならない 24 のほうが広い。**1 枚のときは 44px**（触れるものの規則）を
   行の中央に。行ぜんぶ（56）にしない ── 行タップ（日のシート）の的を札の外に残す。
   行を伸ばすと曲線の形が歪む（docs/18 §2-1）ので、行は等高のまま。
   面（__in）は的の中で上下中央に: 面を 28px にすると 2 枚で行を使い切って隙間が無くなる。
   長押しで暦がせり上がる（duesheet.js が display:block を当てるので、
   外側は block、中の並びは __in が持つ）。 */
.og-wave-card {
  display: block; position: relative; flex: 1 1 auto; min-height: calc(var(--wave-card) + 2px); min-width: 0;
  color: var(--ink); cursor: pointer;
  transition: opacity var(--dur-swap) var(--ease-linear);
}
.og-wave-card:only-child { flex: 0 0 var(--tap-min); min-height: var(--tap-min); }
.og-wave-card__in {
  position: absolute; left: 0; right: 0; top: 0; bottom: 0; margin: auto 0; height: var(--wave-card);
  display: flex; align-items: center; gap: 8px; padding-right: 10px;
  border-radius: var(--r-btn); background: var(--surface); overflow: hidden;
}
/* 掴んだ印（duesheet.js の og-card--lifted）は面に出す。的（透明な外側）に出すと
   26px の札の周りに行いっぱいの枠が立つ。 */
.og-wave-card.og-card--lifted { outline: 0; }
.og-wave-card.og-card--lifted .og-wave-card__in { outline: 2px solid var(--ink); outline-offset: 2px; }
.og-wave-card__rail { width: 3px; align-self: stretch; flex: none; }
.og-wave-card__title {
  flex: 1; min-width: 0; font: 600 13px/1 var(--font-sans); letter-spacing: -.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* 期日超過（今日に集めた札）は色そのものを替える（形は変えない）。 */
.og-wave-card--overdue .og-wave-card__title { color: var(--overdue); }
/* 3 枚目からは数で。札の列の右端に浮くピル。 */
.og-wave-more {
  position: absolute; right: 0; top: 50%; transform: translateY(-50%);
  height: 18px; padding: 0 7px; border-radius: var(--r-knob);
  background: var(--bg-2); color: var(--ink-2); font: 700 9px/18px var(--font-mono); letter-spacing: .08em;
}
.og-wave-cards:has(.og-wave-more) .og-wave-card { margin-right: 34px; }

/* wide（≥700px。iPad）: 日付レール＋曲線を左 45%、札の列を右 55% に分け、同じ行に横並び。 */
html[data-og-width="wide"] .og-wave-cards {
  position: static; width: auto; flex: 0 0 55%; padding: 0 8px; box-sizing: border-box;
}
html[data-og-width="wide"] .og-wave-more { right: 8px; }

/* デスクトップ: 行 48px。曲線の列は **424px が基準（flex-basis）・
   --wave-curve-max が上限**で、帯の残りは札の列。424px 固定をやめた理由は
   トークンの側に書いた（負荷の目盛りであって読む幅ではない）。

   **424px は床ではない。** min-width を置いていないので、帯が狭い段では割る ──
   実際に取れる幅は `帯 − レール 56 − 札の下限 240`。1280 で右パネルを開くと
   帯 582px → 曲線 **286px** で、424px 固定だったころより目盛りが粗くなる
   （上限 capacity_h の線は幅の 71% に立つので 1 時間あたり 37.9 → 25.5px、−32%）。
   床を入れないのは、入れられないから ── 56 + 424 + 240 = 720px で、582px の帯には
   どうやっても収まらない。どちらを先に潰すかの選択で、**札の題（240px）を先に
   守っている**（424px 固定だったころ、この段の札は 102px まで潰れて題が読めなかった）。
   広い段（帯 1040px）では曲線が上限 640px に達するので、この譲りが効くのは
   880px の窓と 1280 + 右パネルだけ。
   .og-wave-row を挟むのは wide の属性セレクタ（同じ強さ）に後から勝つため。

   **帯そのものの上限は --measure-row（1040px）のまま置く。** 広げても得るものが
   札の列にしか行かないから ── 札の題は中央値 14 字・nowrap で、いまの 344px には
   とっくに全部入っている（1920 の実測で 64 行のうち札が載るのは 9 行）。
   1040 なら レール 56 + 曲線 640 + 札 344 で、曲線が上限まで伸びて札も足りる。

   **その代わり、1920 では帯の右に 620px が空いたまま残る**（盤面 1688 − 左余白 28
   − 帯 1040。左ナビをレールに畳むと 796px）。TASKS の MATRIX が 858 → 0 に
   なったのと違って、WAVE の「右端が余る」は**この段では直っていない**。
   埋め方は決まっていて、「その日に何があるか」の常設列（docs/18 の日のシート・
   400px）を第 3 列として置く PR ── ただしそれは views/wave.js に列を足す改修で、
   この段（CSS だけ）には入っていない。札の列を膨らませて埋める場所ではないので、
   **空きは空きのまま置いてある**（黙って据え置かないこと。docs/18 §2-11 にも
   同じことを書く）。 */
.og-frame--desktop { --wave-row: 48px; --wave-card: 22px; }
.og-frame--desktop .og-wave-band { max-width: var(--measure-row); }
.og-frame--desktop .og-wave-row .og-wave-curve { flex: 1 1 424px; max-width: var(--wave-curve-max); }
/* 札の列は残り全部。ただし下限を持たせる ── 880px の窓や 1280 + 右パネルでは
   帯が 582px まで縮み、曲線が先に取ると札の題が読めない幅（実測 102px）に落ちる。
   240px は「PJ 色の帯 3 + 間 8 + 題 ≒ 20 字 + 右余白 10」で題が読み切れる下限。 */
.og-frame--desktop .og-wave-row .og-wave-cards { flex: 1; min-width: 240px; }

/* ── 尺（2W / 8W / 26W）── 変えるのは行の高さだけ ───────────────────────
   日ごとの値は丸めない（週や月に集約すると 1 日の山が平らになり、依頼の核心
   「いつ忙しいか」が消える）。帯が自分に --wave-row を置き直すので、行の高さの
   読み口（views/wave.js の rowHeightOf）は 1 つのまま。
   8W / 26W の行は 12 / 3.5〜4px（26W は narrow だけ 3.5px）で 44px の的を取れないので、**行も印も押さない**
   （帯を押すとその日を真ん中にして 2W へ降りる。的の規則は agents/design.md §4）。 */
.og-wave-band--8w { --wave-row: var(--wave-row-8w); }
.og-wave-band--26w { --wave-row: var(--wave-row-26w); }
/* 札の列を作らない段なので、曲線が行の残り全部を使う（424px の基準も上限も外す）。
   セレクタの重さは .og-frame--desktop の規則と同じ 3 クラスで、後に置いて勝つ。 */
.og-wave-band--sm .og-wave-row .og-wave-curve { flex: 1 1 auto; max-width: none; }
/* 月名はレールの縦の真ん中。3.5〜4px の行では上端（top: 2px）に置くと 1 つ前の月に被る。 */
.og-wave-band--sm .og-wave-rail__month { top: 50%; transform: translateY(-50%); }

/* 小さい尺（8W / 26W）のレールの日付。**5 の倍数だけ**（30 は翌月の月名と重なるので出さない。
   wave.js の tickDay）。12px / 3.5px の行に 17px の数字は入らないので、月名と同じく
   行に**重ねて**置く ── 行の高さは 1px も変えない（曲線の形を歪めないため）。
   月名（--ink-3・9px）より一段退かせて、月の切れ目のほうが先に目に入るようにする。 */
.og-wave-band--sm .og-wave-rail__tick {
  position: absolute; top: 50%; transform: translateY(-50%); left: 0; width: 56px;
  text-align: center; font: 400 9px/1 var(--font-mono); letter-spacing: .06em;
  color: var(--ink-3); opacity: .72; pointer-events: none;
}
/* 月名が立つ行では日付は出ない（1 日は 5 の倍数ではない）ので、取り合いは起きない。
   今日の点（右 8px）とは横に離れているので、5 日・10 日が今日でも重ならない。 */
/* 今日。数字を出さない段なので --ink の小さな点で言う（暦の「今日」と同じ塗り）。
   帯を横切る線は引かない ── 罫線ゼロ、かつオレンジは全注意のときだけ（§3）。 */
.og-wave-rail__today {
  position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
  width: 6px; height: 6px; border-radius: 50%; background: var(--ink);
}
/* 小さい尺の節目。丸と、**縦に入るときだけ名**（2026-09-05。依頼主「2W と同じように、
   マイルストーンを表示」）。名は 9px の 1 行で、前に名を出した節目から 13px 以上
   離れている印にだけ付く（wave.js の MARK_LABEL_GAP）── 8W（12px/日）は実質すべて、
   26W（3.5〜4px/日）は 3〜4 日に 1 つ。丸は今までどおり全部出るので、間引かれても
   「在ること」は読める。押せないので的を持たない（表示専用。pointer-events も切る）。 */
.og-wave-dot {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 10px; height: 10px; border-radius: 50%; pointer-events: none;
}
/* 推定（inferred）は確実さの語彙 = 同色の不透明度 .45（2W の印と同じ）。 */
.og-wave-dot--inferred { opacity: .45; }
/* 名を伴う印。丸は絶対配置をやめて中に置き、器のほうが x を持つ。 */
.og-wave-dotwrap {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  display: flex; align-items: center; gap: 5px; white-space: nowrap; pointer-events: none;
}
.og-wave-dotwrap .og-wave-dot { position: static; transform: none; flex: none; }
/* 名は**沈めない**（丸だけが `--inferred` で .45 に落ちる）── 9px の字を .45 にすると
   地に溶けて読めない。等幅・字間は 2W の名（.og-wave-mark__label）と同じ語彙。 */
.og-wave-dot__label {
  font: 600 9px/1 var(--font-mono); letter-spacing: .06em; color: var(--ink-2);
}
/* 尺の分節（`2W · 8W · 26W`）は load.js の faceSwitch と同じ og-segmented。
   塗りは選択 = --ink / 台 = --bg-2 のまま（新しい色は足さない）。height 52 は
   **内側の駒を 44px にする**ため（og-segmented は外 − 8 が駒）── ここは見出しの
   操作部品なので、帯の中の 32px ではなく 44px を取る。
   **ここに寸法の規則は置かない。** `og-*` の器は `display: contents`（このファイルの
   頭）なので `.og-wave-scale` に flex や width を書いても届かない ── 効かせる先は
   og-segmented が作る**中の台**で、views/wave.js の scaleSwitch が props.style で渡す。
   class は「これが尺の分節」と分かるための印だけ。 */
/* narrow は見出しに入らないので凡例の行の左端へ（凡例はこの右で横に流れる）。 */
.og-wave-scalerow { display: flex; align-items: center; gap: 10px; padding: 0 20px 8px; min-width: 0; }
.og-wave-scalerow .og-wave-legend-host { flex: 1; min-width: 0; }
.og-wave-scalerow .og-wave-legend { padding: 0; }
/* **narrow は尺と絞り込みを 2 段に割る。** 1 行に並べると、分節（170px）の残りで
   凡例に **155px しか無い**（実測 375: ピル 8 枚で 522px ＝ 3 割しか見えない）。
   目当ての PJ を横に探ることになり、絞り込みとして使えない。2 段なら全幅 335px を
   使えて `ALL` ＋ 3〜4 枚が同時に見える。wide / desktop は幅があるので 1 行のまま。 */
html[data-og-width="narrow"] .og-wave-scalerow { flex-wrap: wrap; row-gap: 4px; }
/* 2 段目はピル（32px）ぶんだけ。44px の下限は**駒の的**の話で、行の背を 44px に
   しても的は 32px のまま ── 帯に返せる縦を 12px 削るだけになる（帯は WAVE の本体）。 */
html[data-og-width="narrow"] .og-wave-scalerow .og-wave-legend-host { flex: 1 0 100%; min-height: 32px; }

/* 日のシート。器（og-sheet の本文 20px / 右パネル）が余白を持つので、行の margin は 0。 */
.og-wave-day { display: flex; flex-direction: column; gap: 8px; }
.og-wave-day .og-agenda-row, .og-frame--desktop .og-wave-day .og-agenda-row { margin-left: 0; margin-right: 0; }
.og-wave-day .og-agenda-row + .og-agenda-row { margin-top: 0; }
.og-panel .og-wave-day { padding: 0 20px 24px; }

/* 予定の行の PJ のピル（押すと付け替え）。帯の中の操作部品なので 32px（§4）。
   塗りは .og-agenda-row__chip の inline（あり = accent-soft / なし = 塗らない字）のまま。 */
.og-wave-pjpill {
  height: 32px; padding: 0 10px; border: 0; border-radius: var(--r-knob);
  display: inline-flex; align-items: center; cursor: pointer; background: transparent;
}
/* PJ の一覧。行の中に沈んだトレイ（--bg-2）で開く。present には乗せない。 */
.og-wave-pjpick {
  display: flex; flex-direction: column; gap: 6px; margin-top: 4px; padding: 10px 12px;
  border-radius: var(--r-btn); background: var(--bg-2);
}
.og-wave-pjpick__chips { display: flex; flex-wrap: wrap; gap: 8px; }
/* トレイの中の駒は面（--surface）に。off を --bg-2 のままにするとトレイに溶ける。 */
.og-wave-pjpick og-chip button:not([aria-pressed="true"]) { background: var(--surface); }
.og-wave-pjpick og-toggle button { height: 44px; }
.og-wave-pjpick__say { min-height: 14px; font: 400 12px var(--font-sans); color: var(--ink-2); }

/* 節目のシートの欄。 */
.og-wave-msform { display: flex; flex-direction: column; gap: 20px; padding: 0 0 8px; }
.og-wave-msform__chips { display: flex; flex-wrap: wrap; gap: 8px; }
.og-panel .og-wave-msform { padding: 0 20px 24px; }

/* ── Undo の帯（og.js の showUndo）。TASKS の INBOX ✕ / DONE / クイック追加が使う ─────
   タブバー（44）の上、FAB（60）の左に出す。右を FAB ぶん空けるのは、6 秒のあいだ
   FAB が帯の下に潜ると「追加した」直後に次を足せないため。デスクトップは FAB が
   浮いていないので左下に短く出るだけ（max-width）。
   影なし・`--ink` の塗り・`--on-ink` の字・44px。戻す口は帯の中の 32px
   （帯の中の操作部品は 32px まで。agents/design.md §4）。塗りは地と反転させる
   ── オレンジにしない（全注意ではない）。 */
.og-undo {
  position: fixed; z-index: 32;
  left: 14px; right: calc(20px + var(--fab, 60px) + 10px + var(--safe-right, 0px));
  max-width: 480px;
  bottom: calc(var(--tabbar-bottom, 14px) + 44px + 16px + var(--player-h, 0px));
  height: 44px; box-sizing: border-box;
  display: flex; align-items: center; gap: 12px;
  padding: 0 6px 0 16px;
  border-radius: var(--r-knob);
  background: var(--ink); color: var(--on-ink);
  animation: og-rise var(--dur-swap) var(--ease-rise) both;
}
.og-undo__text {
  flex: 1; min-width: 0; font: 600 11px var(--font-mono); letter-spacing: .04em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.og-undo__action {
  flex: none; height: 32px; padding: 0 14px; border: 0; border-radius: var(--r-knob);
  background: var(--on-ink); color: var(--ink);
  font: 700 10px var(--font-mono); letter-spacing: .12em; cursor: pointer;
}

/* ── クイック追加（FAB の長押し。overlays.js の openQuickAdd）─────────────────
   入力欄 52px と「追加」を 1 行に。欄は .og-input（16px。iOS が寄せない下限）。 */
.og-quick { display: flex; gap: 8px; align-items: center; }
.og-quick .og-input { height: 52px; padding: 0 14px; flex: 1; }
.og-quick__add {
  flex: none; height: 52px; padding: 0 18px; border: 0; border-radius: var(--r-btn);
  background: var(--ink); color: var(--on-ink);
  font: 700 15px var(--font-sans); cursor: pointer;
}
.og-quick__add:disabled { opacity: .45; cursor: default; }
.og-quick__note { font: 400 11px/1.45 var(--font-mono); color: var(--ink-3); }

/* ── LIST の絞り「TODAY ✓」（tasks.js の todayRowEl）──────────────────────────
   夜の消し込み用。行の左に 44px の ✓ を置き、押すと即 DONE（Undo 付き）。
   行そのものは og-task-row と同じ背（--row-h-task）・同じ札の語彙（--surface, --r-card）。
   ✓ は沈んだ升（--bg-2）で、押す前からオレンジにも黒にもしない ── 連打する面で
   全部が黒いと、どれを押したかが読めない。 */
.og-today-row {
  display: flex; align-items: center; gap: 12px;
  height: var(--row-h-task); padding: 0 12px 0 8px;
  border-radius: var(--r-card); background: var(--surface); color: var(--ink);
}
.og-today-row__check {
  width: 44px; height: 44px; flex: none; padding: 0; border: 0; border-radius: var(--r-btn);
  background: var(--bg-2); color: var(--ink);
  font: 700 18px var(--font-sans); display: flex; align-items: center; justify-content: center;
  cursor: pointer; transition: background var(--dur-tap) var(--ease-linear);
}
.og-today-row__check:disabled { opacity: .45; cursor: default; }
.og-today-row__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; cursor: pointer; }
.og-today-row__title { font: 600 15px var(--font-sans); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.og-today-row__meta { font: 400 11px var(--font-mono); color: var(--ink-3); display: flex; gap: 5px; min-width: 0; }
.og-today-row__meta--overdue { color: var(--overdue); font-weight: 700; }

/* ══════════════════════════════════════════════════════════════════════
   デスクトップの仕上げ（担当 D。docs/04_UI_SPEC.md §3-2）
   すべて .og-frame--desktop の中か、デスクトップの面（.og-dt-*）でしか
   使わない札。モバイルの枠には1つも当たらない。
   ══════════════════════════════════════════════════════════════════════ */

/* ── 一覧の行の2つの印（og.js の listNav が付け外しする）────────────────
   「開いている」はインクの輪郭、「キーで指している」はオレンジの輪郭。
   WAVE の選択行（.og-wave-row--selected）と同じ語彙 ── 罫線ではなく輪郭
   （agents/design.md §2-1 の「線が要る3つ」の1つ）。内側（-2px）に置くのは
   行の角丸に沿わせるため。両方付いたときは指しているほう（橙）が勝つ。 */
.og-dt-row--open { outline: 2px solid var(--ink); outline-offset: -2px; }
.og-dt-row--keyed { outline: 2px solid var(--accent); outline-offset: -2px; }

/* ── ホバー：一覧の行は --bg-2（og-setting-row / サイドバーと同じ）、
   札（og-task-card）は 1px の輪郭。**JS では張らない** ── .og-frame--desktop は
   マウスの機でしか組まれない（app.js の MEDIA）ので、CSS の :hover で足りる。
   指の画面には当たらない（design.md §0 の「1回押したら効く」）。 */
.og-frame--desktop .og-rec-row:hover,
.og-frame--desktop .og-doc-row:hover,
.og-frame--desktop .og-mail-row:hover { background: var(--bg-2); }
.og-frame--desktop og-task-card > div:hover { outline: 1px solid var(--neutral-mid); outline-offset: -1px; }

/* ── DOC：行にホバーで「開く ↗」。要素は doc.js が CAN_HOVER のときだけ置く。 */
.og-doc-row__open {
  flex: none; font: 600 10px var(--font-mono); letter-spacing: .1em; color: var(--ink-2);
  opacity: 0; transition: opacity var(--dur-tap) var(--ease-linear);
}
.og-doc-row:hover .og-doc-row__open,
.og-doc-row.og-dt-row--keyed .og-doc-row__open { opacity: 1; }

/* ── MAIL：一覧の行と手番（ball）の印。行の寸法は mail.js のインライン
   （モバイルと共有）が持つ。ここは印だけ ── 10px の正方形（サイドバーの印と
   同じ形）。こちら＝インク、相手＝--neutral-mid、未設定＝置くが塗らない
   （行の頭を揃えるため）。 */
.og-mail-row__ball { width: 10px; height: 10px; flex: none; margin-top: 4px; background: transparent; }
.og-mail-row__ball--us { background: var(--ink); }
.og-mail-row__ball--them { background: var(--neutral-mid); }

/* ── LOAD 実績（デスクトップ）：巨大数値と棒は左、PJ 行は右の2列。
   幅は .og-dt-measure（1040px）が止める。列は**入る幅があるときだけ 2 つ**:
   1024px でパネルが開くと盤面は 392px（1024 − 232 − 400）で、ここを 2 つに
   割ると 153px ── 棒の札も PJ 行も縦に折れて読めなかった。1 列の下限は 340px
   （モバイルの 390 − 余白と同じ算数）、45% は 1040px で 3 列にならないための蓋。 */
.og-dt-load { display: grid; grid-template-columns: repeat(auto-fit, minmax(max(340px, 45%), 1fr)); gap: 20px; align-items: start; }
.og-dt-load__col { min-width: 0; display: flex; flex-direction: column; gap: 10px; }

/* ── サイドバーの足：キーの一覧（`?` で開く）。コマンドパレットではない ──
   入力欄を持たず、読むだけの小さな表。 */
.og-sidebar__tail { margin-top: auto; display: flex; flex-direction: column; }
.og-sidebar__keys-toggle {
  display: flex; align-items: center; gap: 10px; height: 44px; padding: 0 18px;
  border: 0; background: none; width: 100%; text-align: left; cursor: pointer;
  transition: background var(--dur-tap) var(--ease-linear);
}
.og-sidebar__keys-toggle:hover, .og-sidebar__keys-toggle--open { background: var(--bg-2); }
/* display:grid は UA の [hidden] を負かすので、畳んだときの none を自分で書く。 */
.og-sidebar__keys[hidden] { display: none; }
.og-sidebar__keys {
  padding: 8px 18px 12px; background: var(--bg-2);
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 6px 12px; align-items: center;
}
.og-sidebar__key {
  display: inline-flex; align-items: center; justify-self: start;
  height: 22px; padding: 0 7px; border-radius: var(--r-knob);
  background: var(--surface); color: var(--ink);
  font: 700 10px var(--font-mono); letter-spacing: .06em; white-space: nowrap;
}
.og-sidebar__key-what { font: 400 11px/1.3 var(--font-sans); color: var(--ink-2); }
