/* ============================================================
   kabu_alert dashboard — style v3
   v2 (508行) の上書き。狙いは「機能の修正」ではなく質感の底上げ。
   テンプレートは 1 行も変えない前提。

   前提 (外せない制約):
   - JavaScript なし / 外部アセットなし (CDN・Webフォント不可)
   - CSP は default-src 'self'; img-src 'self' data:; style-src 'self'
     → @font-face も @import も外部からは引けない。font-family はシステムフォントのみ
     → このファイルは url() を 1 つも使わない (data: URI も使わない)
   - ライト / ダーク 両対応 (prefers-color-scheme + data-theme)
   - スマホ幅前提。横スクロールを絶対に出さない。左右 16px ガター
   - 入力欄の font-size は 16px 以上 (iOS のフォーカス時ズーム防止)

   v3 の方針 (詳細は data/proposals/dashboard_design_review_v2.md):
   1. 余白とタイポに「尺度」を持たせる (--sp-*, --step-*)。値を思いつきで書かない
   2. 面は 3 段 (bg / surface / surface-2)。奥行きは影ではなく
      ライト=極小の影 / ダーク=上面のわずかな明るみ で出す
   3. 数字が主役。画面の答えになる数字だけ 26px まで上げ、他は下げる
   4. 状態 (到達・要判断) はベタ塗りの帯ではなくピルで示す
   5. グラフの軸ラベルは viewBox 単位。実寸 5px しかなかったのを直す
   ============================================================ */

/* ── 1. デザイントークン ───────────────────────────────────
   色は「役割」で持つ。--surface に対して何が乗るかが決まっていれば、
   ダークは値を差し替えるだけで済む。 */
:root {
  color-scheme: light;

  /* 面: 3 段。ページ地 → カード → カード内の沈み */
  --bg:          #eef1f6;
  --surface:     #ffffff;
  --surface-2:   #e9edf3;   /* 目盛り・沈んだ塗り・コード背景 */

  /* 文字 */
  --fg:          #12161d;
  --fg-2:        #3c4350;   /* 見出し以外の通常文字を少し落とす用 */
  --muted:       #58606e;   /* 補足テキスト。--surface 上で 6.1:1 */

  /* 罫線: soft は「あるのが分かる程度」、line は通常、strong は境界 */
  --line-soft:   #edf0f5;
  --line:        #dfe4ec;
  --line-strong: #c3cbd8;   /* 装飾用 (表の見出し罫など) */
  /* 操作できる部品の輪郭は WCAG 1.4.11 の 3:1 を満たす必要がある。
     装飾の罫線と同じ色にすると入力欄の枠が 1.6:1 しかなくなるので分ける。
     ページ地 3.10:1 / カード面 3.51:1 */
  --field-line:  #838997;

  --accent:      #1a46c8;
  --accent-2:    #2f5fe0;   /* ボタンのごく浅いグラデ上端 */
  --accent-soft: #e6ecfc;   /* 選択範囲・フォーカスの暈し */
  --accent-line: #b9c9f5;

  /* 日本の慣行: 上げ=赤 / 下げ=緑。
     色だけに頼らないよう (1) テンプレート側が騰落値を必ず符号付き
     ("{:+,.0f}" / "%+.2f") で出している (2) 赤と緑の輝度を約 1.6 倍ぶん
     離してあるので、赤緑の判別が難しい場合でも濃淡の差として読める。 */
  --up:          #c2261f;
  --down:        #0a5138;

  /* 注意書きの 3 段階 */
  --warn:        #8a5300;   /* 注意 (琥珀) */
  --warn-bg:     #fdf4e3;
  --warn-line:   #f0dcb4;
  --danger:      #b3261e;   /* 要判断・エラー (赤) */
  --danger-bg:   #fdecea;
  --danger-line: #f3c9c5;

  /* 奥行き。ライトだけ影を使い、ダークでは無効化する */
  --shadow-1: 0 1px 1px rgba(16, 24, 40, .04), 0 2px 6px -3px rgba(16, 24, 40, .10);
  --shadow-2: 0 1px 2px rgba(16, 24, 40, .06), 0 8px 20px -10px rgba(16, 24, 40, .18);
  --sheen: none;            /* ダークで上面のハイライトに使う */
  --btn-sheen: linear-gradient(180deg, rgba(255,255,255,.10), rgba(255,255,255,0));

  /* 間隔の尺度 (4px 基準)。ここ以外で生の px を書かないための土台 */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;

  --radius:     14px;
  --radius-sm:  10px;
  --radius-xs:  6px;
  --pill:       999px;
  --gutter:     16px;
  --measure:    640px;      /* 広い画面での読み幅の上限 */
}

