:root {
    color-scheme: light dark;
    --border: #ccc;
    --panel-bg: #fafafa;
    /* /portfolio-comparison's Human/System/AI series colors (2026-08-12) --
       slots 1/2/3 (blue/orange/aqua) of the dataviz skill's validated
       8-hue categorical palette; those specific first three are the ones
       that clear the CVD/normal-vision floors on ALL pairs simultaneously
       (not just adjacent pairs), which is what a 3-line chart with a
       shared legend/tooltip needs -- see references/palette.md. Human
       gets slot 1 (blue) as the "primary"/first-mentioned strategy
       throughout this app's own docs, System slot 2, AI slot 3. */
    --series-human-v1: #2a78d6;
    --series-system-v1: #eb6834;
    --series-ai-v1: #1baf7a;
}

body {
    font-family: system-ui, -apple-system, "Hiragino Sans", sans-serif;
    margin: 0;
    padding: 0;
    line-height: 1.5;
}

.sim-banner {
    background: #b00020;
    color: #fff;
    text-align: center;
    padding: 0.5em 1em;
    font-weight: bold;
}

.site-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1em;
    padding: 0.75em 1.5em;
    border-bottom: 1px solid var(--border);
}

.site-title {
    font-size: 1.25em;
    font-weight: bold;
    text-decoration: none;
    color: inherit;
}

.site-nav {
    display: flex;
    gap: 0.5em;
}

.site-nav a {
    color: inherit;
    text-decoration: none;
    opacity: 0.75;
    padding: 0.35em 0.9em;
    border-radius: 999px;
}

.site-nav a:hover {
    opacity: 1;
    background: rgba(128, 128, 128, 0.12);
}

.site-nav a.active {
    opacity: 1;
    font-weight: bold;
    background: rgba(128, 128, 128, 0.18);
}

/* ログインユーザー表示・ログアウト(2026-08-16) -- .site-headerの右端に
   flexで押し出す(margin-left: auto)。roleがguestの時だけバッジを出し、
   「閲覧専用で見ている」ことを常時分かるようにする(guestに新しい色の
   意味を割り当てず、既存の.badgeをそのまま使う)。 */
.site-user {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 0.6em;
    font-size: 0.9em;
}

.site-logout-form { margin: 0; }

.site-logout-button {
    padding: 0.3em 0.8em;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--panel-bg);
    color: inherit;
    font: inherit;
    cursor: pointer;
}