/* ダークは自動反転ではなく専用の値を置く。
   `data-theme` 属性は現状テンプレートが付けないが、将来の手動切替
   (Cookie + サーバ側出力) に備えて同じ値を 2 箇所に書いてある。
   **この 2 ブロックは常に同じ値に保つこと。** */
@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) {
    color-scheme: dark;

    --bg:          #0b0e13;
    --surface:     #161b23;
    --surface-2:   #202733;

    --fg:          #e8ebf1;
    --fg-2:        #c3cad6;
    --muted:       #9ba5b4;

    --line-soft:   #1e242e;
    --line:        #2a313d;
    --line-strong: #3b4451;
    --field-line:  #616977;   /* ページ地 3.49:1 / カード面 3.12:1 */

    --accent:      #86b0f8;
    --accent-2:    #86b0f8;
    --accent-soft: #18263d;
    --accent-line: #2d4566;

    --up:          #ff9a93;
    --down:        #2fa574;

    --warn:        #f0b429;
    --warn-bg:     #2a2213;
    --warn-line:   #4a3c1c;
    --danger:      #ff8a82;
    --danger-bg:   #2d1715;
    --danger-line: #5a2b27;

    /* 暗い面では影が見えないので、代わりに上端をわずかに明るくして
       「光が上から当たっている」状態を作る。強いグラデは使わない。 */
    --shadow-1: none;
    --shadow-2: 0 10px 24px -12px rgba(0, 0, 0, .8);
    --sheen: linear-gradient(180deg, rgba(255,255,255,.035), rgba(255,255,255,0) 96px);
    --btn-sheen: linear-gradient(180deg, rgba(255,255,255,.08), rgba(255,255,255,0));
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0b0e13; --surface: #161b23; --surface-2: #202733;
  --fg: #e8ebf1; --fg-2: #c3cad6; --muted: #9ba5b4;
  --line-soft: #1e242e; --line: #2a313d; --line-strong: #3b4451;
  --field-line: #616977;
  --accent: #86b0f8; --accent-2: #86b0f8; --accent-soft: #18263d; --accent-line: #2d4566;
  --up: #ff9a93; --down: #2fa574;
  --warn: #f0b429; --warn-bg: #2a2213; --warn-line: #4a3c1c;
  --danger: #ff8a82; --danger-bg: #2d1715; --danger-line: #5a2b27;
  --shadow-1: none;
  --shadow-2: 0 10px 24px -12px rgba(0, 0, 0, .8);
  --sheen: linear-gradient(180deg, rgba(255,255,255,.035), rgba(255,255,255,0) 96px);
  --btn-sheen: linear-gradient(180deg, rgba(255,255,255,.08), rgba(255,255,255,0));
}

/* ── 2. ベース ─────────────────────────────────────────── */
* { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  /* 左右は safe-area を足す (横向きのノッチ対策)。下は指の届く余白 */
  padding:
    0
    max(var(--gutter), env(safe-area-inset-right))
    calc(72px + env(safe-area-inset-bottom))
    max(var(--gutter), env(safe-area-inset-left));
  background: var(--bg);
  color: var(--fg);
  font-family: system-ui, -apple-system, BlinkMacSystemFont, "Hiragino Sans",
               "Hiragino Kaku Gothic ProN", "Noto Sans JP", "Yu Gothic UI",
               Meiryo, sans-serif;
  font-size: 16px;
  line-height: 1.75;
  letter-spacing: .012em;        /* 和文は僅かに開けたほうが読みやすい */
  overflow-x: hidden;            /* 横スクロールは出さない */
  overflow-wrap: break-word;     /* 長い語での突き抜けを防ぐ (数字は割らない) */
  line-break: strict;            /* 禁則処理を厳密に */
}

/* 見えるフォーカス。リングの外側にさらに淡い暈しを重ねて、
   どの面の上でも輪郭が消えないようにする */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}
::selection { background: var(--accent-soft); color: var(--fg); }

/* iOS 既定のタップ時グレー被せを外し、代わりに自前の :active を置く。
   外すだけだと「押した感」が無くなるので、必ず対で指定する。 */
a, button, label { -webkit-tap-highlight-color: transparent; }

/* 動きは「触れたものが反応する」ぶんだけ。減速指定があれば全部止める */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── 3. ヘッダーとナビ ─────────────────────────────────── */
header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-3) 0 10px;
}
header .brand {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-weight: 700;
  font-size: 1.0625rem;
  letter-spacing: .005em;
  font-feature-settings: "palt" 1;
  text-decoration: none;
  color: var(--fg);
}
/* ブランドマーク。文字ではなく塗りなので読み上げには乗らない */
header .brand::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 3px;
  background: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

/* ログイン系はナビが出ないので、ヘッダ側に区切りを戻す */
body:not(:has(nav)) header {
  border-bottom: 1px solid var(--line);
  margin-bottom: var(--sp-2);
}
/* ログイン / 招待 / 初回セットアップ。ナビが無い = 未ログインの画面では
   フォームがページ地に直置きで、入口としての体裁が無かった。
   カードに載せる (この 3 画面にはフォームが 1 つしかないので誤爆しない)。 */
body:not(:has(nav)) form {
  background-color: var(--surface);
  background-image: var(--sheen);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-1);
  padding: var(--sp-2) var(--sp-4) var(--sp-5);
  margin: var(--sp-4) 0;
}
body:not(:has(nav)) form > label:first-of-type { margin-top: var(--sp-3); }

/* ナビは上端に貼り付ける。保有が増えると縦に長くなり、
   固定しないと画面切替のたびに最上部まで戻る必要がある。
   全幅に敷くため左右のガターぶんだけ負マージンで逃がす。 */
nav {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  gap: 2px;
  flex-wrap: wrap;
  margin: 0 calc(var(--gutter) * -1) var(--sp-4);
  padding: var(--sp-1) var(--gutter) 6px;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}
/* 対応ブラウザでは半透明 + 背景ぼかしにする。
   下の内容がうっすら透けることで「上に乗っている」ことが伝わる。 */
@supports ((backdrop-filter: blur(8px)) or (-webkit-backdrop-filter: blur(8px))) {
  nav {
    background: color-mix(in srgb, var(--bg) 78%, transparent);
    -webkit-backdrop-filter: blur(14px) saturate(1.6);
    backdrop-filter: blur(14px) saturate(1.6);
  }
}
nav a {
  display: inline-flex;
  align-items: center;
  min-height: 40px;              /* 指で押せる高さ */
  padding: var(--sp-1) 9px;      /* 5 項目が 375px 幅で 1 行に収まる上限 */
  border-radius: var(--pill);
  color: var(--fg-2);            /* 既定は本文寄り。現在地だけを立てる */
  font-size: .875rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: .01em;
  font-feature-settings: "palt" 1;
  white-space: nowrap;
  text-decoration: none;
  transition: background-color .16s ease, color .16s ease;
}
nav a[aria-current="page"] {
  background: var(--accent);
  color: var(--surface);
  font-weight: 700;
  text-decoration: none;         /* 下線ではなく塗りで現在地を示す */
}
nav a:active { background: var(--surface-2); }
nav a[aria-current="page"]:active { background: var(--accent); }
@media (hover: hover) {
  nav a:hover { background: var(--surface-2); }
  nav a[aria-current="page"]:hover { background: var(--accent); }
}