@media (prefers-color-scheme: dark) {
    .site-logout-button { background: #1c1c1c; }
}

main {
    max-width: 1100px;
    margin: 0 auto;
    padding: 1em 1.5em 3em;
}

/* ログイン画面(2026-08-16) -- 単独ページ(base.htmlを継承しない、ログイン
   前はナビの各リンクがどうせ全部/loginへ弾かれるだけなので出さない)。
   カードは.panelをそのまま再利用し、画面中央に小さく表示する。 */
.login-main {
    max-width: 420px;
    margin: 3em auto;
    padding: 0 1.5em;
}

.login-panel {
    text-align: center;
}

.login-title {
    margin: 0 0 1em;
    font-size: 1.3em;
}

.login-panel .settings-form {
    text-align: left;
}

.login-error {
    color: #b00020;
    font-size: 0.9em;
    margin: 0 0 1em;
}

@media (prefers-color-scheme: dark) {
    .login-error { color: #ff6b6b; }
}

/* /performance only (base.html's {% block main_class %}) -- every other
   page keeps the 1100px default above (higher-specificity selector wins,
   no change to their layout). Fixed px, not a vw()-based value -- the
   earlier min(1800px, 96vw) recomputed continuously against the
   viewport, and combined with the wide table-layout:auto event list
   table below, made browser resizing visibly janky. A plain max-width
   still shrinks down to fit a narrower viewport than this value (where
   .table-scroll below takes over), it just no longer keeps
   recalculating against every resize pixel above that.
   1600px -> 2400px (2026-08-11): the イベント一覧 table grew from 10 to
   12 columns (signal, 人間判断(仮想購入)) and was clipping into
   .table-scroll's horizontal scroll even on a genuinely wide (~2000px)
   browser window -- this is just a cap, not a forced width (main still
   shrinks to fit anything narrower via margin:0 auto), so raising it
   only ever gives ADDITIONAL wide-viewport headroom before .table-scroll
   needs to kick in; it changes nothing on any screen already narrower
   than 1600px. */
main.performance-wide {
    max-width: 2400px;
}

.panel {
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 1em 1.25em;
    margin: 1.25em 0;
    background: var(--panel-bg);
}

.panel-highlight {
    border-color: #2a6fdb;
    border-width: 2px;
}

.cta-button {
    display: inline-block;
    margin-top: 0.5em;
    padding: 0.5em 1.25em;
    background: #2a6fdb;
    color: #fff;
    text-decoration: none;
    border-radius: 4px;
    font-weight: bold;
}

.cta-button:hover {
    background: #1f57ad;
}

.back-link {
    margin: 1em 0 0;
}

.back-link a {
    color: inherit;
    opacity: 0.8;
    text-decoration: none;
}

.back-link a:hover {
    opacity: 1;
    text-decoration: underline;
}

/* Neutral labels for internal states (classification/gate_result/...).
   Deliberately a single neutral style, not colored per value — this app
   never implies a buy/sell recommendation (see AI-DECISIONS.md). */
.badge {
    display: inline-block;
    padding: 0.15em 0.6em;
    border: 1px solid var(--border);
    border-radius: 4px;
    font-size: 0.9em;
    background: rgba(128, 128, 128, 0.1);
}

/* evaluation_status variants (performance.html). badge-caution flags
   corporate_action_review as needing a closer look (a data caveat, not a
   buy/sell signal -- see performance_view.py's module docstring) without
   breaking the neutral-badge philosophy above. badge-muted is for
   "未評価" (no performance_results row yet), visually de-emphasized
   rather than looking like a real computed status. */
.badge-caution {
    border-color: #b8860b;
    background: rgba(184, 134, 11, 0.15);
}

.badge-muted {
    opacity: 0.6;
    font-style: italic;
}

@media (prefers-color-scheme: dark) {
    .badge-caution { border-color: #d8ab3c; background: rgba(216, 171, 60, 0.18); }
}

/* Wide tables (e.g. performance.html's 15-column list) scroll within
   their own box instead of forcing the whole page to scroll sideways.
   max-height + overflow-y:auto (2026-08-11, on top of the original
   overflow-x-only version) additionally bounds this box to (roughly) one
   screenful: with 140+ rows, an unbounded box's own horizontal scrollbar
   sat at the box's bottom edge -- i.e. below every row -- so reaching it
   required scrolling the whole page all the way down first. Capping the
   box's height turns ROW scrolling into something that happens INSIDE
   this box too, so both of its scrollbars stay within the same
   screenful the box first appears in, from any page scroll position.
   Pairs with thead th's position:sticky below, which needs exactly this
   element to be the scrolling ancestor. */
/* イベント一覧 銘柄/会社名 絞り込み (2026-08-15, performance.html + app.js).
   .row-filtered-out hides an already-rendered row client-side -- no rows
   are ever removed from the DOM, just toggled, so the existing star/memo
   handlers (which look up .closest("tr")) keep working on hidden rows the
   same as visible ones. */
.event-filter {
    display: flex;
    align-items: center;
    gap: 0.6em;
    margin: 0.5em 0;
}

.event-filter-input {
    padding: 0.35em 0.6em;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--panel-bg);
    color: inherit;
    font: inherit;
    min-width: 16em;
}

.event-filter-count {
    font-size: 0.85em;
    opacity: 0.7;
}

.row-filtered-out {
    display: none;
}

.table-scroll {
    overflow: auto;
    max-height: 75vh;
}

.table-scroll thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    /* Matches .panel's own light/dark background exactly (hardcoded the
       same way .panel's dark-mode override already is, not via
       --panel-bg -- see that variable's own single :root definition --
       so a sticky header row reads as fully opaque against rows
       scrolling underneath it, in both themes) rather than a translucent
       rgba() tint that would let scrolled-under row text show through. */
    background: #fafafa;
}

@media (prefers-color-scheme: dark) {
    .table-scroll thead th { background: #1c1c1c; }
}

@media (prefers-color-scheme: dark) {
    .panel { background: #1c1c1c; }
    :root {
        --border: #444;
        /* Same three palette slots, stepped for the dark surface -- see
           references/palette.md's dark column, not a separate palette. */
        --series-human-v1: #3987e5;
        --series-system-v1: #d95926;
        --series-ai-v1: #199e70;
    }
    .panel-highlight { border-color: #5b9bf0; }
    .cta-button { background: #5b9bf0; color: #0a0a0a; }
    .cta-button:hover { background: #7bb0f5; }
}

.data-table, .kv-table {
    width: 100%;
    border-collapse: collapse;
    margin-top: 0.5em;
}

.data-table th, .data-table td,
.kv-table th, .kv-table td {
    border: 1px solid var(--border);
    padding: 0.4em 0.6em;
    text-align: left;
    font-size: 0.9em;
}

.kv-table th {
    width: 12em;
    background: rgba(128, 128, 128, 0.1);
}

/* portfolio_comparison.html/dashboard.html (2026-08-21): a plain sub-header
   row splitting a summary table into "主指標(%ベース)" / "参考(円ベース)"
   groups -- position_sizing.mode="quantity" (1株固定) made 円ベースの
   合計損益 not comparable across tickers, so %ベース指標(勝率・平均リターン%)
   is now the primary indicator (see rules.yaml's own comment / docs/11_
   validation_policy.md §3/§5). th already renders bold by default; only a
   background tint is added here to read as a section divider, not another
   data row. */
.table-group-header th {
    background: rgba(128, 128, 128, 0.15);
    text-align: left;
}

/* performance.html's summary table has longer labels than the 12em
   default above (e.g. "corporate_action_review", "screening snapshotが
   存在するevent数") that would otherwise wrap to two lines, AND its
   values are short numbers -- unlike every other kv-table in this app
   (e.g. dashboard's 総資産・損益 panel, which needs the shared
   width:100% above for its longer yen amounts), stretching this one to
   the full width of main.performance-wide leaves either column looking
   arbitrarily oversized no matter how the two columns split that width.
   So this table opts out of width:100% entirely and sizes itself to its
   own content (capped so it can't overflow a narrow screen); th only
   needs white-space:nowrap to guarantee its label never wraps. Scoped
   overrides -- .kv-table/.kv-table th themselves, and every other
   kv-table's layout, are unchanged. */
.performance-summary-table {
    width: auto;
    max-width: 40em;
}

.performance-summary-table th {
    white-space: nowrap;
}

/* イベント一覧 (performance.html) opts out of .data-table's shared
   width:100% -- same reason and same pattern as
   .performance-summary-table above: distributing any leftover width
   (container width minus the sum of every column's own width) across
   all columns proportionally would widen every one of them past what
   its content needs, INCLUDING squeezing whichever column has the
   least slack to spare (仮想購入判断・メモ's select+メモ badge visibly
   wrapped back onto two lines under this, 2026-08-12 -- the exact
   regression its own flex-wrap fix earlier that day was meant to
   prevent). .table-scroll's own overflow-x already exists for the
   reverse case (content that DOES need more than the container) --
   sizing to content here just stops wasting width when it doesn't.
   width:auto with table-layout:fixed below means the table's own width
   is simply the sum of the <colgroup> widths (templates/
   performance.html) -- no proportional redistribution either way.

   table-layout:fixed (2026-08-15, was the browser default table-
   layout:auto until now): auto requires the browser to inspect every
   cell in every row to compute each column's content-based width, on
   every reflow -- with ~148 un-paginated rows (see performance.html's
   own comment on why this table isn't paginated) that recomputation is
   what made dragging the browser window to resize it visibly janky
   (reported by the user, reproduced before this fix). fixed instead
   takes each column's width directly from the <colgroup> in
   performance.html (sized off real production content, see its own
   comment for the actual measurements) -- an O(columns) lookup instead
   of O(rows x columns), so a resize reflow no longer scales with row
   count. */
.performance-events-table {
    width: auto;
    table-layout: fixed;
}

/* イベント一覧's 5 percentage columns. Their VALUES are always short
   ("-44.3%" etc) but a shared width keeps all five visually equal
   instead of each sizing to its own header's length. white-space:nowrap
   guarantees neither the (now short, 2026-08-12) headers nor a value
   ever wraps. This th width is now redundant with -- but kept in sync
   with, see its own comment -- the <colgroup> in performance.html,
   which is what actually governs the column width now that
   .performance-events-table is table-layout:fixed (2026-08-15); left
   in place since removing it buys nothing and .col-pct isn't used
   anywhere else. */
.col-pct {
    width: 5.5em;
    white-space: nowrap;
}

/* イベント一覧's return_5d/10d/20d/max_return_20d/max_drawdown_20d
   (performance.html's pct() macro) -- negative values in red, same red
   as .error-list above, with a brighter dark-mode variant for contrast
   against a dark background (that existing rule has none since it's
   never shown on a dark panel background the way this table is). Not a
   buy/sell recommendation color -- just highlighting a negative number,
   same as red ink in any financial table. */
.pct-negative {
    color: #b00020;
}

@media (prefers-color-scheme: dark) {
    .pct-negative { color: #ff6b6b; }
}

/* |value| >= 28% (performance.html's LARGE_MOVE_THRESHOLD_PCT) -- an
   unusually large move, independent of sign; combines with
   .pct-negative (both classes on the same <span>) so a large negative
   value is bold AND red, not just one or the other. Background reuses
   .badge-caution's amber tokens exactly (chip-like padding/radius, same
   as that badge) -- one neutral "this magnitude is notable" highlight
   for both directions rather than a green/red or yellow/orange pair,
   which would either read as a buy/sell endorsement or fight for
   attention against the already-red pct-negative text. Direction is
   still conveyed by the sign and by pct-negative's red -- this only
   flags magnitude. */
.pct-large {
    font-weight: bold;
    background: rgba(184, 134, 11, 0.15);
    border-radius: 3px;
    padding: 0.1em 0.4em;
}

@media (prefers-color-scheme: dark) {
    .pct-large { background: rgba(216, 171, 60, 0.18); }
}

.row-buy { background: rgba(0, 128, 0, 0.08); }
.row-skip { color: #888; }

/* performance.html's 要監視 (human review flag) -- reuses the app's own
   existing blue accent (.cta-button/.panel-highlight's #2a6fdb) rather
   than a new color, since that's already this app's "pay attention to
   this" signal elsewhere. Whole-row tint so a flagged event stands out
   while scanning the list, distinct from .pct-large's per-value amber
   chip and .pct-negative's red text (all three can appear on the same
   row without visually colliding -- different property (background vs.
   text) and different hue). */
.row-watch {
    background: rgba(42, 111, 219, 0.08);
}

@media (prefers-color-scheme: dark) {
    .row-watch { background: rgba(91, 155, 240, 0.10); }
}

/* 要監視 star toggle (performance.html, replaces the old checkbox+label,
   2026-08-12) -- click posts via fetch (static/app.js), no page reload.
   ON state reuses .row-watch's same blue accent. */
.watch-star {
    border: none;
    background: none;
    padding: 0;
    margin-right: 0.15em;
    font-size: 1.1em;
    line-height: 1;
    vertical-align: -0.1em;
    cursor: pointer;
    color: var(--border);
}

.watch-star-on {
    color: #2a6fdb;
}

@media (prefers-color-scheme: dark) {
    .watch-star-on { color: #5b9bf0; }
}

/* メモ badge + inline editor (performance.html, replaces the old always-
   visible text input + 保存 button, 2026-08-12) -- one click target per
   row instead of three. Empty rows show the muted "＋ メモ" placeholder;
   rows with a note show it in full, never truncated (no max-width/
   ellipsis -- dropped 2026-08-12 per explicit request; still
   white-space:nowrap, so a long note widens the row instead of wrapping
   it taller, same one-line-per-row rule as everything else on this
   page -- .table-scroll's existing horizontal scroll is the escape
   valve for a note wide enough to need it). Click swaps this for
   .memo-input; blur/Enter saves via fetch, Escape cancels -- see
   static/app.js. */
.memo-badge {
    display: inline-block;
    white-space: nowrap;
    vertical-align: bottom;
    padding: 0.15em 0.6em;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: rgba(128, 128, 128, 0.1);
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.memo-badge-empty {
    opacity: 0.6;
    font-style: italic;
}

/* Wraps .memo-input (2026-08-12) -- a real <form> (name="note" on the
   input, same name the still-unchanged 人間判断 column's <form> uses) so
   the browser's own autocomplete keeps suggesting previously-typed note
   values here, same as it always did before this field became a JS-driven
   badge/editor instead of a plain always-visible <input>. display:
   inline-block only to avoid <form>'s default block-level layout shifting
   the row -- no visual styling of its own beyond that. */
.memo-form {
    display: inline-block;
}

.memo-input {
    width: 12em;
    padding: 0.25em 0.4em;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--panel-bg);
    color: inherit;
    font: inherit;
}

/* Momentary outline on a failed save (star or memo) -- there's no save
   button left to retry from, so the control itself needs to say
   something didn't stick. static/app.js removes this class again after
   a couple seconds. */
.save-error {
    outline: 2px solid #c0392b;
}

/* flex-wrap:nowrap (not wrap) deliberately: with wrap, a flex container's
   default min-width:auto lets the browser shrink the column and stack
   checkbox/input/button onto separate lines instead of growing the
   table -- exactly the 3-line-tall row regression reported 2026-08-11
   once the 人間判断(仮想購入) form doubled how many of these forms each
   row holds. nowrap forces the browser to size the column to fit one
   line, which (same as event_id's .nowrap above) just grows the table
   past main.performance-wide's width -- .table-scroll's own overflow-x
   already exists specifically to turn that into a horizontal scrollbar
   rather than a layout break, so nothing else needs to change for
   narrower viewports. */
.review-form {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    gap: 0.4em;
}

/* 人間判断(仮想購入) form (performance.html) -- select alone submits the
   form on change (static/app.js); no visible note input or button left
   (removed 2026-08-12 as a duplicate of the 要監視・メモ column -- see
   templates/performance.html's comment). */
.decision-select {
    flex-shrink: 0;
    padding: 0.25em 0.4em;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--panel-bg);
    color: inherit;
    font: inherit;
}

/* Wraps the 仮想購入判断 <form> + メモ badge + order-outcome paragraph in
   one column (2026-08-12, merged from two separate columns -- メモ and
   人間判断(仮想購入) -- into 仮想購入判断・メモ). Row, not column: select +
   メモ badge side by side keeps the row one line tall (stacking them
   doubled row height -- reported and reverted the same day). flex-wrap
   lets the occasional order-outcome <p> (仮想注文 #.../ 注文未作成: ...)
   drop to its own line instead of forcing the row wider when present. */
.decision-memo-cell {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3em;
}

.decision-order-info {
    margin: 0;
    font-size: 0.85em;
    opacity: 0.8;
}

.decision-order-skipped {
    color: #b8860b;
}

/* 仮想購入 sizing inputs (2026-08-12, human-v1 only; moved into
   #virtual-buy-modal the same day -- originally lived inline in the row
   itself, toggled via a `hidden` attribute, which re-triggered the same
   3-line-tall row regression .review-form's own comment above describes
   for this same column. A single shared modal sidesteps that entirely --
   it never affects any row's own height, open or closed. */
.sizing-inputs {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    gap: 0.3em;
}

.sizing-input {
    width: 6em;
    padding: 0.2em 0.4em;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--panel-bg);
    color: inherit;
    font: inherit;
}

.sizing-or {
    font-size: 0.8em;
    opacity: 0.7;
}

.sizing-submit-button {
    padding: 0.2em 0.6em;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--panel-bg);
    color: inherit;
    font: inherit;
    cursor: pointer;
}

/* Empty text takes no visible space -- only populated (see static/app.js's
   submit-time cross-field validation) when 株数/投資額 were both given or
   an obviously invalid value was typed, so client-side feedback doesn't
   require a round trip through the server's own PlainTextResponse 400
   (still the fallback if JS is unavailable -- see app.py). */
.sizing-error {
    color: #c0392b;
    font-size: 0.8em;
}

/* Re-opens #virtual-buy-modal for a row whose decision is ALREADY 仮想購入
   (see templates/performance.html's comment on this button) -- kept small
   and low-key since it's a secondary/retry action, not the primary one. */
.reopen-virtual-buy-button {
    margin-left: 0.4em;
    padding: 0.15em 0.5em;
    font-size: 0.8em;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--panel-bg);
    color: inherit;
    cursor: pointer;
}

/* Opens #virtual-sell-modal for a row with an open human-v1 position
   (2026-08-19, human_sell.py; moved from templates/performance.html to
   templates/dashboard.html's 仮想保有銘柄 panel 2026-08-20 -- see that
   template's comment on this button). Deliberately its OWN class, not a
   shared class with .reopen-virtual-buy-button, even though the visual
   style is identical below -- static/app.js's document-level click
   delegation keys off the class name to decide which modal to open, so
   sharing a class here would wire this button to the wrong (buy) modal
   too. */
.open-virtual-sell-button {
    margin-left: 0.4em;
    padding: 0.15em 0.5em;
    font-size: 0.8em;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--panel-bg);
    color: inherit;
    cursor: pointer;
}

/* #virtual-buy-modal (2026-08-12): a native <dialog>, centered by the
   browser's own UA stylesheet -- only box/spacing is set here. Same
   background convention as .panel/.table-scroll's sticky header above
   (var(--panel-bg) in light, a literal #1c1c1c override in dark -- not
   --panel-bg itself, which intentionally stays #fafafa in both modes,
   see .table-scroll thead th's own comment for why). `color` is left to
   inherit from body (color-scheme:light dark on :root already gives
   correct light/dark text color with no explicit body color set, same
   as the rest of this page). */
.virtual-buy-modal {
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1.25em;
    width: min(90vw, 24em);
    background: var(--panel-bg);
    color: inherit;
}

.virtual-buy-modal::backdrop {
    background: rgba(0, 0, 0, 0.4);
}

@media (prefers-color-scheme: dark) {
    .virtual-buy-modal { background: #1c1c1c; }
}

.virtual-buy-modal-title {
    margin: 0 0 0.75em;
    font-size: 1.1em;
}

.virtual-buy-modal-form {
    display: flex;
    flex-direction: column;
    gap: 0.6em;
}

.virtual-buy-modal-form .sizing-inputs {
    flex-wrap: wrap;
}

.virtual-buy-modal-reason-label {
    display: flex;
    flex-direction: column;
    gap: 0.3em;
    font-size: 0.85em;
}

.virtual-buy-modal-reason {
    resize: vertical;
    min-height: 4em;
    padding: 0.4em 0.5em;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--panel-bg);
    color: inherit;
    font: inherit;
}

@media (prefers-color-scheme: dark) {
    .virtual-buy-modal-reason { background: #1c1c1c; }
}

.virtual-buy-modal-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.5em;
    margin-top: 0.25em;
}

.virtual-buy-modal-cancel {
    padding: 0.3em 0.8em;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--panel-bg);
    color: inherit;
    font: inherit;
    cursor: pointer;
}

/* Dark-mode fix (2026-08-12, found via this session's own Playwright
   screenshot check -- see DEVELOPMENT.md's screenshot-verification loop):
   every control below pairs `background: var(--panel-bg)` (intentionally
   NEVER redefined itself for dark -- stays #fafafa in both modes, see
   .table-scroll thead th's own comment) with `color: inherit` (which DOES
   correctly become light/white in dark mode, via :root's `color-scheme:
   light dark` -- no explicit body color needed). Light text on an
   always-light background is invisible in dark mode: confirmed for
   .decision-select/.reopen-virtual-buy-button/.memo-input (pre-existing)
   and .sizing-input/.sizing-submit-button/.virtual-buy-modal-cancel
   (added earlier this same day, so never yet seen in dark mode in
   production either) via a real typed-value screenshot before this fix.
   Same literal #1c1c1c override as .panel/.table-scroll thead th/
   .virtual-buy-modal use for the same reason, applied here in one place
   rather than repeating it six times. MUST stay physically after every
   rule it overrides (equal specificity -- last one in source order wins
   whenever this media condition is active, @media or not) -- this was
   originally placed near .decision-select's own definition further up
   and silently lost to .reopen-virtual-buy-button/.sizing-input/
   .sizing-submit-button/.virtual-buy-modal-cancel's own later base
   rules until moved down here. */
@media (prefers-color-scheme: dark) {
    .decision-select,
    .memo-input,
    .sizing-input,
    .sizing-submit-button,
    .reopen-virtual-buy-button,
    .virtual-buy-modal-cancel,
    .open-virtual-sell-button {
        background: #1c1c1c;
    }
}

@media (prefers-color-scheme: dark) {
    .decision-order-skipped { color: #d8ab3c; }
}

.error-list { color: #b00020; }

code {
    font-size: 0.85em;
    word-break: break-all;
}

/* performance.html's event_date/event_id columns. .nowrap is a generic
   utility (event_date). event_id is forced to a single line the same
   way -- a fixed-width page (main.performance-wide above) plus
   .table-scroll's horizontal scroll means a long event_id widening its
   column is fine; it never needs to wrap at all, so this overrides the
   shared `code` element's word-break:break-all (still right for short,
   boundary-free strings like commit SHAs elsewhere in the app) outright
   rather than just relaxing it. */
.nowrap {
    white-space: nowrap;
}

.event-id-cell {
    white-space: nowrap;
}

.markdown-source-note {
    color: #666;
    font-size: 0.9em;
}

@media (prefers-color-scheme: dark) {
    .markdown-source-note { color: #aaa; }
}

.markdown-body table {
    width: 100%;
    border-collapse: collapse;
    margin: 0.75em 0;
    font-size: 0.9em;
}

.markdown-body th, .markdown-body td {
    border: 1px solid var(--border);
    padding: 0.4em 0.6em;
    text-align: left;
}

.markdown-body th {
    background: rgba(128, 128, 128, 0.1);
}

.markdown-body pre {
    background: rgba(128, 128, 128, 0.1);
    padding: 0.75em 1em;
    border-radius: 4px;
    overflow-x: auto;
}

.markdown-body blockquote {
    border-left: 3px solid var(--border);
    margin-left: 0;
    padding-left: 1em;
    color: #666;
}

@media (prefers-color-scheme: dark) {
    .markdown-body blockquote { color: #aaa; }
}

.month-group, .industry-group {
    border: 1px solid var(--border);
    border-radius: 6px;
    margin: 0.75em 0;
    padding: 0 0.9em;
}

.month-group summary, .industry-group summary {
    cursor: pointer;
    padding: 0.6em 0;
    font-weight: bold;
}

.month-group summary:hover, .industry-group summary:hover {
    opacity: 0.8;
}

.month-group table, .industry-group table {
    margin-bottom: 0.9em;
}

.search-form {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5em;
    margin: 0.9em 0;
}

.search-input {
    flex: 1 1 16em;
    padding: 0.4em 0.6em;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--panel-bg);
    color: inherit;
    font: inherit;
}

.search-form button {
    padding: 0.4em 1em;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--panel-bg);
    color: inherit;
    font: inherit;
    cursor: pointer;
}

.search-clear {
    font-size: 0.9em;
}

/* 値の意味 legend (performance.html, added 2026-08-12) -- deliberately
   subdued: no .panel border/background, small muted text throughout
   (same color tokens as .markdown-source-note), so it reads as a quiet
   reference at the very bottom of the page rather than competing with
   イベント一覧 above it. */
.legend {
    margin-top: 2em;
    padding-top: 1em;
    border-top: 1px solid var(--border);
    color: #666;
    font-size: 0.85em;
}

@media (prefers-color-scheme: dark) {
    .legend { color: #aaa; }
}

.legend-title {
    margin: 0 0 0.75em;
    font-size: 1em;
    font-weight: 600;
}

.legend-group {
    margin-bottom: 0.75em;
}

.legend-group h3 {
    margin: 0 0 0.25em;
    font-size: 0.95em;
    font-weight: 600;
}

.legend-group ul {
    margin: 0;
    padding-left: 1.2em;
}

.legend-group li {
    margin-bottom: 0.15em;
}

/* /portfolio-comparison (2026-08-12) -- see portfolio_comparison.py's
   module docstring and static/portfolio_comparison.js. Series identity
   (Human/System/AI) always comes from this swatch + the ink-colored text
   beside it, never from coloring the text itself -- dataviz skill's own
   "text never wears the data color" rule; validate_palette.js flagged the
   AI/aqua swatch below 3:1 contrast on the light surface specifically
   (WARN, not FAIL), whose documented mitigation -- visible ink-colored
   labels plus a full table view, both already present here regardless of
   the chart -- is exactly this page's existing design, not an extra
   step. */
.legend-swatch {
    display: inline-block;
    width: 0.8em;
    height: 0.8em;
    border-radius: 2px;
    margin-right: 0.35em;
    vertical-align: -0.05em;
}

.series-human-v1 { background: var(--series-human-v1); }
.series-system-v1 { background: var(--series-system-v1); }
.series-ai-v1 { background: var(--series-ai-v1); }

.portfolio-summary-table th:first-child {
    width: 14em;
    background: rgba(128, 128, 128, 0.1);
    white-space: nowrap;
}

.portfolio-summary-table thead th {
    white-space: nowrap;
}

.portfolio-chart-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 1em;
    margin: 0.5em 0;
    font-size: 0.9em;
}

.legend-entry {
    display: inline-flex;
    align-items: center;
}

.portfolio-chart-wrap {
    position: relative;
}

.portfolio-chart {
    width: 100%;
    height: auto;
    /* Fixed aspect ratio matches the SVG's own viewBox (900x320, set in
       static/portfolio_comparison.js) -- keeps the chart from collapsing
       to 0 height before JS runs/on a slow connection. */
    aspect-ratio: 900 / 320;
    touch-action: none;
}

.portfolio-chart-gridline {
    stroke: var(--border);
    stroke-width: 1;
}

.portfolio-chart-axis-label {
    fill: #898781;
    font-size: 11px;
}

.portfolio-chart-line {
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.portfolio-chart-line.series-human-v1 { stroke: var(--series-human-v1); }
.portfolio-chart-line.series-system-v1 { stroke: var(--series-system-v1); }
.portfolio-chart-line.series-ai-v1 { stroke: var(--series-ai-v1); }

.portfolio-chart-crosshair {
    stroke: var(--border);
    stroke-width: 1;
}

.portfolio-chart-marker {
    stroke: var(--panel-bg);
    stroke-width: 2;
}

.portfolio-chart-marker.series-human-v1 { fill: var(--series-human-v1); }
.portfolio-chart-marker.series-system-v1 { fill: var(--series-system-v1); }
.portfolio-chart-marker.series-ai-v1 { fill: var(--series-ai-v1); }

@media (prefers-color-scheme: dark) {
    .portfolio-chart-marker { stroke: #1c1c1c; }
}

.portfolio-chart-tooltip {
    position: absolute;
    top: 0;
    left: 0;
    pointer-events: none;
    background: var(--panel-bg);
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: 0.5em 0.7em;
    font-size: 0.85em;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
    white-space: nowrap;
    z-index: 1;
}

@media (prefers-color-scheme: dark) {
    .portfolio-chart-tooltip { background: #1c1c1c; }
}

.portfolio-chart-tooltip-date {
    font-weight: 600;
    margin-bottom: 0.3em;
}

.portfolio-chart-tooltip-row {
    display: flex;
    align-items: center;
    gap: 0.4em;
}

.portfolio-chart-tooltip-label {
    flex: 1;
    opacity: 0.8;
}

.trade-detail {
    font-size: 0.85em;
}

.trade-detail summary {
    cursor: pointer;
    opacity: 0.8;
}

.trade-detail p {
    margin: 0.3em 0;
}

.trade-detail-none {
    opacity: 0.5;
}

/* Footer: deliberately minimal, single "ドキュメント" link -- see
   AskUserQuestion decision (2026-08-13): nav already has 6 top-level
   items, a 7th /docs entry was declined in favor of an unobtrusive
   footer link instead. */
.site-footer {
    text-align: center;
    padding: 1.5em 1.5em 2em;
    opacity: 0.6;
    font-size: 0.85em;
}

.site-footer a {
    color: inherit;
}

/* /docs -- vouchers.aptty.com's /docs viewer's own doc-list/doc-view-
   layout/doc-toc-nav/doc-content class names, reused here for the same
   two-column (目次 + content) shape, but themed via this app's existing
   --border/--panel-bg tokens (already dark-mode aware, see .panel above)
   instead of vouchers' own hardcoded light-only hex palette. */
.doc-list { list-style: none; margin: 0; padding: 0; }
.doc-list-item { border-bottom: 1px solid var(--border); }
.doc-list-item:last-child { border-bottom: none; }
.doc-list-item a { display: block; padding: 0.75em 0.25em; color: inherit; text-decoration: none; }
.doc-list-item a:hover { text-decoration: underline; }

.doc-view-layout {
    display: grid;
    grid-template-columns: 220px 1fr;
    gap: 1.25em;
    align-items: start;
}

.doc-toc-nav {
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.9em;
    background: var(--panel-bg);
    position: sticky;
    top: 1em;
    max-height: calc(100vh - 2em);
    overflow-y: auto;
}

.doc-toc-heading {
    font-size: 0.75em;
    font-weight: bold;
    opacity: 0.6;
    letter-spacing: 0.05em;
    margin-bottom: 0.5em;
}

.doc-toc-nav .toc > ul,
.doc-toc-nav .toc ul {
    list-style: none;
    margin: 0;
    padding-left: 0;
}

.doc-toc-nav .toc a {
    display: block;
    padding: 0.3em 0.4em;
    border-radius: 4px;
    font-size: 0.82em;
    color: inherit;
    text-decoration: none;
    opacity: 0.85;
}

.doc-toc-nav .toc a:hover {
    opacity: 1;
    background: rgba(128, 128, 128, 0.12);
}

.doc-toc-nav .toc > ul > li > ul a { padding-left: 1.1em; opacity: 0.65; }
.doc-toc-nav .toc > ul > li > ul ul a { padding-left: 1.7em; }

.doc-content { max-width: 860px; }
.doc-content h1 { font-size: 1.4em; border-bottom: 2px solid var(--border); padding-bottom: 0.4em; }
.doc-content h2 { font-size: 1.15em; margin-top: 1.5em; }
.doc-content h3 { font-size: 1em; margin-top: 1.2em; }
.doc-content code { background: rgba(128, 128, 128, 0.12); padding: 0.1em 0.35em; border-radius: 4px; font-size: 0.9em; }
.doc-content pre code { background: none; padding: 0; }

@media (max-width: 900px) {
    .doc-view-layout { grid-template-columns: 1fr; }
    .doc-toc-nav { position: static; max-height: none; }
}

/* /strategy-settings (2026-08-14) -- ai-v1設定編集フォーム。sizing-inputs
   同様グリッドだが、8フィールド(モード+7しきい値+備考)を並べるため列数を
   増やしたバリエーション。 */
.settings-form {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 1em;
    align-items: end;
    margin-top: 0.5em;
}

.settings-field {
    display: flex;
    flex-direction: column;
    gap: 0.3em;
}

.settings-field label {
    font-size: 0.85em;
    opacity: 0.8;
}

/* Numeric field labels carry a title="" tooltip explaining what the
   value means (2026-08-14, same native title="" tooltip convention as
   performance.html's note/reason badges -- no custom tooltip widget
   introduced). Dotted underline + help cursor is the standard visual
   affordance for "hover this for more info". */
.settings-field-label-help {
    cursor: help;
    border-bottom: 1px dotted currentColor;
}

/* 過去バージョン一覧の「有効にする」ボタン (2026-08-14) -- 見た目は
   .reopen-virtual-buy-button と同じ小型セカンダリボタンだが、機能が
   異なるため別クラス名にしている(意味づけを明確にするため)。 */
.activate-version-form {
    margin: 0;
}

.activate-version-button {
    padding: 0.15em 0.5em;
    font-size: 0.8em;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--panel-bg);
    color: inherit;
    cursor: pointer;
    white-space: nowrap;
}

/* Deliberately its OWN dark-mode block placed AFTER the rule above,
   rather than folded into the earlier .reopen-virtual-buy-button-era
   dark-mode block near the top of this file -- that block sits BEFORE
   this class's own base rule in source order, so adding it there would
   silently lose to the (later, equal-specificity) rule above instead of
   overriding it -- see that block's own comment for the exact same
   gotcha it was written to document. */
@media (prefers-color-scheme: dark) {
    .activate-version-button { background: #1c1c1c; }
}

.settings-field input,
.settings-field select,
.settings-field textarea {
    padding: 0.4em 0.5em;
    border: 1px solid var(--border);
    border-radius: 4px;
    font: inherit;
    background: var(--panel-bg);
    color: inherit;
}

/* Dark-mode fix (2026-08-22, user-reported on templates/login.html's
   username/password fields, viewed on a phone with system dark mode --
   invisible white-on-light-gray input text). Same var(--panel-bg)
   (always-light) + color:inherit (correctly light/white in dark mode)
   mismatch as the 2026-08-12 fix above (.decision-select/.memo-input/
   etc.) and .activate-version-button's own later block -- .settings-field
   input/select/textarea was simply never added to either at the time.
   Deliberately its OWN block placed AFTER the base rule directly above
   (same equal-specificity/source-order gotcha those two comments already
   document) rather than folded into one of them. Affects every page that
   reuses .settings-field (login, memos, strategy-settings,
   system-rule-settings, ...), not just login -- one shared rule, one
   shared fix. */
@media (prefers-color-scheme: dark) {
    .settings-field input,
    .settings-field select,
    .settings-field textarea {
        background: #1c1c1c;
    }
}

.settings-field-wide {
    grid-column: 1 / -1;
}

.settings-form .cta-button {
    grid-column: 1 / -1;
    justify-self: start;
    border: none;
    cursor: pointer;
}

/* /ai-decisions (2026-08-14) -- buy/watch/avoid/error distribution bar.
   Colors deliberately REUSE this app's own existing hues rather than
   introducing a new palette: buy=.row-buy's green, watch=.row-watch's
   blue, avoid=.pct-negative's red, error=neutral gray. */
.decision-dist-bar {
    display: flex;
    width: 100%;
    min-width: 80px;
    height: 0.9em;
    border-radius: 3px;
    overflow: hidden;
    background: rgba(128, 128, 128, 0.15);
}

.dist-buy { background: rgba(0, 128, 0, 0.55); }
.dist-watch { background: rgba(42, 111, 219, 0.55); }
.dist-avoid { background: rgba(176, 0, 32, 0.55); }
.dist-error { background: rgba(128, 128, 128, 0.55); }

.decision-dist-legend {
    display: flex;
    gap: 1.2em;
    align-items: center;
    font-size: 0.85em;
    opacity: 0.85;
    margin: 0.5em 0 0;
}

.dist-legend-swatch {
    display: inline-block;
    width: 0.8em;
    height: 0.8em;
    border-radius: 2px;
    margin-right: 0.35em;
    vertical-align: middle;
}

/* /memos and company_detail.html's own メモ section (2026-08-15) -- see
   memos.py's module docstring. .memo-form reuses .settings-form/
   .settings-field as-is (same label-above-input grid, no new field
   styling needed). */

/* 見出し+「＋メモを追加」を1行にまとめてコンパクトにする (2026-08-15)。
   .cta-buttonは通常margin-top: 0.5emを持つため、この行の中では見出しと
   縦位置がずれる -- 0にリセットしている。 */
.memo-panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1em;
}

.memo-panel-header h2 {
    margin: 0;
}

.memo-panel-header .cta-button {
    margin-top: 0;
}

/* 使い方の説明 -- デフォルトで畳んでおき、常時3行分場所を取らないように
   する。markdown-source-noteと同じ控えめな色調。 */
.memo-panel-help {
    margin-top: 0.4em;
    font-size: 0.85em;
    color: #666;
}

.memo-panel-help summary {
    cursor: pointer;
}

.memo-panel-help p {
    margin: 0.4em 0 0;
}

@media (prefers-color-scheme: dark) {
    .memo-panel-help { color: #aaa; }
}
/* position: relative -- .memo-edit-buttonをこの要素基準の右上へ固定する
   ため。右側のpaddingはそのボタン用の余白(ヘッダー行の文字列と重ならない
   ようにする)。 */
.memo-item {
    position: relative;
    border-bottom: 1px solid var(--border);
    padding: 0.75em 3.5em 0.75em 0.25em;
}

.memo-item:last-child {
    border-bottom: none;
}

.memo-item-header {
    display: flex;
    gap: 0.6em;
    align-items: center;
    flex-wrap: wrap;
    margin-bottom: 0.3em;
}

.memo-item-body {
    white-space: pre-wrap;
    margin: 0;
}

/* 編集ボタン (2026-08-15) -- <details>自体は.memo-item-headerの外、本文の
   後ろに置いた普通のブロック要素(開いた時の編集フォームはそこに縦に
   伸びるだけで、ヘッダー行のflexレイアウトには一切影響しない -- 以前の
   実装は<details>をヘッダーのflex行の中に置いていたため、開いたときに
   編集フォームの中身(grid)がヘッダー全体のレイアウトを壊していた)。
   「右上のボタン」に見せているのは<summary>だけをposition: absoluteで
   .memo-item基準の右上に固定しているため -- 閉じている間は場所を取らず、
   開いてもヘッダー行やボタン自身の位置は動かない。 */
.memo-edit-button {
    position: absolute;
    top: 0.75em;
    right: 0.25em;
    list-style: none;
    display: inline-block;
    padding: 0.15em 0.5em;
    font-size: 0.8em;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--panel-bg);
    color: inherit;
    cursor: pointer;
    white-space: nowrap;
}

/* デフォルトの開閉矢印マーカーを消す -- Chrome/Safari(WebKit)とFirefox
   (::marker)の両方をカバー。list-style: noneだけでは古いWebKit系で
   矢印が残るため。 */
.memo-edit-button::-webkit-details-marker {
    display: none;
}

.memo-edit-button::marker {
    display: none;
}

.memo-edit-panel {
    margin-top: 0.75em;
}

.memo-form {
    margin-top: 0.75em;
}

/* Own class rather than reusing .activate-version-button (same look,
   different meaning -- see that class's own comment above for why this
   codebase keeps same-styled-but-different-purpose buttons separate). */
.memo-delete-form {
    margin: 0.5em 0 0;
}

.memo-delete-button {
    padding: 0.15em 0.5em;
    font-size: 0.8em;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--panel-bg);
    color: inherit;
    cursor: pointer;
}

@media (prefers-color-scheme: dark) {
    .memo-delete-button { background: #1c1c1c; }
    .memo-edit-button { background: #1c1c1c; }
}

/* 会社名(2026-08-15) -- codeバッジ(.badge)と並ぶが、company_nameは
   ticker検証もリンク先も持たないplain textなので別クラス。 */
.memo-company-name {
    font-size: 0.9em;
    opacity: 0.85;
}

/* メモ追加モーダル (2026-08-15) -- .virtual-buy-modal(performance.html)
   と全く同じ<dialog>の見た目(border/padding/幅/backdrop)をそのまま
   複製している。共有マクロ化するほど再利用箇所は多くない、という
   このアプリの既存方針(SBIリンクのコメント等を参照)と同じ判断。
   フィールド自体は.settings-field/.settings-formをそのまま再利用する
   (新しいフィールド用スタイルは追加していない)。 */
.memo-add-modal {
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1.25em;
    width: min(90vw, 28em);
    background: var(--panel-bg);
    color: inherit;
}

.memo-add-modal::backdrop {
    background: rgba(0, 0, 0, 0.4);
}

.memo-add-modal-title {
    margin: 0 0 0.75em;
    font-size: 1.1em;
}

.memo-add-modal-form {
    display: flex;
    flex-direction: column;
    gap: 0.6em;
}

.memo-add-modal-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.5em;
    margin-top: 0.25em;
}

.memo-add-modal-cancel {
    padding: 0.3em 0.8em;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--panel-bg);
    color: inherit;
    font: inherit;
    cursor: pointer;
}

/* .virtual-buy-modal/.virtual-buy-modal-cancel と同じdark-mode修正
   (2026-08-12の教訓 -- 上のコメント参照): background: var(--panel-bg)
   + color: inheritの組み合わせは、dark modeではinheritが明るい文字色に
   なる一方でpanel-bgは常に明るい背景のままのため、文字が見えなくなる。 */
@media (prefers-color-scheme: dark) {
    .memo-add-modal { background: #1c1c1c; }
    .memo-add-modal-cancel { background: #1c1c1c; }
}

/* トピックのグループ (2026-08-16) -- 複数銘柄にまたがる話題(例: 「HDD
   製造」)を1つの見出し+説明文+インデントされた銘柄別メモとしてまとめて
   表示する。左辺の帯は.panel-highlight/.row-watchと同じ既存の「注目」
   アクセント(青)をそのまま流用し、新しい色の意味を増やさない。 */
.topic-group {
    border: 1px solid var(--border);
    border-left: 4px solid #2a6fdb;
    border-radius: 6px;
    padding: 1em 1.25em 0.5em;
    margin: 1.25em 0;
    background: var(--panel-bg);
}

@media (prefers-color-scheme: dark) {
    .topic-group { border-left-color: #5b9bf0; }
}

/* 展開・折りたたみ(2026-08-16、デフォルト折りたたみ) -- .memo-panel-help
   の「使い方」と同じ、ネイティブ<details>のみ(JS不要)。トピック名だけを
   summaryにし、開閉のトリガー(クリック範囲)をトピック名部分に絞ることで、
   本文側にある「＋銘柄メモを追加」ボタンを押した時に開閉と競合しない
   ようにしている。 */
.topic-group-heading {
    margin: 0;
    font-weight: bold;
    font-size: 1.1em;
    cursor: pointer;
}

.topic-group-body {
    margin-top: 0.75em;
}

.topic-group-header {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 0.5em;
}

/* トピックへの銘柄メモ追加ボタン(2026-08-16) -- ページ上部の主要な
   「＋メモを追加」(.cta-button)より控えめな、トピックカード内の副次的な
   操作という位置づけ。トピックの帯と同じ青アクセントを枠線・文字色に
   使い、このカードに属する操作であることを示す。 */
.topic-group-add-button {
    flex-shrink: 0;
    padding: 0.3em 0.8em;
    font-size: 0.85em;
    border: 1px solid #2a6fdb;
    border-radius: 4px;
    background: var(--panel-bg);
    color: #2a6fdb;
    font: inherit;
    cursor: pointer;
}

@media (prefers-color-scheme: dark) {
    .topic-group-add-button { border-color: #5b9bf0; color: #5b9bf0; }
}

/* .memo-item自身と同じ「編集ボタンをposition: absoluteで右上に固定する
   ための土台」-- 説明メモ(code/company_nameが空)には.memo-itemの
   バッジ行が無いため、専用にposition: relative + 右側paddingだけを
   持たせている(.memo-edit-button/.memo-edit-details/.memo-edit-panelは
   .memo-itemのものをそのまま再利用)。 */
.topic-group-overview {
    position: relative;
    padding-right: 3.5em;
    /* 銘柄1件目と2件目の間の区切り(.memo-item自身のborder-bottom)と
       同じ見た目の線を、説明文と銘柄1件目の間にも入れる(2026-08-16)。 */
    padding-bottom: 0.75em;
    margin-bottom: 0.75em;
    border-bottom: 1px solid var(--border);
}

.topic-group-items {
    margin-left: 1.5em;
}

/* ドラッグ&ドロップでの並び替え(2026-08-16) -- /home/kakeiboの設定→
   カテゴリ管理と同じ見た目・流儀(⠿ハンドル、ドロップ先のハイライト)。
   static/app.jsのinitSortable()が.sortable-item同士でdragstart/dragover/
   drop/dragendを処理する。 */
.drag-handle {
    color: #666;
    font-size: 1rem;
    flex-shrink: 0;
    cursor: grab;
    user-select: none;
}

@media (prefers-color-scheme: dark) {
    .drag-handle { color: #aaa; }
}

.sortable-item.drag-over {
    box-shadow: 0 0 0 2px #2a6fdb;
    opacity: 0.6;
}

@media (prefers-color-scheme: dark) {
    .sortable-item.drag-over { box-shadow: 0 0 0 2px #5b9bf0; }
}