/* ── 4. タイポグラフィ ─────────────────────────────────── */
h1 {
  font-size: 1.5rem;
  line-height: 1.35;
  font-weight: 700;
  letter-spacing: -.012em;
  font-feature-settings: "palt" 1;
  margin: var(--sp-1) 0 var(--sp-3);
  text-wrap: balance;            /* 未対応ブラウザでは無視される */
}
h2 {
  font-size: 1.1875rem;
  line-height: 1.45;
  font-weight: 700;
  letter-spacing: -.008em;
  font-feature-settings: "palt" 1;
  margin: var(--sp-6) 0 var(--sp-3);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--line);   /* 長い1カラムを区切る */
  text-wrap: balance;
}
h1 + h2, h2:first-child {
  border-top: 0;
  padding-top: 0;
  margin-top: var(--sp-4);
}
h3 {
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -.005em;
  margin: var(--sp-5) 0 var(--sp-2);
}

p { margin: var(--sp-3) 0; }

a {
  color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
/* 既定の #0000EE / 訪問済み #551A8B を残すとダークで読めない。必ず上書きする */
a:visited { color: var(--accent); }

code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .875em;
  padding: 1px 5px;
  border-radius: var(--radius-xs);
  background: var(--surface-2);
  overflow-wrap: anywhere;       /* パス名で突き抜けない */
}

.muted {
  color: var(--muted);
  font-size: .875rem;
  line-height: 1.7;
}
.muted strong { color: var(--fg-2); font-weight: 600; }

/* ── 5. カード ─────────────────────────────────────────── */
.card {
  position: relative;            /* ::before の帯を置くため */
  background-color: var(--surface);
  background-image: var(--sheen);   /* ダークだけ上端がわずかに明るむ */
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-1);
  padding: var(--sp-3) var(--sp-4);
  margin-bottom: var(--sp-3);
}
/* カード見出し (銘柄名・セクション名) */
.card > strong:first-child,
.card > .row:first-child > strong:not(.num) {
  font-size: 1.0625rem;
  line-height: 1.45;
  letter-spacing: -.008em;
  font-feature-settings: "palt" 1;
}
.card > p:first-child { margin-top: 0; }
.card > p:last-child  { margin-bottom: 0; }
/* 説明用の .card.muted は「読ませる箱」なので、沈めて本文扱いにする */
.card.muted {
  font-size: .9375rem;
  background-color: var(--surface-2);
  background-image: none;
  border-color: transparent;
  box-shadow: none;
}
.card.muted p  { margin: 10px 0; }
.card.muted ul { padding-left: 1.2em; }

/* ── 6. 行 (ラベル + 値) ─────────────────────────────────
   カードの中で .row が続くときは薄い罫を入れて、明細表のように読ませる。
   区切りが入ることで「ラベルと値の対」が視覚的に閉じる。 */
.row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--sp-1) var(--sp-3);
  flex-wrap: wrap;               /* 長い銘柄名でも横に溢れさせない */
  padding: 5px 0;
  line-height: 1.5;
}
.row > * { min-width: 0; }
.card > .row + .row { border-top: 1px solid var(--line-soft); }
/* 折り返した時も値は右端に残す (:not(:first-child) は「1 要素だけの .row」を守る) */
.row > *:last-child:not(:first-child) { margin-left: auto; text-align: right; }
/* ラベル側を一段落とす。class 付きの span (num / muted / up / down) には当てない
   — .up / .down より詳細度が高くなり、騰落の色を潰してしまうため。 */
.row > span:first-child:not([class]) { color: var(--muted); }

/* 主要な数字だけを大きくする。テンプレート上 <strong class="num"> が
   付いているのは評価額・含み損益・実現損益・勝率など「その画面の答え」だけ。 */
.card > .row > strong.num {
  font-size: 1.3125rem;
  font-weight: 700;
  line-height: 1.35;
  letter-spacing: -.02em;
}
/* h1 直後のカード = その画面のサマリ。先頭行の値は「最初に読む数字」なので
   さらに一段上げる。保有/履歴/入出金の 3 画面で評価額・投下元本に当たる。 */
h1 + .card > .row:first-child > strong.num {
  font-size: 1.625rem;
  line-height: 1.3;
}
/* 保有画面サマリの「要判断 N銘柄」。
   この画面で唯一 .num が付かない strong で、かつフォームを持つカードは
   ここだけなので拾えている。専用クラスが付けば不要になる (提案書参照)。 */
.card:has(> form) > .row > strong:not(.num) {
  font-size: 1.3125rem;
  font-weight: 700;
  line-height: 1.35;
  color: var(--danger);
}

/* ── 7. 数字と符号 ─────────────────────────────────────── */
.num {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  letter-spacing: 0;
}
/* 上げ=赤 / 下げ=緑。テンプレート側が全ての騰落値を符号付きで出しているので、
   色を落としても符号と濃淡で方向が読める。 */
.up   { color: var(--up);   font-weight: 600; }
.down { color: var(--down); font-weight: 600; }

/* ── 8. 注意書き (3 段階) ──────────────────────────────
   既定は「左罫 + 薄い地」。本当に判断が要るものだけ強く出す。 */
.notice {
  background: var(--warn-bg);
  border: 1px solid var(--warn-line);
  border-left: 3px solid var(--warn);
  border-radius: var(--radius-xs) var(--radius-sm) var(--radius-sm) var(--radius-xs);
  color: var(--fg);
  padding: 10px var(--sp-3);
  margin: var(--sp-4) 0;
  font-size: .9375rem;
  line-height: 1.7;
}
.notice p:first-child { margin-top: 0; }
.notice p:last-child  { margin-bottom: 0; }
.notice a { color: var(--accent); }
/* カードの中に入る注意書きは一段静かに */
.card > .notice { font-size: .875rem; padding: var(--sp-2) var(--sp-3); }

.error {
  background: var(--danger-bg);
  border: 1px solid var(--danger-line);
  border-left: 3px solid var(--danger);
  border-radius: var(--radius-xs) var(--radius-sm) var(--radius-sm) var(--radius-xs);
  color: var(--fg);
  padding: var(--sp-3) var(--sp-4);
  margin: var(--sp-4) 0;
  font-weight: 600;
}

/* ── 9. 保有画面: 判断が要る銘柄 ───────────────────────
   positions.html のカード構造:
     .card > .row(銘柄名) > [.notice(exit_status)] > .row… > table > [.notice(売りSig)]
   先頭行の直後にある .notice は exit_status が holding でない時だけ出る。
   サマリカードは .notice が先頭行の隣に来ないので当たらない。
   = サマリの「要判断 N銘柄」と件数が一致する。 */
.card:has(> .row:first-child + .notice) {
  border-color: var(--danger-line);
  /* 左端の帯は inset shadow で引く。疑似要素だと角丸に追従せず
     カードの丸みから 3px だけはみ出して見えるため。 */
  box-shadow: inset 3px 0 0 var(--danger), var(--shadow-2);
}
/* 利確到達 / 損切到達 / 期限超過 のバッジ。
   帯ではなくピルにして「札が貼ってある」見せ方にする */
.card > .row:first-child + .notice {
  display: inline-block;
  background: var(--danger-bg);
  border: 1px solid var(--danger-line);
  border-radius: var(--pill);
  color: var(--danger);
  font-weight: 700;
  font-size: .8125rem;
  letter-spacing: .02em;
  line-height: 1.4;
  padding: 5px 12px;
}
/* 売りシグナル警告 (表の後ろに来る .notice) は一段下の「注意」 */
.card > table + .notice {
  background: var(--warn-bg);
  border: 1px solid var(--warn-line);
  border-left: 3px solid var(--warn);
  color: var(--fg);
}

/* ── 10. 表 ───────────────────────────────────────────── */
table {
  width: 100%;
  border-collapse: collapse;
  font-size: .9375rem;
  margin: var(--sp-1) 0;
}
th, td {
  text-align: left;
  padding: var(--sp-2) 6px;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: top;
}
th {
  font-size: .75rem;
  font-weight: 700;
  color: var(--muted);
  letter-spacing: .06em;         /* 小さい見出しは字間を開けて別物に見せる */
  line-height: 1.5;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--line-strong);
}
th:first-child, td:first-child { padding-left: 0; }
th:last-child,  td:last-child  { padding-right: 0; }
tr:last-child td { border-bottom: 0; }   /* カード枠との二重線をなくす */

td.num, th.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}
/* 数字セルは語中で割らない。keep-all は和文の任意改行も止めるので
   「3,095.9 / 円」のように数値と単位が泣き別れるのを防げる
   (幅が足りない時は、折り返せる 1 列目が縮んで吸収する) */
td.num, th.num { overflow-wrap: normal; word-break: keep-all; }
td strong { font-weight: 700; }

@media (hover: hover) {
  table tr:not(:first-child):hover td { background: var(--surface-2); }
}

/* positions の「いくらで売る」見出し行 (空の td を 2 つ持つ行) を
   罫線付きのデータ行ではなく小見出しとして見せる */
table tr:first-child:has(td:empty) td {
  border-bottom: 0;
  padding-bottom: 2px;
}
table tr:first-child:has(td:empty) strong {
  font-size: .75rem;
  font-weight: 700;
  color: var(--muted);
  letter-spacing: .06em;
}

/* ── 11. フォーム ─────────────────────────────────────── */
form { margin: 0; }

label {
  display: block;
  margin: var(--sp-4) 0 6px;
  font-size: .875rem;
  font-weight: 700;
  letter-spacing: .01em;
  color: var(--fg);
}
label + .muted, input + .muted, select + .muted { margin-top: 6px; }

input, select, textarea {
  width: 100%;
  padding: 11px var(--sp-3);
  font-size: 16px;               /* iOS のズーム防止。16px を下回らせない */
  font-family: inherit;
  line-height: 1.5;
  border-radius: var(--radius-sm);
  border: 1px solid var(--field-line);
  background: var(--surface);
  color: var(--fg);
  caret-color: var(--accent);
  transition: border-color .16s ease, box-shadow .16s ease;
}
/* select は appearance を潰さずネイティブの矢印を残す。
   iOS はホイールピッカーを出すので、自前の矢印に置き換える利点がない。 */
select { padding-right: var(--sp-2); }
input:focus, select:focus, textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
input[type="checkbox"] {
  width: auto;
  min-width: 22px;
  min-height: 22px;
  accent-color: var(--accent);
  box-shadow: none;
}
input::placeholder { color: var(--muted); opacity: 1; }
input[type="date"] { min-height: 46px; }   /* iOS で高さが潰れるのを防ぐ */

/* 触れない入力欄は沈めて明示する (記録の訂正画面で、決済済みの買い約定は
   株数・単価・約定日が disabled になる)。-webkit-text-fill-color は
   iOS が独自に文字を薄くするのを打ち消すため。 */
input:disabled, select:disabled, textarea:disabled {
  background: var(--surface-2);
  border-color: var(--line);
  color: var(--muted);
  -webkit-text-fill-color: var(--muted);
  opacity: 1;
  cursor: not-allowed;
}

button {
  width: 100%;
  min-height: 48px;
  padding: var(--sp-3) var(--sp-4);
  margin-top: var(--sp-5);
  font-size: 1rem;
  font-family: inherit;
  font-weight: 700;
  letter-spacing: .02em;
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  background-color: var(--accent);
  background-image: var(--btn-sheen);
  color: var(--surface);
  cursor: pointer;
  transition: transform .1s ease, box-shadow .16s ease, background-color .16s ease;
}
button:active { transform: translateY(1px); }
button.secondary {
  background-color: var(--surface);
  background-image: none;
  color: var(--accent);
  border-color: var(--field-line);
}
@media (hover: hover) {
  button.secondary:hover { background-color: var(--surface-2); }
}
/* 行内のログアウト。主導線ではないので静かにする (inline style で幅と余白は固定) */
header button.secondary {
  min-height: 0;
  margin: 0;
  font-size: .8125rem;
  font-weight: 600;
  color: var(--muted);
  border-color: var(--field-line);
  border-radius: var(--pill);
}
/* カードの中のサブ操作 (現在値を更新) は本文より小さく */
.card > form > button.secondary {
  min-height: 44px;
  margin-top: var(--sp-3);
  font-size: .9375rem;
}
/* 行の中に置かれた小さな操作 (記録の一覧の「削除」) は行の高さに合わせる。
   48px のままだと隣の文字リンクと釣り合わない。 */
.row button {
  min-height: 36px;
  margin-top: 0;
  font-size: .8125rem;
  border-radius: var(--pill);
}
/* 取り消しは色でも区別する。action で拾えるので構造は触らない。 */
form[action$="/delete"] button {
  color: var(--danger);
  border-color: var(--danger-line);
}

/* ── 12. 行動リンクをボタンに見せる ───────────────────────
   「約定を記録する」は各カードの出口だが、素のリンクでは
   タップ領域が文字高ぶんしかない。href で拾えるので構造は触らない。 */
a[href^="/executions/new"] {
  display: block;
  min-height: 46px;
  margin-top: var(--sp-1);
  padding: 11px var(--sp-4);
  border: 1px solid var(--field-line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--accent);
  font-size: .9375rem;
  font-weight: 700;
  letter-spacing: .01em;
  text-align: center;
  text-decoration: none;
  transition: background-color .16s ease, border-color .16s ease;
}
a[href^="/executions/new"]:active { background-color: var(--surface-2); }
@media (hover: hover) {
  a[href^="/executions/new"]:hover {
    background: var(--surface-2);
    border-color: var(--field-line);
  }
}
a[href="/executions/new?side=buy"] {          /* 唯一の主導線は塗る */
  background-color: var(--accent);
  background-image: var(--btn-sheen);
  border-color: var(--accent);
  color: var(--surface);
  min-height: 48px;
  font-size: 1rem;
  box-shadow: var(--shadow-1);
}
a[href="/executions/new?side=buy"]:active { background-color: var(--accent-2); }
@media (hover: hover) {
  a[href="/executions/new?side=buy"]:hover { background-color: var(--accent-2); }
}

/* ── 13. グラフ ───────────────────────────────────────
   色は dataviz の検証で両モードとも合格を確認した v2 の値を引き継ぐ。
   v3 で直したのは寸法。SVG は viewBox 640x220 を幅 320px 前後で描くので
   縮尺が約 0.5 倍になり、font-size:11px の軸ラベルは実寸 5px しかなかった。
   CSS の値は viewBox 単位なので、実寸から逆算して指定し直す。 */
.viz-root {
  --viz-surface: var(--surface);
  --viz-series-1: #2a78d6;   /* 評価額 */
  --viz-ref: var(--muted);   /* 投下元本 (参照線) */
  --viz-grid: var(--line);
}
@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) .viz-root {
    --viz-series-1: #3987e5;
    --viz-grid: var(--line);
  }
}
:root[data-theme="dark"] .viz-root { --viz-series-1: #3987e5; }

.viz-root svg {
  width: 100%;
  height: auto;
  display: block;
  border-radius: var(--radius-xs);
  /* 目盛り線。テンプレートに線の要素が無いので背景で引く。
     viewBox の作図領域は上 16 / 下 28 なので、
     高さ 80% の帯を 36.36% の位置に置くと作図領域にちょうど重なる。
     等間隔 = 等価格幅なので、ラベルが無くても嘘にはならない。 */
  background-image:
    repeating-linear-gradient(to bottom, var(--viz-grid) 0 1px, transparent 1px 25%);
  background-size: 100% 80%;
  background-position: 0 36.36%;
  background-repeat: no-repeat;
}
.viz-series {
  fill: none;
  stroke: var(--viz-series-1);
  stroke-width: 2.25;
  stroke-linejoin: round;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;   /* 縮尺に関係なく実寸 2.25px */
}
.viz-ref {
  fill: none;
  stroke: var(--viz-ref);
  stroke-width: 1.25;
  stroke-dasharray: 5 5;
  vector-effect: non-scaling-stroke;
}
/* 最新値の点。面と同色の縁を回して線の上に浮かせる */
.viz-dot {
  fill: var(--viz-series-1);
  stroke: var(--viz-surface);
  stroke-width: 3;
  paint-order: stroke;
  vector-effect: non-scaling-stroke;
  r: 7px;                    /* CSS 幾何プロパティ。未対応なら属性の r=4 のまま */
}
/* ホバーの当たり判定はマークより大きく取る (JS なしで title を出すため)。
   対応環境では触れた列がうっすら光る */
.viz-hit { fill: var(--viz-series-1); fill-opacity: 0; }
@media (hover: hover) {
  .viz-hit { transition: fill-opacity .12s ease; }
  .viz-hit:hover { fill-opacity: .1; }
}
.viz-axis {
  font-size: 21px;           /* viewBox 単位。実寸では約 10.5px になる */
  font-weight: 600;
  fill: var(--muted);
  font-variant-numeric: tabular-nums;
  letter-spacing: .3px;
}
.viz-legend {
  display: flex;
  gap: var(--sp-2);
  flex-wrap: wrap;
  margin-top: var(--sp-3);
  font-size: .8125rem;
  color: var(--muted);
}
/* 凡例は「文字の列」ではなくチップにして、数値と対で読ませる */
.viz-legend > span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border: 1px solid var(--line);
  border-radius: var(--pill);
  background: var(--surface-2);
  font-variant-numeric: tabular-nums;
  line-height: 1.6;
}
.viz-key {
  display: inline-block;
  width: 14px;
  height: 0;
  vertical-align: middle;
  border-top: 2.5px solid var(--viz-series-1);
  border-radius: 2px;
}
.viz-key.ref { border-top: 1.5px dashed var(--viz-ref); }

/* ── 14. 画面が広い時 ─────────────────────────────────
   スマホが主だが、PC で開くと 1 行が長くなりすぎて読めなくなるので
   読み幅を止める。レイアウトは 1 カラムのまま変えない。 */
@media (min-width: 560px) {
  body {
    padding-left:  max(var(--gutter), calc((100vw - var(--measure)) / 2));
    padding-right: max(var(--gutter), calc((100vw - var(--measure)) / 2));
  }
  nav { margin-left: 0; margin-right: 0; padding-left: 0; padding-right: 0; }
  .card { padding: var(--sp-4) var(--sp-5); }
  h1 { font-size: 1.75rem; }
  h1 + .card > .row:first-child > strong.num { font-size: 1.75rem; }
}

/* ── 15. 印刷 ─────────────────────────────────────────── */
@media print {
  nav, button, a[href^="/executions/new"] { display: none; }
  body { padding: 0; background: #fff; }
  .card {
    break-inside: avoid;
    border-color: #999;
    box-shadow: none;
    background-image: none;
  }
}
