/* =====================================================================
   Culminans シェルの共通スタイル（chaser の app.css から、シェル（レイアウト・ログイン・個人設定・
   ユーザー管理・メッセージ枠・アイコン）に関わる部分だけを抽出して移植したもの。
   モジュール固有のスタイルは各モジュールの wwwroot（_content/Culminans.Xxx/…）に置く。
   デザイントークン（--alt-*）はモジュールからも使ってよい（テーマは themes.css が上書きする）。
   ===================================================================== */

/* ===== デザイントークン（テーマ対応。themes.css が [data-theme] ごとに上書きする） =====
   ライトテーマの既定値。色を追加するときは、なるべく既存トークンを使い回すこと。 */
:root {
    /* 面（背景） */
    --alt-bg-body: #ffffff;          /* 本文エリアの背景 */
    --alt-bg-page: #f4f6f9;          /* 画面・パネルのうすい背景 */
    --alt-bg-subtle: #f7f9fc;        /* さらに薄い背景（ヘッダー行など） */
    --alt-bg-muted: #eef2f7;         /* ホバー・チップの背景 */
    --alt-surface: #ffffff;          /* カード・グリッドの面 */
    --alt-bg-primary: #ffffff;       /* サイドバー等の面（旧トークン。互換のため残す） */
    --alt-bg-secondary: #fafafa;

    /* 枠線 */
    --alt-border: #e3e8ef;
    --alt-border-strong: #cdd6e1;
    --alt-border-primary: #d4d4d4;
    --alt-border-secondary: #e5e5e5;

    /* 文字 */
    --alt-text-primary: #171717;
    --alt-text-body: #1f2933;
    --alt-heading: #2c3e50;
    --alt-text-strong: #3a4a5f;
    --alt-text-sub: #5b6b81;
    --alt-text-muted: #7a8ba6;
    --alt-text-secondary: #404040;
    --alt-text-secondary-hover: #262626;
    --alt-text-tertiary: #525252;
    --alt-text-placeholder: #737373;
    --alt-on-accent: #ffffff;        /* アクセント色・濃色の上に載せる文字 */
    --alt-tooltip-bg: #1f2933;       /* 絵だけのボタンの名札（2026-09-06） */
    --alt-tooltip-fg: #ffffff;

    /* アクセント（ブランド青） */
    --alt-brand: #1d4ed8;
    --alt-accent: #2c6fd9;
    --alt-accent-hover: #1a44c2;
    --alt-accent-weak: #4d7cc7;
    --alt-accent-soft: #eef4fd;      /* 選択・ホバーの薄青背景 */
    --alt-accent-soft-strong: #dbe8fb;
    --alt-nav-active-bg: var(--alt-accent-soft-strong);  /* サイドバーの現在位置。濃色サイドバーは themes.css で差し替える */
    --alt-parent-issue-bg: #fdf9ec;  /* 親課題（子課題を持つ課題）のうす黄背景。選択の薄青と区別する */

    /* 状態色 */
    --alt-danger: #d92c2c;
    --alt-danger-strong: #b00020;
    --alt-danger-text: #9b1c14;
    --alt-danger-bg: #fdf3f3;
    --alt-danger-border: #f0c2c2;
    --alt-success: #0b6b3a;
    --alt-success-text: #166534;
    --alt-success-bg: #f0faf4;
    --alt-success-border: #c2e6d2;
    --alt-warning-bg: #fff7e6;
    --alt-warning-border: #ffec99;
    --alt-warning-text: #8a6d00;

    /* ボタン */
    --alt-btn-primary-bg: #2c3e50;
    --alt-btn-primary-hover: #1f2d3a;

    /* 形状・影 */
    --alt-radius-sm: 6px;

    /* 入力フォームの最大幅（2026-09-06・TEST1-61）。ダイアログ（.dialog-form）とページ直置きの
       入力（.alt-form-grid）が同じ値を読む＝どちらかだけ広い画面を作らない。A4 の紙面に収まる幅。 */
    --alt-form-max: 800px;
    --alt-radius-md: 8px;
    --alt-radius-xl: 12px;
    --alt-shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.05);

    /* サイドバーの幅。ドラッグで変更し、localStorage に記憶する（sidebar-resize.js）。
       値は <html> のインラインスタイルで上書きされる。 */
    --alt-sidebar-width: 220px;
    --alt-sidebar-width-min: 200px;
    --alt-sidebar-width-max: 480px;
}

body {
    font-family: -apple-system, "Segoe UI", "Hiragino Sans", "Noto Sans JP", sans-serif;
    margin: 0;
    background: var(--alt-bg-body);
    color: var(--alt-text-body);
    line-height: 1.6;
}

/* 本文領域。ブラウザ幅にそのまま追随させる（一覧のグリッドを広い画面いっぱいに使うため）。
   以前は max-width: 1200px で中央寄せしていたが、ワイドモニタで左右が大きく余り、
   案件一覧の列が横スクロールに追いやられていたので上限を外した。 */
.container {
    margin: 1.75rem 0;
    padding: 0 1.5rem;
    width: 100%;
    box-sizing: border-box;
}

h1 { color: var(--alt-heading); }
h2 { color: var(--alt-heading); font-size: 1.15rem; margin-top: 1.5rem; }

#blazor-error-ui {
    display: none;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    background: var(--alt-warning-bg);
    padding: 0.6rem 1.25rem;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 0.9rem;
    top: 0.5rem;
}

/* ===== レイアウト（左サイドバー + 本文） ===== */
.app-shell {
    display: flex;
    align-items: stretch;
    min-height: 100vh;
}

.app-sidebar {
    flex: 0 0 var(--alt-sidebar-width);
    width: var(--alt-sidebar-width);
    /* 画面の高さに固定する（min-height ではない）。メニューが長くてもサイドバーは伸びず、
       はみ出す分は .app-tree の中だけでスクロールする＝本文とスクロールを分ける（2026-08-31 TEST1-48）。
       overflow は付けない＝アカウントのポップアップとフローティングメニューは
       サイドバーの外（left: calc(100% + 6px)）へ出るので、ここで切ると隠れる。 */
    height: 100vh;
    background: var(--alt-bg-primary);
    border-right: 1px solid var(--alt-border-secondary);
    padding: 20px 0;
    position: sticky;
    top: 0;
    align-self: stretch;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    box-sizing: border-box;
}

/* サイドバーの中身（ブランド・自分のアイコン・ベル・メニュー）。
   縦の flex にして余った高さをメニュー（.app-tree）へ渡す＝メニューだけがスクロールする。
   **下の .app-tree の指定と対で、通常幅のときだけ**＝狭い画面のドロワーはサイドバー自身がスクロールする作りで、
   ここで中身を縮めるとサイドバーが溢れなくなり、下のメニューに手が届かなくなる。 */
@media (min-width: 1025px) {
    .app-sidebar-main {
        display: flex;
        flex-direction: column;
        flex: 1;
        min-height: 0;
    }
}

/* サイドバー右端のつまみ（幅変更）。ダブルクリックで既定(220px)に戻る。 */
.app-sidebar-resizer {
    position: absolute;
    top: 0;
    right: -3px;
    width: 6px;
    height: 100%;
    z-index: 20;
    cursor: col-resize;
    background: transparent;
    touch-action: none;
}

.app-sidebar-resizer:hover,
.app-sidebar-resizer:focus-visible,
body.app-resizing .app-sidebar-resizer {
    background: rgba(29, 78, 216, 0.35);
    outline: none;
}

/* ドラッグ中は本文を選択させない（クラス付与は sidebar-resize.js）。 */
body.app-resizing {
    cursor: col-resize;
    user-select: none;
}

.app-brand {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 20px;
    margin-bottom: 20px;
}

/* Figma から書き出したロゴ（wwwroot/img/alterap-symbol.png）。 */
.app-brand-logo {
    display: inline-block;
    width: 24px;
    height: 24px;
    border-radius: var(--alt-radius-sm);
    background-image: url('img/alterap-symbol.png');
    background-size: contain;
    background-repeat: no-repeat;
}

.app-brand a {
    color: var(--alt-text-primary);
    font-size: 15px;
    line-height: 22px;
    font-weight: 700;
    text-decoration: none;
}

/* DevExpress の DxTreeView（サイドバーのメニュー）。
   user-select: none はダブルクリック開閉（tree-dblclick.js）でメニュー文字が
   選択反転しないようにするため（2026-08-10）。 */
.app-tree {
    padding: 0 16px;
    overflow: hidden;
    user-select: none;
}

/* メニューだけを内側でスクロールさせる（2026-08-31 TEST1-48）。縦だけ開けるので、横は上の hidden のまま
   ＝下の white-space: nowrap と対。flex: 1 と min-height: 0 が無いと、中身の高さのまま伸びてサイドバーからはみ出す。
   **通常幅のときだけ**＝狭い画面（≦1024px）のサイドバーは幅固定のドロワーで、
   あちらは既にサイドバー自身がスクロールする（1 段のままにして、頼まれていない挙動を足さない）。 */
@media (min-width: 1025px) {
    .app-tree {
        flex: 1;
        min-height: 0;
        overflow-y: auto;
    }
}

/* サイドバーが狭くてもメニュー文字を折り返さない（Phase7）。
   DevExpress内部スタイル（CJKは単語中でも改行される）より優先させるため全要素に強制。
   はみ出しはクリップ（.app-tree の overflow:hidden）。 */
.app-tree,
.app-tree * {
    white-space: nowrap !important;
    word-break: keep-all !important;
    overflow-wrap: normal !important;
}

/* はみ出すノード文字は省略記号に（内部クラス名は推測。効かなくてもクリップは上記で担保） */
.app-tree .dxbl-text {
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}

/* 階層のインデント。
   DxTreeView は展開アイコンの分だけ親の文字が右にずれるため、
   そのままだと子の方が左に見えてしまう。子側に余白を足して階層を揃える。
   もっと下げたい/戻したい場合は .alt-lv1 の padding-left を調整する。 */
.app-tree .alt-lv0 {
    padding-left: 0;
}

.app-tree .alt-lv1 {
    padding-left: 40px;
}

/* 第1階層の並び替え（2026-08-31 TEST1-50。取り回しは wwwroot/js/nav-reorder.js）。
   掴めることはカーソルで見せる（ノードは DevExpress が描くので、DOM に印を足さずに済ませる）。
   DevExpress の内部指定に負けないよう、行の要素まで書いて特異度を上げる（§7 の現在位置の強調と同じ理由）。
   **通常幅のときだけ**＝JS も同じ幅でしか並べ替えを始めないので、狭い画面で掴めるように見せない。 */
@media (min-width: 1025px) {
    .app-tree li.alt-lv0 > div[class*="dxbl-"] {
        cursor: grab;
    }
}

.app-tree li.app-nav-dragging {
    opacity: 0.5;
}

/* 運んでいる間（クラス付与は nav-reorder.js）。つまみのドラッグ（body.app-resizing）と同じ作り。 */
body.app-nav-reordering {
    cursor: grabbing;
    user-select: none;
}

/* 落とし先の合図（このノードの手前／後ろ）。線は li の内側に引く＝配下の子ツリーごと囲まない。 */
.app-tree li.app-nav-drop-before > div[class*="dxbl-"] {
    box-shadow: inset 0 2px 0 0 var(--alt-accent);
}

.app-tree li.app-nav-drop-after > div[class*="dxbl-"] {
    box-shadow: inset 0 -2px 0 0 var(--alt-accent);
}

/* 第3階層（プロジェクト配下の 概要/課題/…、機能設定配下のモジュール別の項目）。
   DxTreeView が階層分の余白（展開ボタン幅）を自前で付けるので、第2階層のような大きな下げ幅は要らない。
   第3階層より深い項目も同じクラスで描く（NavMenu の Lv が lv3 で頭打ちにする）。 */
.app-tree .alt-lv2,
.app-tree .alt-lv3 {
    padding-left: 12px;
}

/* 終わったもの（アーカイブ済みのプロジェクトなど。NavMenuItem.Archived）。
   隠さずに淡く出す＝開けるが、動いているものと同じ濃さで並ぶと見分けられない。
   地色は行要素だけに敷く（li は子ツリーごと含むため。現在位置の強調と同じ理由）。
   斜体は li に当てても DevExpress の内部指定に届かないので、テキスト要素へ直接当てる。
   **現在位置より前に置く**＝同じ特異度なので、後ろに置くと開いているアーカイブ済みの行が光らない。 */
.app-tree .alt-nav-archived .alt-ico {
    opacity: 0.45;
}

li.alt-nav-archived > div {
    background: var(--alt-bg-muted);
    border-radius: var(--alt-radius-sm);
}

li.alt-nav-archived > div .dxbl-text,
.app-flyout-item.alt-nav-archived {
    font-style: italic;
}

.app-flyout-item.alt-nav-archived {
    background: var(--alt-bg-muted);
    border-radius: var(--alt-radius-sm);
}

/* 項目の目印の色線（NavMenuItem.AccentColor。Pm のプロジェクトのヘッダーカラー）。
   色は項目ごとに違うので CSS クラスでは表せない＝NavMenu が --app-nav-accent に載せて渡す。
   ツリーは文字の直前（TextTemplate の中）、フローティングメニューは文字の手前の空要素。 */
.app-nav-accent {
    border-left: 3px solid var(--app-nav-accent);
    border-radius: 1px;
    padding-left: 6px;
}

.app-nav-accent-mark {
    flex: none;
    width: 3px;
    align-self: stretch;
    min-height: 1em;
    border-radius: 1px;
    background: var(--app-nav-accent);
    margin-left: -2px;
}

/* 画像アイコン（NavMenuItem.IconUrl が DxTreeViewNode.IconUrl に渡す img。Pm のプロジェクトアイコン）。
   DevExpress は大きさを指定しないので、そのままだと画像の原寸（100px）で出る。
   ほかのメニューアイコン（.alt-ico-sm）と同じ 16px に揃え、縦横比の違う画像でも崩れないよう cover で切り抜く。
   img.dxbl-image は DevExpress が生成する内部クラス（この img に自前の class を付けさせてもらえないための
   逃げ道）。版が上がって名前が変わると**サイドバーだけ原寸で出る**（CSS なので例外もログも出ない）ので、
   アイコンの見た目が急に大きくなったらここを疑うこと。フローティング側は自前の .app-flyout-ico。 */
.app-tree img.dxbl-image {
    width: 16px;
    height: 16px;
    border-radius: 4px;
    object-fit: cover;
}

/* 現在ページ・現在セクションのノード（DxTreeViewNode の CssClass で付与）。
   ツリーでは CssClass が li（＝子ツリーごと含む要素）に付くため、強調は「li 直下の行要素」
   （.dxbl-treeview-item-content）にだけ当てる。子ツリーは div ではない兄弟要素
   （dxbl-expandable-container）なので、この境界なら配下を巻き込まない。
   li 自身や子孫セレクタ（.alt-nav-active *）に当てると、グループが現在位置のときに
   配下の項目まで同じ色・太さになり、どの行が現在位置か分からなくなる（2026-08-24 実測）。
   太字は li に当てても DevExpress の内部指定に届かないので、テキスト要素へ直接当てる。 */
li.alt-nav-active > div {
    background: var(--alt-nav-active-bg);
    border-radius: var(--alt-radius-sm);
    color: var(--alt-text-secondary-hover);
}

li.alt-nav-active > div .dxbl-text {
    font-weight: 600;
}

/* ツリー以外（アイコンリストバー・フローティングメニュー）は要素全体を塗る。 */
:not(li).alt-nav-active {
    background: var(--alt-nav-active-bg);
    border-radius: var(--alt-radius-sm);
    font-weight: 600;
    color: var(--alt-text-secondary-hover);
}

/* Figma から書き出したアイコンSVG（wwwroot/icons/）。 */
.alt-ico {
    display: inline-block;
    width: 20px;
    height: 20px;
    background-repeat: no-repeat;
    background-position: center;
    background-size: 20px 20px;
    vertical-align: middle;
}

.alt-ico-home { background-image: url('icons/home-line.svg'); }
.alt-ico-star { background-image: url('icons/star-01.svg'); }

/* サイドメニューの子項目用アイコン（Phase7。少し小さく表示） */
.alt-ico-sm {
    width: 16px;
    height: 16px;
    background-size: 16px 16px;
}

.alt-ico-folder { background-image: url('icons/folder.svg'); }
.alt-ico-plus { background-image: url('icons/plus-circle.svg'); }
.alt-ico-eye { background-image: url('icons/eye.svg'); }
.alt-ico-board { background-image: url('icons/columns-03.svg'); }
.alt-ico-gantt { background-image: url('icons/gantt-bars.svg'); }
.alt-ico-burndown { background-image: url('icons/trend-down.svg'); }
.alt-ico-wiki { background-image: url('icons/book-open.svg'); }
.alt-ico-file { background-image: url('icons/file-04.svg'); }
.alt-ico-users { background-image: url('icons/users-01.svg'); }
.alt-ico-edit { background-image: url('icons/pencil-01.svg'); }
/* コメントの引用（2026-08-08）。閉じ引用符「99」の形。16pxでも読み取れることを確認済み。 */
.alt-ico-quote { background-image: url('icons/quote.svg'); }
.alt-ico-window { background-image: url('icons/layout-top.svg'); } /* 簡易ビュー（カード/ウィンドウ風。Phase7） */

/* 入力欄の Markdown ツールバー（2026-08-28。Figma の alt-Template から書き出した Untitled UI のアイコン）。
   連番の箇条書きだけは元のセットに無いので、同じ書式（20x16・stroke 2）で自作した。 */
.alt-ico-bold { background-image: url('icons/bold-01.svg'); }
.alt-ico-italic { background-image: url('icons/italic-01.svg'); }
.alt-ico-strike { background-image: url('icons/type-strikethrough-01.svg'); }
.alt-ico-bullets { background-image: url('icons/dotpoints-01.svg'); }
.alt-ico-numbers { background-image: url('icons/list-numbered.svg'); }
.alt-ico-table { background-image: url('icons/layout-grid-02.svg'); }
.alt-ico-code { background-image: url('icons/brackets-ellipses.svg'); }
.alt-ico-link { background-image: url('icons/link-03.svg'); }
.alt-ico-edit { background-image: url('icons/edit-05.svg'); }
.alt-ico-delete { background-image: url('icons/delete.svg'); }

/* 一覧の操作列のアイコン（2026-09-05・TEST1-60）。**操作列のボタンは絵で揃える**ので、
   文字で並んでいた動詞のぶんだけ絵が要る。当てられる絵が既にあるもの（編集・削除・表示/非表示・
   リンク・割り当て）はそれを使い、無かった 5 つ（開く・複製・棄却・バーコード・取り下げ）は
   ほかと同じ書式（24x24・stroke 2・角丸）で足した。
   **同じ画像に別の名前を付けているのは意味が違うから**＝片方の絵を替える日に、もう片方まで
   替えたくない。この差分で 3 組ある＝admin（サイドバーの「管理」）と settings（行の設定を開く）、
   todo（Pm のメニュー）と check（確定・採用）、doc（Sales の伝票）と note（行のメモ）。 */
.alt-ico-open { background-image: url('icons/arrow-square-up-right.svg'); }
.alt-ico-copy { background-image: url('icons/copy-01.svg'); }
.alt-ico-close { background-image: url('icons/x-close.svg'); }
.alt-ico-barcode { background-image: url('icons/barcode.svg'); }
.alt-ico-undo { background-image: url('icons/flip-backward.svg'); }
.alt-ico-check { background-image: url('icons/check-circle.svg'); }
.alt-ico-note { background-image: url('icons/file-05.svg'); }
.alt-ico-settings { background-image: url('icons/settings-01.svg'); }
.alt-ico-layout { background-image: url('icons/layout-top.svg'); }
.alt-ico-download { background-image: url('icons/file-download.svg'); }
.alt-ico-print { background-image: url('icons/printer.svg'); }

/* 明細を編める表の並べ替え（2026-09-06・TEST1-60。Figma の alt-Template から）。
   **矢印ではなく山形**＝1 つ上・1 つ下へずらす操作で、行が飛んでいく矢印より近い。
   × は共通の close をそのまま使う。 */
.alt-ico-move-up { background-image: url('icons/chevron-up.svg'); }
.alt-ico-move-down { background-image: url('icons/chevron-down.svg'); }

/* 操作が多すぎる一覧の「その他」（2026-09-06・TEST1-60）。**絵が 4 つを超えたら畳む**＝
   同じ大きさの絵が横に並ぶほど、どれが目当てか見分けるのに時間がかかる。
   残すのは「よく押すもの」だけで、残りはこの中へ入れる。 */
.alt-ico-more { background-image: url('icons/dots-horizontal.svg'); }

/* ワークフロー図の整列メニュー（2026-09-04・TEST1-55。Figma の alt-Template「Layout」から書き出した
   Untitled UI のアイコン）。**矢印つきの -01 系を採った**＝図形 2 つを並べた -02 系は、左揃え・中央・右揃えが
   16px では同じ絵に見えて選び分けられない。名前の horizontal / vertical は**寄せる向きではなく基準線の向き**
   （horizontal-centre は縦線へ左右から寄せる＝左右中央）なので、クラス名は画面の言葉に合わせてある。 */
.alt-ico-align-left { background-image: url('icons/align-left-01.svg'); }
.alt-ico-align-center-x { background-image: url('icons/align-horizontal-centre-01.svg'); }
.alt-ico-align-right { background-image: url('icons/align-right-01.svg'); }
.alt-ico-align-top { background-image: url('icons/align-top-01.svg'); }
.alt-ico-align-middle-y { background-image: url('icons/align-vertical-center-01.svg'); }
.alt-ico-align-bottom { background-image: url('icons/align-bottom-01.svg'); }
.alt-ico-distribute-x { background-image: url('icons/distribute-spacing-horizontal.svg'); }
.alt-ico-distribute-y { background-image: url('icons/distribute-spacing-vertical.svg'); }

/* 簡易ビューのツールバー（2026-08-28）。ウォッチ中は eye-off に差し替える＝押すと解除、が絵で読める。 */
.alt-ico-browser { background-image: url('icons/browser.svg'); }
.alt-ico-eye-off { background-image: url('icons/eye-off.svg'); }
.alt-ico-attachment { background-image: url('icons/file-attachment-05.svg'); }

/* カスタムフォーム（2026-08-31。Figma の alt-Template から書き出した Untitled UI の code-browser）。
   画面から表を組み立てるモジュールなので、枠（browser）の中に山かっこが入った絵を当てる。
   もとは rows-03（alt-ico-master）で、ほかのモジュールの一覧と同じ絵だった。 */
.alt-ico-form { background-image: url('icons/code-browser.svg'); }

/* 入力欄の「添付」ボタン（2026-08-28）。クリップの形は簡易ビューの添付（file-attachment-05）と
   分けてある＝あちらは「この課題に付いているファイル」、こちらは「本文に添える」で意味が違う。 */
.alt-ico-paperclip { background-image: url('icons/paperclip.svg'); }

/* プライマリ（青）・デンジャー（赤）ボタン上のアイコンは白抜きに（アイコンSVGは黒ストロークのため。Phase7） */
.btn-primary .alt-ico,
.btn-danger .alt-ico,
.dxbl-btn-primary .alt-ico,
.dxbl-btn-danger .alt-ico {
    filter: invert(1);
}

/* ただしドロップダウンの項目は白抜きにしない（2026-09-04）。**DevExpress のメニュー項目は
   中身が dxbl-btn-primary クラスを持つ**（見た目は白地に黒文字なのに）ので、上の規則が誤爆して
   アイコンが白い線になり、白い背景の上で完全に見えなくなる。要素も背景画像も正しいまま
   色だけが消えるので、例外もログも出ない。
   **暗いテーマの反転（themes.css の html[data-theme="dark"] .alt-ico）はこれより詳細度が高いので残る**
   ＝暗い背景では白いままで正しい。打ち消したいのは上の 1 つだけなので、ここは !important にしないこと。 */
.dxbl-btn-dropdown-item .alt-ico {
    filter: none;
}
.alt-ico-data { background-image: url('icons/bar-chart-square-02.svg'); }
.alt-ico-master { background-image: url('icons/rows-03.svg'); }
/* Import/Export: ユーザー提供の cloud-download / cloud-upload を合成した自作アイコン（2026-08-07）。
   旧: upload-01.svg（上向き矢印のみで取込み側が表せていなかった）。 */
.alt-ico-transfer { background-image: url('icons/import-export.svg'); }
/* フォームのレコードの入出力（2026-09-02。CUL1-38。Untitled UI の upload-cloud-02 / download-cloud-02）。
   **1 つの絵（alt-ico-transfer）で兼ねない**＝あちらは管理画面の「入出力」という 1 つの機能を指すが、
   こちらは取り込みと書き出しが別のボタンとして並ぶので、向きの違う絵でないと押し分けられない。 */
.alt-ico-import { background-image: url('icons/upload-cloud-02.svg'); }
.alt-ico-export { background-image: url('icons/download-cloud-02.svg'); }
/* Figmaの「管理」はOpsgenieのブランドロゴ。単体で書き出せなかったため同じアイコンセットの歯車を使用。 */
.alt-ico-admin { background-image: url('icons/settings-01.svg'); }
/* 全体通知（Phase8。2026-08-11）。拡声器。既存アイコンセットに無かったため同じ線幅・角丸で自作。 */
.alt-ico-megaphone { background-image: url('icons/announcement-01.svg'); }
/* ---- 販売・購買・在庫の絵（2026-08-26。Figma の alt-Template / Icons から取得）----
   もとは filter-lines を請求、bar-chart を入金、rows-03 を在庫に当てていた＝手元にある絵で間に合わせた状態で、
   絵と意味が合っていなかった。売り買いで対応する伝票は同じ絵にする（見積と発注、請求と仕入請求）。 */
/* Slack 連携（本人のアカウント紐付け）。 */
.alt-ico-route { background-image: url('icons/route.svg'); }

/* Slack のマーク（単色）。Figma のセットには入っていないので Bootstrap Icons（MIT）から取り、
   ほかのアイコンと同じ 24x24 の枠に揃えてある。**塗りのアイコンなので線幅は合わせられない**
   ＝ロゴは形が決まっていて描き直せない（商標）。 */
.alt-ico-slack { background-image: url('icons/slack.svg'); }
/* 組織管理は dataflow-01 を 270 度回したもの（縦の階層図を横向きの組織図として使う）。SVG 側で回してあるので
   CSS の transform は要らない＝背景画像は transform で回せない。 */
.alt-ico-org { background-image: url('icons/dataflow-01-rotate270.svg'); }
/* 帳票レイアウト（用紙の四隅と余白）。 */
.alt-ico-layout-dots { background-image: url('icons/grid-dots-outer.svg'); }
/* プロジェクト管理（製図コンパス）。folder は配下の「プロジェクト」「ファイル」が使い続ける。 */
.alt-ico-compass { background-image: url('icons/compass.svg'); }
.alt-ico-bag { background-image: url('icons/shopping-bag-03.svg'); }
.alt-ico-cart { background-image: url('icons/shopping-cart-01.svg'); }
.alt-ico-doc { background-image: url('icons/file-05.svg'); }
.alt-ico-receipt { background-image: url('icons/receipt.svg'); }
.alt-ico-file-check { background-image: url('icons/file-check-02.svg'); }
.alt-ico-chart-breakout { background-image: url('icons/chart-breakout-square.svg'); }
.alt-ico-receipt-check { background-image: url('icons/receipt-check.svg'); }
.alt-ico-coins { background-image: url('icons/coins-hand.svg'); }
.alt-ico-package { background-image: url('icons/package.svg'); }
.alt-ico-package-check { background-image: url('icons/package-check.svg'); }
.alt-ico-package-plus { background-image: url('icons/package-plus.svg'); }
.alt-ico-clipboard-check { background-image: url('icons/clipboard-check.svg'); }
.alt-ico-database { background-image: url('icons/database-01.svg'); }
.alt-ico-tag { background-image: url('icons/tag-01.svg'); }

/* 情報（お知らせの既定。発信元のモジュールが分からないとき）。既存セットに無かったため自作。 */
.alt-ico-info { background-image: url('icons/info-circle.svg'); }
.alt-ico-ai { background-image: url('icons/stars-02.svg'); }
.alt-ico-todo { background-image: url('icons/check-circle.svg'); }
/* ワークフロー（Phase10。2026-08-12）。既存セットに無かったため同じ線幅・角丸で自作したフロー図。 */
.alt-ico-flow { background-image: url('icons/dataflow-03.svg'); }

/* 「自分のアイコン」の置き場（Phase7・2026-08-07 以降はアイコン1つだけを常駐させる）。
   パスワード変更・2段階認証・ログアウトはアイコンのポップアップから個人設定へ入る。
   2026-08-09: サイドバー最下部（.app-sidebar-footer）から、お知らせベルの上へ移動。 */
.app-sidebar-account {
    padding: 0 12px;
    margin-bottom: 10px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

/* ---- 常駐アカウントアイコン（AccountMenu.razor） ---- */
.app-account {
    position: relative;
    width: 100%;
}

.app-account-btn {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    box-sizing: border-box;
    padding: 8px;
    border: 1px solid var(--alt-border-secondary);
    border-radius: var(--alt-radius-xl);
    background: none;
    text-align: left;
    cursor: pointer;
}

.app-account-btn:hover,
.app-account.is-open .app-account-btn {
    background: var(--alt-bg-secondary);
}

.app-account-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.app-account-name {
    font-size: 14px;
    line-height: 20px;
    font-weight: 600;
    color: var(--alt-text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.app-account-role {
    font-size: 12px;
    line-height: 18px;
    color: var(--alt-text-tertiary);
    white-space: nowrap;
}

/* ショートカットのポップアップ。2026-08-09 にアカウントをサイドバー上部へ移したため
   下方向（top 基準）に開く（以前は最下部だったので上方向だった）。
   見た目はアイコンバーのフローティングメニュー(.app-flyout)と揃えている。 */
.app-account-pop {
    position: absolute;
    left: 0;
    top: calc(100% + 6px);
    z-index: 60;
    min-width: 220px;
    padding: 8px;
    background: var(--alt-bg-primary);
    border: 1px solid var(--alt-border-secondary);
    border-radius: var(--alt-radius-md);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.14);
}

.app-account-pop .app-flyout-item {
    width: 100%;
    box-sizing: border-box;
    border: none;
    background: none;
    cursor: pointer;
    text-align: left;
}

.app-account-pop-sep {
    height: 1px;
    margin: 6px 2px;
    background: var(--alt-border-secondary);
}

/* ポップアップを本文より手前に出すため、サイドバー自体を持ち上げる。
   （position:sticky の .app-sidebar はスタッキングコンテキストを作るので、
     中の z-index だけ上げても DevExpress の sticky ヘッダー等に負ける。
     モバイルのドロワー(50)より低くしてあるので、狭い画面の挙動は変わらない） */
@media (min-width: 1025px) {
    .app-sidebar {
        z-index: 40;
    }
}

.app-body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    background: var(--alt-bg-primary);
}

/* ===== モジュール共通の画面部品（Sales/Pm/Workflow から使う。モジュールの CSS は互いに参照できないのでここに置く） ===== */
/* カード（見出し付きの枠） */
.alt-card { margin: 0 0 1rem; padding: 0.9rem 1.1rem; border: 1px solid var(--alt-border); border-radius: var(--alt-radius-sm); background: var(--alt-surface); }
.alt-card-title { margin: 0 0 0.6rem; font-size: 1.05rem; font-weight: 700; }
/* 2 列のフォームグリッド（alt-span2 で 2 列ぶち抜き。狭い画面では 1 列） */
/* 入力の並び（2 列）。**幅は --alt-form-max で止める**（2026-09-05・TEST1-61）＝ダイアログ
   （.dialog-form）と同じ上限を、ページに直に置いたフォーム（伝票の編集・各モジュールの設定画面）にも
   効かせる。ダイアログの中はもともとこれより狭いので、二重にかかっても何も変わらない。
   **入力ではなく表や数字を 2 列に並べるためにこの道具を借りている場所は alt-form-wide で外す**
   ＝この規則が見ているのは「2 列に並べる」というクラスであって「入力かどうか」ではないので、
   借りている側が自分で名乗る（alt-w-full と同じ流儀）。 */
.alt-form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 14px; max-width: var(--alt-form-max); }
.alt-form-grid.alt-form-wide { max-width: none; }
.alt-form-grid > div { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.alt-form-grid label { color: var(--alt-text-sub); font-size: 0.85rem; }
.alt-span2 { grid-column: span 2; }
@media (max-width: 720px) {
    .alt-form-grid { grid-template-columns: 1fr; }
    .alt-span2 { grid-column: span 1; }
}
/* 詳細画面の見出し行（タイトル＋右寄せの操作ボタン） */
.wf-detail-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; flex-wrap: wrap; }
.wf-detail-actions { display: flex; gap: 8px; flex-shrink: 0; flex-wrap: wrap; }

/* 帳票の印刷プレビュー（Core の Components/ReportPreview）。ビューアは入れ物の高さいっぱいに広がるので、
   高さを持つのはこの入れ物。Core に wwwroot は無いので Core 部品の CSS はここに置く（CLAUDE.md §2）。 */
.report-preview { height: 78vh; }

/* 帳票レイアウトのデザイナー（Pages/AdminReportLayouts）。プレビューと同じで、高さを持つのは入れ物のほう。
   デザイナーは道具箱と項目一覧を左右に置くので、プレビューより高さが要る。 */
.report-designer { height: 82vh; }
/* 様式の選択。幅を決めないと DxComboBox が行いっぱいに伸びて、状態と操作が次の行へ落ちる。 */
.grid-toolbar .report-style-select { width: 260px; align-self: center; }

.logout-form {
    margin: 0;
}

/* ウィザードの歩（矢羽）。**Pm のリポジトリ連携と Forms の作成ウィザードが同じものを要求した**ので
   シェルへ移した（app.css に置くのは 2 つ以上のモジュールが使うものだけ）。
   いまどこにいるかは形と色で示す＝太字だけだと並んだうちのどれが現在なのか一目で分からない。 */
.alt-wizard-steps { display: flex; gap: 2px; flex-wrap: nowrap; margin-bottom: 8px; font-size: 0.9rem; list-style: none; padding: 0; }
.alt-wizard-steps > * {
    flex: 1 1 0;
    min-width: 0;
    padding: 6px 10px 6px 22px;
    background: var(--alt-bg-muted);
    color: var(--alt-text-muted);
    text-align: center;
    clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 50%, calc(100% - 12px) 100%, 0 100%, 12px 50%);
}
/* 端の矢は外側を切らない（最初の左と最後の右はまっすぐ）。 */
.alt-wizard-steps > *:first-child { padding-left: 10px; clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 50%, calc(100% - 12px) 100%, 0 100%); }
.alt-wizard-steps > *:last-child { clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%, 12px 50%); }
.alt-wizard-steps .is-done { background: var(--alt-accent-soft-strong); color: var(--alt-text-strong); }
.alt-wizard-steps .is-active { background: var(--alt-accent); color: var(--alt-on-accent); font-weight: 600; }
/* 状態（is-active / is-done）を選ぶ規則は Core の WizardSteps。CSS と対にしてある
   ＝写すと、状態を 1 つ足したときにどれかの画面が取り残される。 */

.linklike {
    background: none;
    border: none;
    cursor: pointer;
    font: inherit;
}

/* 並んだリンク風ボタンのあいだの余白。**素の空白 1 つでは足りず**、一覧の操作列で
   「開く 設定 編集」が 1 続きの文に見える（2026-08-31 の指摘 CUL1-35）。
   ここ 1 か所に置く＝画面ごとに書くと、次に足した一覧が必ず取り残される。 */
.linklike + .linklike {
    margin-left: .75rem;
}

/* 書き出しの形を選ぶドロップダウンの中身（Forms のレコード、シフト表）。**1 行 1 つで、折り返させない**
   ＝素の .dialog-form は幅なりに流れるので、「CSV (Shift_JIS)」が 2 行に割れたり 3 つが横一列になったりする
   （どちらも何行あるのか読み取りにくい）。幅を数字で決めないのは、言語で長さが変わるため。
   **2 つ目の要求者（シフト表の書き出し・2026-09-07）が出たのでモジュールから上げた**＝写すと、
   片方だけ間隔や折り返しを直した日に同じ見た目のメニューが 2 種類になる。 */
.export-menu {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: .35rem;
    white-space: nowrap;
}

/* **左の余白は打ち消す**＝上の `.linklike + .linklike` は<b>横に並ぶ</b>リンクのあいだを空けるためのもので、
   縦に積むここでは 2 つ目以降だけが右へずれる。縦の間隔は上の gap が持つ。 */
.export-menu .linklike + .linklike {
    margin-left: 0;
}

/* システムエリア（本文の 1 行目・2026-09-05・TEST1-61。実体は Components/Layout/SystemBar）。
   いまのモジュール（絵＋名前）とパンくずを 1 行に左寄せで並べる。
   **本文（main.container）の中に置く**＝画面の上へ貼り付けると、TEST1-48/50 で分けた
   「メインだけがスクロールする」作りの外に出ることになり、狭い画面では上部バー
   （.app-mobile-bar）と役割が二重になる。
   折り返しは許す＝モジュール名も項目名も翻訳で伸びるので、狭い画面で 1 行に押し込むと文字が切れる。 */
.app-systembar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .35rem;
    margin-bottom: .8rem;
    font-size: .85rem;
    color: var(--alt-text-sub);
}

.app-systembar a {
    color: inherit;
    text-decoration: none;
}

.app-systembar a:hover {
    color: var(--alt-text-primary);
    text-decoration: underline;
}

/* 絵＋名前（2026-09-06 に【】を外した）。空けたいのは絵と名前のあいだだけ。 */
.app-systembar-module {
    display: inline-flex;
    align-items: center;
    gap: .2rem;
    font-weight: 600;
    color: var(--alt-text-primary);
}

.app-systembar-sep {
    color: var(--alt-text-muted);
}

/* モジュールのタブ（本文の 2 行目・2026-09-06・TEST1-72。実体は Components/Layout/ModuleTabs）。
   2026-09-06 に Pm の .pm-tabs をここへ移して改名した＝タブの見た目を持つ CSS はほかに
   .acct-tab（個人設定）と .wf-tab（申請一覧）があるが、どちらも**同じ画面の中で表を切り替える**もの。
   こちらは**別の画面へ移る**帯なので、4 つ目を作らずシェルの 1 か所に置く。
   折り返しは許す（システムエリアと同じ理由＝項目名は翻訳で伸びる）。 */
.app-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
    border-bottom: 2px solid var(--alt-border);
    margin: 0 0 12px;
}

.app-tab {
    padding: 6px 14px;
    margin-bottom: -2px;
    border-bottom: 2px solid transparent;
    color: var(--alt-text-sub);
    text-decoration: none;
    font-weight: 500;
}

.app-tab:hover {
    color: var(--alt-text-strong);
    border-bottom-color: var(--alt-text-muted);
    text-decoration: none;
}

/* 現在位置の下線だけプロジェクトの色にする（--app-tab-accent はメニューの AccentColor 由来）。
   **文字色には使わない**＝色は自由に選べるので、淡い色を文字に当てると白地で読めなくなる
   （下線は 2px の帯なので淡くても体裁が崩れない）。 */
.app-tab.is-active {
    color: var(--alt-accent);
    border-bottom-color: var(--app-tab-accent, var(--alt-accent));
    font-weight: 600;
}

/* ===== 狭い画面（iPad・スマホ）: ハンバーガーメニュー ===== */

/* 開閉スイッチ本体は常に非表示（label[for] から操作する）。
   display:none にしても label 経由の切り替えと :checked セレクタは効く。 */
.app-nav-toggle {
    display: none;
}

/* ハンバーガーボタン（モバイル上部バーとサイドバーの折りたたみトグルで共用）。 */
.app-nav-button {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border: none;
    background: transparent;
    padding: 0;
    border-radius: var(--alt-radius-md);
    cursor: pointer;
}

.app-nav-button:hover {
    background: var(--alt-bg-secondary);
}

.app-nav-button:focus-visible {
    outline: 2px solid var(--alt-brand);
    outline-offset: 2px;
}

/* ハンバーガーのアイコン（中央の線 ＋ 疑似要素で上下の線）。 */
.app-nav-bars {
    position: relative;
}

.app-nav-bars,
.app-nav-bars::before,
.app-nav-bars::after {
    display: block;
    width: 20px;
    height: 2px;
    border-radius: 1px;
    background: var(--alt-text-primary);
}

.app-nav-bars::before,
.app-nav-bars::after {
    content: "";
    position: absolute;
    left: 0;
}

.app-nav-bars::before {
    top: -6px;
}

.app-nav-bars::after {
    top: 6px;
}

/* 上部バーと背景の膜は広い画面では出さない。 */
.app-mobile-bar,
.app-nav-scrim {
    display: none;
}

@media (max-width: 1024px) {
    .app-shell {
        flex-direction: column;
    }

    /* 画面上部の細いバー。ここのハンバーガーでドロワーを開く。 */
    .app-mobile-bar {
        display: flex;
        align-items: center;
        gap: 10px;
        position: sticky;
        top: 0;
        z-index: 30;
        height: 56px;
        padding: 0 12px;
        box-sizing: border-box;
        background: var(--alt-bg-primary);
        border-bottom: 1px solid var(--alt-border-secondary);
    }

    .app-mobile-title {
        font-size: 15px;
        line-height: 22px;
        font-weight: 700;
        color: var(--alt-text-primary);
    }

    /* サイドバーは画面外に隠したドロワーにする（本文が下に押し出されないようにする）。 */
    .app-sidebar {
        position: fixed;
        top: 0;
        left: 0;
        z-index: 50;
        flex: none;
        width: min(300px, 85vw);
        height: 100vh;
        min-height: 0;
        overflow-y: auto;
        transform: translateX(-100%);
        transition: transform 0.2s ease;
        box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
    }

    /* ドロワー時は幅を固定にするのでつまみは出さない。 */
    .app-sidebar-resizer {
        display: none;
    }

    .app-nav-toggle:checked ~ .app-sidebar {
        transform: translateX(0);
    }

    /* ドロワーを開いている間だけ背後を覆う膜。タップで閉じる。 */
    .app-nav-toggle:checked ~ .app-nav-scrim {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 40;
        background: rgba(0, 0, 0, 0.35);
    }

    /* ドロワー表示中は背後をスクロールさせない（クラス付与は nav-drawer.js）。 */
    body.app-nav-open {
        overflow: hidden;
    }

    .container {
        margin: 1rem 0;
        padding: 0 1rem;
    }

    /* 素のHTMLテーブル（ユーザー管理など）も列を潰さず、横スクロールで見せる。
       DxGrid 側は各列の MinWidth で同じことをしている。 */

    .user-table {
        min-width: 860px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .app-sidebar {
        transition: none;
    }
}

.app-error {
    border: 1px solid var(--alt-danger-border);
    background: var(--alt-danger-bg);
    border-radius: 6px;
    padding: 1rem 1.25rem;
    margin: 1rem 0;
}

.app-error h2 {
    color: var(--alt-danger-strong);
    margin-top: 0;
}

.app-error .app-error-type {
    color: #8a1020;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.85rem;
    margin: 0.25rem 0;
}

.app-error .app-error-message {
    white-space: pre-wrap;
    word-break: break-word;
    background: var(--alt-surface);
    border: 1px solid #efd6d6;
    border-radius: 4px;
    padding: 0.6rem 0.75rem;
    font-size: 0.85rem;
}

.app-error .reload {
    display: inline-block;
    margin-top: 0.5rem;
    color: var(--alt-danger-strong);
}

/* ===== ログイン画面（Figma: WebDemoSystem / Log in） ===== */
.login-page {
    display: flex;
    justify-content: center;
    padding: 96px 1rem 3rem;
}

.login-card {
    width: 360px;
    max-width: 100%;
    display: flex;
    flex-direction: column;
    gap: 32px;
}

.login-header {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    text-align: center;
}

/* Figma から書き出したロゴ（wwwroot/img/alterap-symbol.png）。 */
.login-logo {
    display: inline-block;
    width: 32px;
    height: 32px;
    margin-bottom: 12px;
    border-radius: var(--alt-radius-md);
    background-image: url('img/alterap-symbol.png');
    background-size: contain;
    background-repeat: no-repeat;
}

.login-title {
    margin: 0;
    font-size: 24px;
    line-height: 32px;
    font-weight: 600;
    color: var(--alt-text-primary);
}

.login-subtitle {
    margin: 0;
    font-size: 16px;
    line-height: 24px;
    color: var(--alt-text-tertiary);
}

.login-form {
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.field-label {
    font-size: 14px;
    line-height: 20px;
    font-weight: 500;
    color: var(--alt-text-secondary);
}

.field-input {
    width: 100%;
    box-sizing: border-box;
    padding: 10px 14px;
    border: 1px solid var(--alt-border-primary);
    border-radius: var(--alt-radius-md);
    box-shadow: var(--alt-shadow-xs);
    background: var(--alt-bg-primary);
    font-size: 16px;
    line-height: 24px;
    color: var(--alt-text-primary);
}

.field-input::placeholder {
    color: var(--alt-text-placeholder);
}

.field-input:focus {
    outline: none;
    border-color: var(--alt-brand);
    box-shadow: 0 0 0 3px rgba(29, 78, 216, 0.12);
}

.field-error {
    color: var(--alt-danger-strong);
    font-size: 13px;
}

.login-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.login-remember {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 14px;
    line-height: 20px;
    font-weight: 500;
    color: var(--alt-text-secondary);
    cursor: pointer;
}

.login-checkbox {
    width: 16px;
    height: 16px;
    accent-color: var(--alt-brand);
}

.login-submit {
    width: 100%;
    padding: 10px 16px;
    border: none;
    border-radius: var(--alt-radius-md);
    background: var(--alt-brand);
    color: var(--alt-on-accent);
    font-size: 16px;
    line-height: 24px;
    font-weight: 600;
    box-shadow: var(--alt-shadow-xs);
    cursor: pointer;
}

.login-submit:hover {
    background: var(--alt-accent-hover);
}

.login-error {
    color: var(--alt-danger-strong);
    background: var(--alt-danger-bg);
    border: 1px solid var(--alt-danger-border);
    border-radius: 4px;
    padding: 0.5rem 0.75rem;
    font-size: 0.9rem;
}

/* ユーザー管理 */

.user-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.92rem;
}

.user-table th,
.user-table td {
    border-bottom: 1px solid var(--alt-border);
    padding: 0.5rem 0.6rem;
    text-align: left;
    vertical-align: middle;
}

.user-table th {
    color: var(--alt-text-strong);
    font-weight: 600;
}

.user-table tr.row-inactive {
    color: var(--alt-text-muted);
    background: var(--alt-bg-subtle);
}

.user-table .muted {
    color: var(--alt-text-muted);
}

/* フィルタパネル（適用中の条件の表示）をグリッドの一番上に出す。

   DevExpress にパネル位置の設定が無いため、flex の order で並べ替えている。

   グリッド直下の子要素は実機で確認済み（上からの順）:
     dxbl-display-none ×3 / dxbl-grid-top-panel / dxbl-scroll-viewer
     / dxbl-grid-bottom-panel dxbl-pager-container / dxbl-grid-filter-panel
   つまりフィルタパネルは末尾の直下の子なので、order だけで先頭に移せる。

   **DevExpress の内部クラス名に依存する**ため、バージョンアップで効かなくなる可能性がある
   （効かない場合はパネルが従来どおり下に出るだけで、壊れはしない）。
   確認方法はブラウザのコンソールで:
     [...document.querySelector('.alt-grid').children].map(c => c.className)

   元に戻したい場合はこのブロックを削除すればよい。 */
.alt-grid {
    display: flex;
    flex-direction: column;
}

.alt-grid > .dxbl-grid-filter-panel {
    order: -1;
}

/* 一覧上のツールバー（フィルター作成、フィルター切替、表示リセット）。 */
/* 一覧の上に置くボタンの帯。**左に寄せる**（2026-09-06）＝右端に飛ばすと、表の左上から
   目を動かした先に何も無く、押すものを画面の端まで探しに行くことになる。
   フィルターの帯（`GridToolbar`）はこの下に来るので、押すものが左の縦一列に並ぶ。 */
.grid-toolbar {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-start;
    gap: 0.5rem;
    margin: 0.5rem 0;
}

/* ---- サイドメニューの表示モード切替（デスクトップ） ----
   サイドバー上部のハンバーガー（.app-navmode-toggle）で
   「アイコンリストバー ⇄ ツリー表示」を切り替える（2026-08-07 ユーザー要望）。
   実体は幅の切替え（アイコン=64px / ツリー=直前の幅）で、処理は sidebar-resize.js。

   旧仕様の「サイドバーごと隠す折りたたみ」（html.app-nav-collapsed ＋左上の再表示ボタン）は
   アイコンリストバーが上位互換のため廃止した（関連の CSS/JS/マークアップも削除済み）。
   モバイル(≤1024px)は従来どおり上部バーのハンバーガーからドロワーを開く。 */
@media (max-width: 1024px) {
    .app-brand .app-navmode-toggle {
        display: none;
    }
}

/* ---- アイコンリストバー（2026-08-07 ユーザー要望） ----
   サイドバーを最小幅(200px)より狭くすると sidebar-resize.js が幅を 64px にスナップさせ、
   <html> に app-nav-icons を付ける。ここではその状態の見た目を定義する。
   DxTreeView（.app-tree）を細くするのではなく、専用の .app-iconbar に差し替える
   （DevExpress 内部の DOM に依存せず、幅が確実に収まるため）。
   幅を戻すにはつまみを右へドラッグ、またはつまみをダブルクリック（既定220px）。 */

/* 通常幅のときはアイコンバーを出さない。 */
.app-iconbar {
    display: none;
}

/* アイコンモードはデスクトップ専用。狭い画面(≦1024px)ではサイドバーが幅固定のドロワーなので、
   localStorage にアイコン幅が残っていても従来のツリーを出す（折りたたみと同じ方針）。 */
@media (min-width: 1025px) {
    html.app-nav-icons .app-tree {
        display: none;
    }

    /* アイコンモードのときだけサイドバーを本文と一緒に伸ばす（画面の高さに固定しない）。
       アイコンバーは下のとおり overflow を持てない＝中でスクロールできないので、
       高さを固定すると溢れたアイコンに手が届かなくなる（ツリー表示は .app-tree の中でスクロールする）。 */
    html.app-nav-icons .app-sidebar {
        height: auto;
        min-height: 100vh;
    }

    html.app-nav-icons .app-iconbar {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 2px;
        padding: 0 4px;
        /* フローティングメニューが切り取られないよう overflow は付けない。
           グループ化したのでアイコンは数個しかなく、スクロールは不要。 */
    }
}

.app-iconbar-item {
    position: relative; /* 右上に重ねるバッジ（.todo-nav-badge）の基準 */
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    flex: none;
    border: none;
    padding: 0;
    background: none;
    border-radius: var(--alt-radius-sm);
    text-decoration: none;
    color: inherit;
    cursor: pointer;
}

.app-iconbar-item:hover {
    background: var(--alt-bg-secondary);
}

/* フローティングメニューを開いているグループは押下状態に見せる。 */
.app-iconbar-item.is-open {
    background: var(--alt-bg-secondary);
    box-shadow: inset 0 0 0 1px var(--alt-border-primary);
}

/* アーカイブ済のお気に入りはツリー同様に淡く表示する。 */
.app-iconbar-item.is-archived .alt-ico {
    opacity: 0.45;
}

/* ---- TODOメニューの期限超過バッジ（2026-08-11 ユーザー要望) ----
   ツリー側は DevExpress の BadgeText（.dxbl-badge。TreeView は --dxbl-treeview-badge-* 変数で描画。
   テーマ既定は色が未定義＝透明なので、ここで赤ピルにする）、
   アイコンバー側は自前の .todo-nav-badge をアイコン右上に重ねる（狭幅時のベルバッジと同じ手法）。
   注意: themes.css の濃色サイドバーは dxbl-* の背景を !important で透明化するため、
   そちらは :not(.dxbl-badge) でバッジを除外している。 */
.app-tree .dxbl-badge {
    --dxbl-treeview-badge-bg: var(--alt-danger);
    --dxbl-treeview-badge-color: var(--alt-on-accent);
    --dxbl-treeview-badge-border-radius: 10px;
    --dxbl-treeview-badge-font-weight: 700;
    --dxbl-treeview-badge-font-size: 0.72rem;
}

.todo-nav-badge {
    position: absolute;
    top: 2px;
    right: 2px;
    background: var(--alt-danger);
    color: var(--alt-on-accent);
    border-radius: 10px;
    font-size: 0.65rem;
    font-weight: 700;
    line-height: 1.5;
    padding: 0 5px;
}

/* ---- フローティングメニュー（2026-08-07 ユーザー要望） ----
   アイコンバーのグループを押すと、そのアイコンの右横にメニューを出す。
   位置はグループ（position:relative）基準の absolute なので JS 不要。
   外側を押したときは透明の膜(.app-flyout-scrim)で閉じる。 */
/* フライアウトを本文より手前に出すための重なり順（2026-08-07 不具合修正）。

   position:sticky の .app-sidebar はそれ自体がスタッキングコンテキストを作るため、
   中の z-index をいくら上げても .app-body 側の位置指定要素（DevExpress グリッドの
   sticky ヘッダー等。DOM 順で後ろ）に負けてメニューが一覧の下に隔れていた。
   → サイドバー自体を持ち上げて解決する（下の html.app-nav-icons .app-sidebar）。

   膜(.app-flyout-scrim)=55 ＜ アイコンバー=58 ＜ フライアウト=60 の順。
   アイコンバーを膜より上にすることで、メニューを開いたまま別のグループを直接押せる。 */
.app-iconbar {
    position: relative;
    z-index: 58;
}

.app-iconbar-group {
    position: relative;
    display: flex;
    justify-content: center;
    width: 100%;
}

.app-flyout {
    position: absolute;
    left: calc(100% + 6px);
    top: 0;
    z-index: 60;
    min-width: 190px;
    max-width: 280px;
    max-height: 76vh;
    overflow-y: auto;
    padding: 8px;
    background: var(--alt-bg-primary);
    border: 1px solid var(--alt-border-secondary);
    border-radius: var(--alt-radius-md);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.14);
}

.app-flyout-head {
    padding: 2px 8px 6px;
    font-size: 0.78rem;
    font-weight: 700;
    color: var(--alt-text-tertiary);
}

/* 見出しの氏名を個人設定へのリンクにした（2026-08-11）。見た目は見出しのまま、
   押せることが分かるようホバーで項目と同じ強調を付ける。 */
a.app-flyout-head-link {
    display: block;
    text-decoration: none;
    cursor: pointer;
}

a.app-flyout-head-link:hover {
    background: var(--alt-accent-soft);
    color: var(--alt-text-secondary-hover);
    border-radius: var(--alt-radius-sm);
}

.app-flyout-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    border-radius: var(--alt-radius-sm);
    color: var(--alt-text-secondary);
    text-decoration: none;
    font-size: 0.85rem;
    white-space: nowrap;
}

/* フローティングメニューの第2階層以降（プロジェクト配下・機能設定のモジュール配下）。
   ツリーと違って開閉が無いので、インデントだけで親子を見せる。 */
.app-flyout-sub {
    padding-left: 24px;
}

/* 画像アイコン（NavMenuItem.IconUrl。Pm のプロジェクトアイコン）。
   .alt-ico-sm と同じ 16px に揃え、縦横比の違う画像でも崩れないよう cover で切り抜く。 */
.app-flyout-ico {
    flex: none;
    width: 16px;
    height: 16px;
    border-radius: 4px;
    object-fit: cover;
    background: var(--alt-bg-secondary);
}

/* 遷移先を持たない見出し（機能設定のモジュール名）。押せないので反応も出さない（色はグループ見出しに合わせる）。 */
.app-flyout-subhead {
    color: var(--alt-text-tertiary);
    font-weight: 700;
    cursor: default;
}

.app-flyout-item:hover {
    background: var(--alt-bg-secondary);
    color: var(--alt-text-secondary-hover);
}

/* お気に入りの各機能（ボード・ガント等）は一段下げる。 */

.app-flyout-item.is-archived .alt-ico {
    opacity: 0.45;
}

/* プロジェクトごとの区切り。 */

/* 外側クリックを拾う透明の膜（メニューの下・本文の上）。 */
.app-flyout-scrim {
    position: fixed;
    inset: 0;
    z-index: 55;
    background: transparent;
}

/* アイコンモードでは文字が入らないので、ブランド名・ロゴを隠す。
   ハンバーガー（表示モード切替 .app-navmode-toggle）だけ残して中央に置く。
   これでアイコンモードからもワンタップでツリー表示に戻せる。

   Phase7（2026-08-07）: サイドバー下部の自分のアイコンはアイコンモードでも常駐させる。
   以前は「フッターごと隠す」割り切りだったため、アイコンモードからは
   パスワード変更・2段階認証・ログアウトに到達できなかった。
   アイコン1つ＋ポップアップに集約したことで、両モードで同じ導線が使える。 */
@media (min-width: 1025px) {
    html.app-nav-icons .app-brand {
        justify-content: center;
        padding: 0 4px;
        gap: 0;
        margin-bottom: 12px;
    }

    html.app-nav-icons .app-brand a,
    html.app-nav-icons .app-brand-logo {
        display: none;
    }

    /* アイコンモードのアカウント: アイコンだけを中央に置き、名前とロールは隠す。
       ポップアップは（幅64pxに収まらないので）右横へ出す。 */
    html.app-nav-icons .app-sidebar-account {
        padding: 0 4px;
        align-items: center;
    }

    html.app-nav-icons .app-account-btn {
        width: 40px;
        height: 40px;
        justify-content: center;
        padding: 0;
        gap: 0;
        border: none;
        border-radius: var(--alt-radius-sm);
    }

    html.app-nav-icons .app-account-text {
        display: none;
    }

    html.app-nav-icons .app-account-pop {
        left: calc(100% + 6px);
        top: 0;
    }

}

/* ==== メッセージ表示の共通スタイル（2026-08-11 ユーザー決定） ====
   各処理でメッセージを表示するときは、必ず次の3種の枠を使う:
     ・情報・完了報告          → <div class="form-info">  （青枠）
     ・バリデーション・エラー  → <div class="form-error"> （赤枠）
     ・警告（続行はできる注意）→ <div class="form-warn">  （黄枠）
   色はテーマのトークン／color-mix で作るので、ダーク・ピンクテーマにも追従する。

   枠を張れない場所（グリッドのセル・表の中・文の途中）に断りを出すときだけ、
   面を持たない <span class="form-error-inline"> を使う（下記）。 */

.form-info {
    margin: 0.4rem 0;
    padding: 0.5rem 0.8rem;
    border: 1px solid color-mix(in srgb, var(--alt-accent) 40%, transparent);
    border-radius: var(--alt-radius-sm);
    background: var(--alt-accent-soft);
    color: var(--alt-accent-hover);
    font-size: 0.9rem;
}


.form-error {
    margin: 0.4rem 0;
    padding: 0.5rem 0.8rem;
    border: 1px solid var(--alt-danger-border);
    border-radius: var(--alt-radius-sm);
    background: var(--alt-danger-bg);
    color: var(--alt-danger-text);
    font-size: 0.9rem;
}

.form-warn {
    margin: 0.4rem 0;
    padding: 0.5rem 0.8rem;
    border: 1px solid color-mix(in srgb, #f9a825 50%, transparent);
    border-radius: var(--alt-radius-sm);
    background: color-mix(in srgb, #f9a825 14%, var(--alt-surface));
    color: color-mix(in srgb, #7a5200 75%, var(--alt-text-primary));
    font-size: 0.9rem;
}

/* 上の 3 種の「枠なし行内版」。面も余白も持たないので、グリッドのセル・表のセル・文の途中に置ける。
   **大きさは持たず、置かれた場所の文字に合わせる**＝グリッドのセルに 0.85rem を持ち込むと
   そのセルだけ行が伸びる（`SizeMode.Small` で 24px → 27px。2026-09-08 実測）。
   入力欄の直下に出す検証メッセージは .field-error（入力欄のスタイル群にある。あちらは独立した行なので
   大きさを持ってよい）。 */
.form-error-inline {
    color: var(--alt-danger-strong);
}

/* ポップアップ内の中身（自前ラッパー）は画面の高さを超えたらスクロールさせる。
   フォームは A4 の紙面に収まる幅で止める＝目が左右に振られず、印刷したときの見当も付く
   （ポップアップの中身も同じクラスだが、ポップアップの幅はこれより狭いので何も変わらない）。
   **上限は --alt-form-max**（2026-09-05・TEST1-61。もとは 820px）＝入力の欄はダイアログでも
   ページ直置きでも同じ幅で止める、という指定なので、値は 1 か所（:root）に置いて
   .alt-form-grid と共有する。

   **これは「自前ラッパーを画面の高さで切る」もので、窓そのものの本文には効かない**
   （2026-09-07・TEST1-89）＝`DxPopup` に `Height` を持たせた窓の中だけをスクロールさせたいときは、
   `BodyCssClass` で本文に名前を付けて当てる（docs/claude/pitfalls.md の DxPopup の項）。
   ここの 74vh は窓の高さと無関係なので、そちらに使うと窓の外にはみ出したまま効かない。 */
.dialog-form,
.app-popup-scroll {
    max-height: 74vh;
    overflow: auto;
}

.dialog-form { max-width: var(--alt-form-max); }

/* ===== 入力の幅（全画面共通。2026-08-26） =====
   **入力は値にふさわしい大きさで止める**。列や画面いっぱいに伸ばすと、2 文字を選ぶだけの項目でも
   ドロップダウンのボタンが画面の端まで離れ、1 つ選ぶのに目と手が画面を横切ることになる。
   効かせるのは DevExpress のテキスト系エディタだけ＝テキスト・数値・日付・コンボはどれも
   .dxbl-text-edit を持つ（実測）。チェックボックス（.dxbl-checkbox）には触らない。
   長い文が入るメモ（.dxbl-memo-edit）と、名前がいくつも並ぶタグ入力（.dxbl-tag-box）は除く＝
   狭めると折り返しが増えるだけで読みにくくなる。
   **2 列ぶち抜き（alt-span2）の項目は対象にしない**＝住所・備考・説明のように、そこを選んだ時点で
   作者が「広く取る」と決めているもの。ここまで狭めると、いまより読みにくい画面ができてしまう。
   **既定は :where() で包んで詳細度を 0 にしてある**＝下の alt-w-* も、画面ごとの指定も、
   読み込み順に関係なく必ず勝つ。ここを普通のセレクタで書くと、細かく決めた個別の幅が
   黙って既定に上書きされる（例外もログも出ず、見た目だけで表に出る）。 */
:where(.dialog-form, .alt-form-grid > div:not(.alt-span2)) > :where(.dxbl-text-edit:not(.dxbl-memo-edit):not(.dxbl-tag-box)) {
    max-width: 360px;
}

/* 値の性質で選ぶ幅。既定より狭めたい・広げたいものに付ける（どれを何にするかは各画面の doc が正）。 */
.alt-w-sm { max-width: 150px; }    /* 日付・時間・数量＝桁数が決まっている */
.alt-w-md { max-width: 220px; }    /* 区分・状態＝短い語を選ぶ */
.alt-w-lg { max-width: 320px; }    /* 氏名・マスタの名称が入る */
.alt-w-full { max-width: none; }   /* 件名・住所・URL＝長さが決まらないので止めない */


/* ダイアログの縦積みフォーム（ラベル＋入力を1列に並べる） */
.dialog-form > label {
    display: block;
    margin-top: 0.6rem;
    margin-bottom: 0.2rem;
    font-size: 0.85rem;
    color: var(--alt-text-sub);
}
.dialog-form > label:first-child { margin-top: 0; }

/* 読み上げ専用テキスト（アイコンだけのボタンのラベル用）。 */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* ===== 2段階認証（Phase7） ===== */

/* コード入力画面下部の入力方法切替リンク */
.login-2fa-links {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: 16px;
    font-size: 0.85rem;
}

.login-2fa-links a {
    color: var(--alt-brand);
    text-decoration: none;
}

.login-2fa-links a:hover {
    text-decoration: underline;
}

/* 副ボタン（メールコード送信など） */

/* 設定画面: QRコードと手入力用キー */
.twofa-qr {
    display: block;
    width: 180px;
    height: 180px;
    margin: 8px auto;
    image-rendering: pixelated;
}

.twofa-key {
    display: block;
    text-align: center;
    font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
    font-size: 0.85rem;
    letter-spacing: 0.06em;
    background: var(--alt-bg-secondary);
    border: 1px solid var(--alt-border-secondary);
    border-radius: var(--alt-radius-sm);
    padding: 6px 8px;
    margin: 4px 0 10px;
    word-break: break-all;
    user-select: all;
}

/* リカバリーコード一覧（表示は有効化直後・再生成時の1回のみ） */
.twofa-codes {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4px 16px;
    list-style: none;
    font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
    background: var(--alt-bg-secondary);
    border: 1px solid var(--alt-border-secondary);
    border-radius: var(--alt-radius-sm);
    padding: 10px 14px;
    margin: 8px 0;
}

.twofa-note {
    font-size: 0.82rem;
    color: var(--alt-text-tertiary);
    margin: 4px 0 10px;
}

.twofa-status {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 999px;
    font-size: 0.82rem;
    font-weight: 600;
}

.twofa-status-on {
    background: #dcfce7;
    color: var(--alt-success-text);
}

.twofa-status-off {
    background: var(--alt-danger-bg);
    color: #991b1b;
}

/* 設定画面の操作ボタン群（有効時） */
.twofa-actions {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 12px;
}

/* ===== ユーザーアイコン（アバター）と個人設定（Phase7。2026-08-07 ユーザー要望） ===== */

/* アイコン本体。画像は /user-icons/{userId} が返す（未登録なら頭文字のSVG）。
   縦横比の違う画像でも崩れないよう cover で切り抜く。 */
.app-avatar {
    display: inline-block;
    flex: none;
    object-fit: cover;
    background: var(--alt-bg-secondary);
    vertical-align: middle;
}

.app-avatar {
    border-radius: 50%;
}

/* UserId が分からない場合のイニシャル表示（画像リクエストを出さない版）。 */
.app-avatar-initial {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--alt-on-accent);
    font-weight: 600;
    line-height: 1;
}

/* 担当者名・タイムラインの投稿者名などに小さく添えるとき。 */

/* ---- 個人設定画面 /account/settings ---- */

.acct-header {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 12px 16px;
    margin-bottom: 16px;
    border: 1px solid var(--alt-border-secondary);
    border-radius: var(--alt-radius-xl);
}

.acct-header-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1;
}

.acct-header-name {
    font-size: 1rem;
    font-weight: 700;
    color: var(--alt-text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
}

.acct-header-meta {
    font-size: 0.82rem;
    color: var(--alt-text-tertiary);
    word-break: break-all;
}

.acct-logout-form {
    margin: 0;
    flex: none;
}

.acct-logout {
    padding: 8px 16px;
    border: 1px solid var(--alt-border-primary);
    border-radius: var(--alt-radius-md);
    background: var(--alt-bg-secondary);
    color: var(--alt-text-secondary);
    font-size: 0.88rem;
    font-weight: 600;
    cursor: pointer;
}

.acct-logout:hover {
    background: var(--alt-bg-page);
}

/* タブ（querystring で切り替えるので、実体はただのリンク） */
.acct-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    border-bottom: 1px solid var(--alt-border-secondary);
    margin-bottom: 16px;
}

.acct-tab {
    padding: 8px 14px;
    border: 1px solid transparent;
    border-bottom: none;
    border-radius: var(--alt-radius-sm) var(--alt-radius-sm) 0 0;
    color: var(--alt-text-secondary);
    text-decoration: none;
    font-size: 0.9rem;
    font-weight: 600;
    margin-bottom: -1px;
}

.acct-tab:hover {
    background: var(--alt-bg-secondary);
}

.acct-tab.is-active {
    background: var(--alt-bg-primary);
    border-color: var(--alt-border-secondary);
    color: var(--alt-brand);
}

.acct-panel {
    max-width: 720px;
}

.acct-section {
    max-width: 720px;
    margin-bottom: 24px;
}

.acct-section-title {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 1.05rem;
    font-weight: 700;
    margin: 0 0 12px;
}

.acct-sub-title {
    font-size: 0.95rem;
    font-weight: 700;
    margin: 12px 0 6px;
}

.acct-form {
    display: flex;
    flex-direction: column;
    gap: 12px;
    max-width: 420px;
}

.acct-submit {
    align-self: flex-start;
    padding: 9px 20px;
    border: none;
    border-radius: var(--alt-radius-md);
    background: var(--alt-brand);
    color: var(--alt-on-accent);
    font-size: 0.92rem;
    font-weight: 600;
    box-shadow: var(--alt-shadow-xs);
    cursor: pointer;
}

.acct-submit:hover {
    background: var(--alt-accent-hover);
}

.acct-submit-secondary {
    background: var(--alt-bg-secondary);
    color: var(--alt-text-secondary);
    border: 1px solid var(--alt-border-primary);
}

.acct-submit-secondary:hover {
    background: var(--alt-bg-page);
}

.acct-status {
    color: var(--alt-success-text);
    background: #f0fdf4;
    border: 1px solid #bbf7d0;
    border-radius: var(--alt-radius-sm);
    padding: 6px 10px;
    font-size: 0.86rem;
    margin: 0 0 10px;
}

.acct-error {
    color: var(--alt-danger-strong);
    background: var(--alt-danger-bg);
    border: 1px solid var(--alt-danger-border);
    border-radius: var(--alt-radius-sm);
    padding: 6px 10px;
    font-size: 0.86rem;
    margin: 0 0 10px;
}

.acct-hint {
    font-size: 0.8rem;
    color: var(--alt-text-tertiary);
    margin: 4px 0 0;
}

/* 入力できないカスタム項目の値（2026-08-30。フォームの式の列）。**入力欄と同じ高さに置く**＝
   ほかの項目と行がずれると、打てないことより先に「壊れている」と読まれる。
   点線にしているのは、空の入力欄との見分けが枠線の種類だけで付くため。 */
.alt-readonly-value {
    margin: 0;
    padding: .35rem .5rem;
    min-height: 2.25rem;
    border: 1px dashed var(--alt-border);
    border-radius: 6px;
    background: transparent;
}

/* 縦に並ぶ入力欄のあいだに置く「OR」の区切り（2026-08-28。機能権限の設定ダイアログ）。
   欄が上下に並ぶだけだと全部埋めないと成立しないように読めるので、
   どれか 1 つでよいことを欄と欄のあいだで伝える。文字は resx から渡す。 */
.alt-or-sep {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 12px 0 2px;
    color: var(--alt-text-tertiary);
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.08em;
}

.alt-or-sep::before,
.alt-or-sep::after {
    content: "";
    flex: 1 1 auto;
    height: 1px;
    background: var(--alt-border);
}

.acct-readonly {
    margin: 0;
    padding: 8px 0;
    font-size: 0.92rem;
    color: var(--alt-text-secondary);
    word-break: break-all;
}

/* プロフィールタブのアイコン欄 */
.acct-avatar {
    display: flex;
    align-items: flex-start;
    gap: 20px;
    margin-bottom: 20px;
}

.acct-avatar-img {
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
}

.acct-avatar-ops {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
    min-width: 0;
}

.acct-file input[type="file"] {
    font-size: 0.85rem;
}

/* メール通知タブ */

@media (max-width: 640px) {
    .acct-header {
        flex-wrap: wrap;
    }

    .acct-avatar {
        flex-direction: column;
    }
}

/* サイドバー常駐アカウントのアイコン（AccountMenu）。押せることが分かるよう薄い枠を付ける。 */
.app-account-avatar {
    box-shadow: 0 0 0 1px var(--alt-border-secondary);
}

/* ===== 個人設定「テーマ」タブ（2026-08-10） ===== */
.theme-pick {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    margin: 12px 0 18px;
}

.theme-card {
    display: flex;
    flex-direction: column;
    gap: 6px;
    width: 200px;
    padding: 12px;
    border: 2px solid var(--alt-border);
    border-radius: var(--alt-radius-md);
    background: var(--alt-surface);
    cursor: pointer;
}

.theme-card:hover {
    border-color: var(--alt-border-strong);
}

/* 選択中のカード。SSR タブなので JS ではなく :has() で追随させる（クリックで即時にハイライトが移る） */
.theme-card:has(input[type="radio"]:checked) {
    border-color: var(--alt-accent);
    background: var(--alt-accent-soft);
}

/* キーボード操作（矢印キーで選択）でも位置がわかるように */
.theme-card:focus-within {
    outline: 2px solid var(--alt-accent);
    outline-offset: 2px;
}

/* ラジオ本体は隠す（カード全体がラベル） */
.theme-card input[type="radio"] {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.theme-card-name {
    font-weight: 700;
    color: var(--alt-text-strong);
}

.theme-card-desc {
    font-size: 0.8rem;
    color: var(--alt-text-sub);
}

/* CSSだけで描くミニプレビュー。テーマごとの色は下で直接指定する
   （選択前にそのテーマの見た目を示すためトークンは使わない） */
.theme-thumb {
    display: flex;
    height: 72px;
    border-radius: var(--alt-radius-sm);
    border: 1px solid var(--alt-border);
    overflow: hidden;
}

.theme-thumb-side { width: 26%; }

.theme-thumb-main {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 8px;
}

.theme-thumb-bar { height: 8px; width: 60%; border-radius: 3px; }
.theme-thumb-card { flex: 1; border-radius: 4px; }

.theme-thumb-light { background: #f4f6f9; }
.theme-thumb-light .theme-thumb-side { background: #ffffff; border-right: 1px solid #e3e8ef; }
.theme-thumb-light .theme-thumb-bar { background: #2c6fd9; }
.theme-thumb-light .theme-thumb-card { background: #ffffff; border: 1px solid #e3e8ef; }

.theme-thumb-dark { background: #1e232c; }
.theme-thumb-dark .theme-thumb-side { background: #1b202a; border-right: 1px solid #343d4d; }
.theme-thumb-dark .theme-thumb-bar { background: #5a8fe8; }
.theme-thumb-dark .theme-thumb-card { background: #232935; border: 1px solid #343d4d; }

.theme-thumb-navy { background: #f4f6f9; }
.theme-thumb-navy .theme-thumb-side { background: #12294d; }
.theme-thumb-navy .theme-thumb-bar { background: #2c6fd9; }
.theme-thumb-navy .theme-thumb-card { background: #ffffff; border: 1px solid #e3e8ef; }

.theme-thumb-pink { background: #faf3f7; }
.theme-thumb-pink .theme-thumb-side { background: #fdf4f8; border-right: 1px solid #f0dbe7; }
.theme-thumb-pink .theme-thumb-bar { background: #d6478f; }
.theme-thumb-pink .theme-thumb-card { background: #ffffff; border: 1px solid #f0dbe7; }

/* サイドバーのカスタム配色（テーマタブ内。2026-08-10） */
.theme-side {
    margin: 4px 0 18px;
    padding: 12px;
    border: 1px solid var(--alt-border);
    border-radius: var(--alt-radius-md);
    background: var(--alt-bg-subtle);
}

.theme-side-check {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-right: 12px;
    font-weight: 600;
    color: var(--alt-text-strong);
    cursor: pointer;
}

.theme-side-color {
    width: 48px;
    height: 28px;
    padding: 0;
    border: 1px solid var(--alt-border-strong);
    border-radius: var(--alt-radius-sm);
    background: var(--alt-surface);
    vertical-align: middle;
    cursor: pointer;
}

/* ===== Culminans シェル追加分（chaser には無い、または既定に頼っていた小物） ===== */

/* 補足説明の小さな文字（一覧の注記など） */
.meta {
    color: var(--alt-text-sub);
    font-size: 0.85rem;
}

/* 件数・合否を短く言うピル（取り込みの下見の件数・機能権限のモード・IP 制限の状態）。
   形は重要度バッジ（.alt-annc-level）と同じだが、**規則は共有しない**＝あちらの 3 段は
   重要度（is-info / is-warning / is-critical）、こちらは合否（is-success / is-danger / is-warning）で、
   名前が重なるのは is-warning だけ。まとめると片方の段を足した日にもう片方に無い色が生える。
   色は状態トークンなので、テーマ（dark / navy / pink）に自動で追従する。

   **グリッドのセルにも入る**（FormImport・AdminPermissions の状態列）ので、
   **外形の高さを 15px に収める**（`line-height` を詰め、上下の padding を持たない）。
   DevExpress のセルは行内でいちばん背の高いものに合わせて伸びるので、ここを 21.8px にすると
   **バッジのある行だけ 24px → 30.8px** になる（`SizeMode.Small` で実測。2026-09-08）。
   `vertical-align` では直らない＝インラインボックスの高さがそのまま行の高さを決めるため。 */
.alt-badge {
    display: inline-block;
    font-size: 0.74rem;
    font-weight: 700;
    line-height: 1.1;
    padding: 0 8px;
    border-radius: 10px;
    white-space: nowrap;
    background: var(--alt-bg-muted);
    color: var(--alt-text-sub);
    border: 1px solid var(--alt-border);
}

.alt-badge.is-success { background: var(--alt-success-bg); color: var(--alt-success-text); border-color: var(--alt-success-border); }
.alt-badge.is-danger  { background: var(--alt-danger-bg);  color: var(--alt-danger-text);  border-color: var(--alt-danger-border); }
.alt-badge.is-warning { background: var(--alt-warning-bg); color: var(--alt-warning-text); border-color: var(--alt-warning-border); }

/* ダイアログ下部のボタン列（保存／キャンセル） */
.dialog-buttons {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    margin-top: 1rem;
}

/* 「続けて登録」が通ったことをダイアログの中に出す文（操作列の左端）。
   画面上部のバナーは開いたままの窓に隠れて読めないので、押したボタンの隣に置く。 */
.dialog-buttons-info {
    margin-right: auto;
    align-self: center;
    color: var(--alt-accent-hover);
    font-size: 0.85rem;
}

/* Ctrl/Command + Enter で押されるボタンの印（.alt-submit ／ Shift つきは .alt-submit-continue）。
   **見た目は持たないので規則も無い**＝どのボタンが主かは RenderStyle が示しており、
   これは js/submit-shortcut.js だけが読む目印。**規約と理由はその冒頭の doc が正**。 */

/* ESC で押される「一覧へ戻る」ボタンの印（.alt-esc-back）。上と同じく**見た目は持たない**
   ＝付けるのは自前の確認（未保存の破棄）を持つ画面だけで、付けなければシェルが聞いて一覧へ戻す。
   **付けてよいのは本文に出るボタンだけ**（窓の中には置かない）。
   **規約と理由は js/esc-back.js の冒頭の doc が正**。 */

/* フローティングメニュー内の件数バッジ（項目文字の右に添える） */
.app-flyout-badge {
    margin-left: auto;
    padding: 0 6px;
    border-radius: 999px;
    background: var(--alt-danger);
    color: var(--alt-on-accent);
    font-size: 0.7rem;
    line-height: 1.5;
}

/* ダッシュボードのモジュール一覧 */
.home-modules {
    max-width: 640px;
}
.home-modules code {
    font-size: 0.85em;
}

/* ===== 表示言語の切替（CultureSwitcher。ログイン画面下部・個人設定「言語」タブ） ===== */
.lang-switch {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0;
}

.lang-switch-item {
    appearance: none;
    border: 1px solid var(--alt-border-strong);
    border-radius: 999px;
    background: var(--alt-surface);
    color: var(--alt-text-secondary);
    padding: 4px 14px;
    font: inherit;
    font-size: 0.85rem;
    line-height: 1.5;
    cursor: pointer;
}

.lang-switch-item:hover {
    background: var(--alt-bg-muted);
    color: var(--alt-text-primary);
}

.lang-switch-item.is-current {
    background: var(--alt-accent);
    border-color: var(--alt-accent);
    color: var(--alt-on-accent);
    cursor: default;
}

/* ログイン画面: カード下部に中央寄せで小さく */
.login-lang {
    justify-content: center;
    margin-top: 1.25rem;
}

/* 個人設定「言語」タブ: 少し大きめのボタン */
.lang-switch-cards .lang-switch-item {
    padding: 8px 22px;
    font-size: 0.95rem;
}

/* ===== 組織管理（/admin/organization）・ユーザー管理の所属欄 ===== */
.org-sample-card {
    border: 1px solid var(--alt-border);
    border-radius: var(--alt-radius-md);
    background: var(--alt-bg-subtle);
    padding: 1rem 1.25rem;
    margin: 0.5rem 0 1.25rem;
    max-width: 640px;
}
.org-sample-title {
    margin: 0 0 0.5rem;
    font-size: 1.05rem;
}

/* ユーザー編集ダイアログの所属一覧 */
.app-userorg { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.app-userorg td { border-top: 1px solid var(--alt-border); padding: 4px 8px 4px 0; vertical-align: middle; }
.app-userorg td.name { width: 45%; }

/* 役職などの短い選択コンボ */
.app-status-select { width: 160px; }
.member-select { width: 260px; }

@media (max-width: 900px) {
    .dialog-form .app-status-select,
    .dialog-form .member-select,
    .grid-toolbar .member-select {
        width: 100% !important;
        max-width: 100%;
    }
    .app-userorg td.name { width: auto; }
    .app-userorg td { display: block; border-top: none; padding: 2px 0; }
    .app-userorg tr { display: block; border-top: 1px solid var(--alt-border); padding: 6px 0; }
}

/* ===== お知らせベル（サイドバー）とお知らせ一覧（chaser から移植） ===== */
.app-bell {
    display: flex; align-items: center; gap: 8px; position: relative;
    padding: 8px 14px; margin: 0 8px 4px; border-radius: 6px;
    color: var(--alt-text-secondary); text-decoration: none; font-size: 0.9rem;
}
.app-bell:hover { background: var(--alt-bg-secondary); color: var(--alt-text-secondary-hover); }
.app-bell-badge {
    background: var(--alt-danger); color: var(--alt-on-accent); border-radius: 10px;
    font-size: 0.72rem; font-weight: 700; padding: 1px 7px; margin-left: auto;
}

/* アイコンモードではベルはアイコンだけにし、未読バッジは右上に重ねる。 */
@media (min-width: 1025px) {
    html.app-nav-icons .app-bell { justify-content: center; padding: 8px 0; margin: 0 4px 6px; }
    html.app-nav-icons .app-bell-label { display: none; }
    html.app-nav-icons .app-bell-badge { position: absolute; top: 2px; right: 6px; margin-left: 0; padding: 0 5px; font-size: 0.65rem; }
}

/* 狭い画面では上部バーの右端にもベルを出す（TEST1-90）。
   **サイドバーの中だけに置いておけない**＝狭い画面のサイドバーはドロワーで、閉じているあいだは
   `translateX(-100%)` で画面外にある。未読バッジが見えるのはメニューを開いたときだけになり、
   シフトの欠員の知らせ（朝の稼働直前に部署の担当者へ飛ぶ）に気づけない。

   **サイドバー側のベルは消さない**＝ドロワーを開いているあいだは覆いの膜（.app-nav-scrim・z-index 40）が
   上部バー（z-index 30）を覆うので、2 つが同時に押せる状態にはならない。消すと「お知らせ」の行が
   画面幅によってメニューから消えることになり、メニューの中身が広い画面と食い違う。

   **1 つの部品を 2 か所へ出すことはできない**＝`transform` を持つ祖先はその子孫の `position: fixed` の
   包含ブロックになるので、ドロワーの中のベルを `fixed` で画面外から救い出すことは原理的にできない
   （試して溶かさないように理由を残す）。だから同じ部品を 2 つ置き、見えるほうだけを CSS で整える。

   **代償は「2 つとも動く」こと**＝`display: none` は Blazor の描画を止めないので、広い画面でも
   未読件数の問い合わせ（索引が効いて実測 0.135ms）と LISTEN の購読が 1 本ずつ余分に走る。
   部品 2 つなら安いが、**3 つ目を足すときはこの行を「安いから足してよい」と読まないこと**
   ＝そのときは未読件数を回線で 1 つに集約する話になる。 */
@media (max-width: 1024px) {
    /* 帯の高さは 56px しかないので、ここではアイコンとバッジだけにする（文字を出すとサービス名が押し出される）。
       **アイコンモード（min-width: 1025px の節）と揃えたのは 2 点だけ**＝ラベルを消すことと、バッジを
       右上のピルに重ねること。位置と余白は箱が違う（あちらは縦のカラム、こちらは 56px の帯）ので合わせていない。

       **大きさは .app-nav-button に任せる**（置く側が NotificationBell へ渡す）＝40px の当たり判定と
       フォーカス枠を隣のハンバーガーと同じ 1 か所から取る。ここで計算し直すと、あちらを 44px にした日に
       ベルだけが 40px で残り、指で押したときの空振りとしてだけ表に出る。
       この節に要るのは「右端へ寄せる」と「.app-bell の余白を外す」の 2 つだけ。 */
    .app-mobile-bar .app-bell {
        margin: 0 0 0 auto;
        padding: 0;
    }
    .app-mobile-bar .app-bell-label { display: none; }
    .app-mobile-bar .app-bell-badge {
        position: absolute; top: 0; right: 0; margin-left: 0; padding: 0 5px; font-size: 0.65rem;
    }
}

.app-notif-list { list-style: none; margin: 0; padding: 0; }
.app-notif-list li {
    display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap;
    border-top: 1px solid var(--alt-border); padding: 10px 8px; cursor: pointer;
}
.app-notif-list li:hover { background: var(--alt-bg-page); }
.app-notif-list li.unread { background: var(--alt-accent-soft); font-weight: 600; }
/* 種別チップは文字を持たないので、baseline 揃えの行では自分で中央に置く。 */
.app-notif-list .alt-notif-kind,
.app-notif-list .alt-notif-ico { align-self: center; }
.app-notif-list .body { color: var(--alt-text-sub); font-size: 0.85rem; }
.app-notif-list .time { margin-left: auto; color: var(--alt-text-muted); font-size: 0.82rem; white-space: nowrap; }

/* ===== 一覧画面の共通部品（chaser の課題一覧から移植。Workflow・Sales 等のモジュール一覧が共用する） ===== */

/* 絞り込みツールバー（表示対象・キーワード・保存条件・フィルター類を横一列に）。右端の grid-toolbar は入れ子で余白ゼロ。
   **単独でも当たる**（2026-09-08）＝`.grid-toolbar` と併せて使う箇所が 18、単独が 19 ある。
   単独の側は `alt-inline-label` や `alt-status-select` を中に置いており、どちらも flex のアイテムである前提の
   指定（`align-self` と幅）を持つので、当たっていないと**綴った幅が黙って効かない**。
   併用の側は `.grid-toolbar` が同じ値を持つので計算値は変わらない（実測で突き合わせた）。
   **この位置を動かさないこと**＝`margin-top` が `.grid-toolbar` の `margin` 一括指定に勝つのは、
   重みが同じで**あとに書いてある**からで、上へ移すと上下の余白が静かに変わる。 */
.alt-toolbar-row2 {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-start;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.25rem;
}
.grid-toolbar.alt-toolbar-row2 .toolbar-right { margin-left: auto; }
.grid-toolbar.alt-toolbar-row2 .toolbar-right .grid-toolbar { margin: 0; display: flex; align-items: center; gap: 8px; }
.alt-inline-label { color: var(--alt-text-sub); font-size: 0.85rem; white-space: nowrap; }
/* 幅は .alt-toolbar-row2 の中でも要る（単独の 4 か所が使う）。keyword-box と date-select は
   単独の中に 1 つも無いので広げない＝要求が出てから足す。 */
.grid-toolbar .alt-status-select,
.alt-toolbar-row2 .alt-status-select { width: 180px; align-self: center; }
.grid-toolbar .alt-keyword-box { width: 260px; align-self: center; }
/* 期間の日付欄（仕入・売上分析）。幅を決めないと DevExpress のエディタが行いっぱいに広がる。 */
.grid-toolbar .alt-date-select { width: 150px; align-self: center; }
.grid-toolbar .alt-inline-label { align-self: center; }

/* キーワード検索の結果件数 */
.alt-keyword-note { margin: 0 0 6px; }

/* 保存済み検索条件のチップリスト。名前ボタン=適用（選択中はもう一度で解除） / × ボタン=条件の削除 */
.alt-filter-chips { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin: 2px 0 8px; }
.alt-filter-chip { display: inline-flex; align-items: center; border: 1px solid var(--alt-border); border-radius: 999px; background: var(--alt-surface); }
.alt-filter-chip:hover { border-color: var(--alt-text-muted); }
.alt-filter-chip.is-active { background: var(--alt-accent-soft); border-color: var(--alt-accent); }
.alt-filter-chip-name,
.alt-filter-chip-x { border: none; background: none; cursor: pointer; font-size: 0.85rem; line-height: 1.4; color: var(--alt-text-strong); padding: 2px 2px 2px 10px; }
.alt-filter-chip.is-active .alt-filter-chip-name { font-weight: 600; color: var(--alt-accent); }
/* × を出さないチップ（Pm の Wiki のタグ）。上の非対称な余白は × が右に来る前提なので、単独なら右も戻す。 */
.alt-filter-chip-name:only-child { padding-right: 10px; }
.alt-filter-chip-x { padding: 2px 8px 2px 2px; color: var(--alt-text-muted); }
.alt-filter-chip-x:hover { color: var(--alt-danger); }

/* 検索条件の保存ダイアログ「いま保存される内容」プレビュー */
.save-filter-preview { display: flex; flex-direction: column; gap: 4px; border: 1px solid var(--alt-border); border-radius: 6px; background: var(--alt-bg-subtle); padding: 8px 12px; font-size: 0.85rem; margin-top: 8px; }
.save-filter-preview-row { display: flex; gap: 8px; }
.save-filter-preview-label { min-width: 5.5em; flex-shrink: 0; color: var(--alt-text-sub); }

/* キーワードのヒット箇所の抜粋（件名セルの下に小さく表示） */
.alt-hit { margin-top: 2px; color: var(--alt-text-sub); font-size: 0.8rem; line-height: 1.4; white-space: normal; word-break: break-word; }
.alt-hit .alt-hit-label { color: var(--alt-text-muted); }
.alt-hit mark { background: var(--alt-warning-border); color: inherit; padding: 0 1px; border-radius: 2px; }

/* 行タップで何かが開くグリッドはポインタカーソルを出す */
.alt-rowclick .dxbl-grid-table > tbody > tr:hover > td { cursor: pointer; }

/* カスタム項目の入力欄（Core の CustomFieldInputs）。モジュールをまたいで同じ見た目にするのでシェルに置く。
   数値の入力は幅を決め打ちする（alt-inline のように伸ばすと、単位の文字が右端へ離れて読めなくなる）。 */
.alt-field-inline { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.alt-check-list { display: flex; flex-wrap: wrap; gap: 4px 16px; padding: 4px 0; }

/* 入力欄＋補助（チェックボックス・注記）を横に並べる（AI 設定などの管理画面）。先頭の入力が伸びる。 */
.alt-inline { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; align-self: start; }
.alt-inline > :first-child { flex: 1 1 240px; }

/* ==================================================================
   全体通知（バナー・一覧・詳細）。chaser から移植。
   重要度の 3 段（is-info / is-warning / is-critical）は
   AnnouncementLevelExtensions.CssClass が返すもので、バナー・一覧・詳細で共用する。
   ================================================================== */

/* 本文最上部に積むバナー群 */
.alt-annc-banners {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-bottom: 14px;
}

.alt-annc-banner {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 9px 12px;
    border: 1px solid var(--alt-border);
    border-left-width: 4px;
    border-radius: 6px;
    background: var(--alt-bg-page);
}

.alt-annc-banner.is-info { background: var(--alt-accent-soft); border-color: var(--alt-border-primary); border-left-color: var(--alt-accent); }
.alt-annc-banner.is-warning { background: var(--alt-warning-bg); border-color: var(--alt-warning-border); border-left-color: var(--alt-warning-text); }
.alt-annc-banner.is-critical { background: var(--alt-danger-bg); border-color: var(--alt-danger-border); border-left-color: var(--alt-danger); }

.alt-annc-banner-title { font-weight: 600; }
.alt-annc-banner-link { margin-left: auto; font-size: 0.85rem; white-space: nowrap; }

.alt-annc-banner-close {
    border: 0;
    background: none;
    cursor: pointer;
    color: var(--alt-text-secondary);
    font-size: 1.1rem;
    line-height: 1;
    padding: 2px 4px;
}

.alt-annc-banner-close:hover { color: var(--alt-text-primary); }

/* 重要度バッジ */
.alt-annc-level {
    font-size: 0.74rem;
    font-weight: 700;
    padding: 2px 8px;
    border-radius: 10px;
    white-space: nowrap;
    border: 1px solid transparent;
}

.alt-annc-level.is-info { background: var(--alt-accent-soft-strong); color: var(--alt-text-secondary); border-color: var(--alt-border-primary); }
.alt-annc-level.is-warning { background: var(--alt-warning-bg); color: var(--alt-warning-text); border-color: var(--alt-warning-border); }
.alt-annc-level.is-critical { background: var(--alt-danger-bg); color: var(--alt-danger-text); border-color: var(--alt-danger-border); }

/* 全体通知の一覧（/announcements） */
.alt-annc-list { list-style: none; margin: 0; padding: 0; }
.alt-annc-list li {
    display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap;
    border-top: 1px solid var(--alt-border); padding: 10px 8px; cursor: pointer;
}
.alt-annc-list li:hover { background: var(--alt-bg-page); }
.alt-annc-list .title { font-weight: 600; }
.alt-annc-list .time { margin-left: auto; color: var(--alt-text-tertiary); font-size: 0.82rem; white-space: nowrap; }

.alt-annc-withdrawn { color: var(--alt-text-tertiary); font-size: 0.82rem; }

/* 全体通知の詳細（/announcements/{id}） */
.alt-annc-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.alt-annc-head .page-title { margin: 0; }
.alt-annc-body { margin: 14px 0 20px; }

/* 管理画面の「届け方」チェック群（縦積み） */
.annc-checks { display: flex; flex-direction: column; gap: 4px; }

/* Markdown の描画（全体通知の本文）。pre-wrap だと Markdown の改行が二重になるので打ち消す。 */
.alt-markdown { white-space: normal; }
.alt-markdown p { margin: 0 0 8px; }
.alt-markdown pre { background: var(--alt-bg-page); border: 1px solid var(--alt-border); border-radius: 6px; padding: 10px; overflow-x: auto; }
.alt-markdown code { background: var(--alt-bg-page); border-radius: 4px; padding: 1px 4px; }
.alt-markdown pre code { background: none; padding: 0; }
.alt-markdown table { border-collapse: collapse; margin: 8px 0; }
.alt-markdown th, .alt-markdown td { border: 1px solid var(--alt-border-strong); padding: 4px 10px; }
.alt-markdown blockquote { border-left: 3px solid var(--alt-border-strong); margin: 8px 0; padding: 2px 12px; color: var(--alt-text-secondary); }
.alt-markdown img { max-width: 100%; height: auto; border-radius: 6px; margin: 6px 0; }

/* 一覧などから別画面へ渡す小さいリンク（「もっと見る」「一覧へ」） */
.alt-inline-link {
    font-size: 0.85rem;
    color: var(--alt-brand);
    text-decoration: none;
    white-space: nowrap;
}

.alt-inline-link:hover { text-decoration: underline; }

/* ==================================================================
   ダッシュボード（/）。chaser から移植。
   中身はお知らせのダイジェストだけ（全体通知／お知らせの 2 枚）。
   モジュールの集計はここには入らない＝業務の入口はサイドバーの見出しが開く画面に揃えてある。
   主段と脇の 2 カラムはそちらのモジュールが持つ（使うのがモジュール 1 つだけになったため）。
   ================================================================== */

/* ---- お知らせのダイジェスト（全体通知／お知らせの 2 枚） ---- */
.dash-notices {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.8rem;
    margin-bottom: 1rem;
}

/* 狭い画面では 1 枚ずつ縦に積む。 */
@media (max-width: 900px) {
    .dash-notices { grid-template-columns: 1fr; }
}

/* グリッドの子は既定で min-width:auto＝中身の最小幅より縮まない。
   お知らせの件名は 1 行に収めて末尾を切る（.dash-notice-text）ので、
   これを入れないと長い件名がそのまま列を押し広げ、右のパネルが画面からはみ出す。 */
.dash-notices > * { min-width: 0; }

.dash-notice-panel { margin: 0; }

/* ダイジェストの見出し行（右端に「未読のみ」トグル） */
.dash-notice-head-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0;
}

.dash-notice-toggle {
    margin-left: auto;
    font-size: 0.8rem;
    font-weight: 400;
}

.dash-notice-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.3rem 0.2rem;
    border-bottom: 1px solid var(--alt-border);
    color: inherit;
    text-decoration: none;
    cursor: pointer;   /* href ではなく click で遷移する（既読にしてから飛ぶ）ので明示する */
}

.dash-notice-row:last-of-type { border-bottom: none; }
.dash-notice-row:hover { background: var(--alt-accent-soft); }
.dash-notice-row.is-unread .dash-notice-text { font-weight: 700; }

.dash-notice-text {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dash-notice-time {
    flex-shrink: 0;
    font-size: 0.8rem;
    color: var(--alt-text-tertiary);
}

.dash-notice-more {
    display: inline-block;
    margin-top: 0.3rem;
}

/* 全体通知の行は「見出し行＋本文プレビュー（3 行まで）」の 2 段 */
.dash-annc-row {
    flex-direction: column;
    align-items: stretch;
    gap: 0.15rem;
}

.dash-notice-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
}

.dash-annc-preview {
    font-size: 0.85rem;
    line-height: 1.5;
    color: var(--alt-text-secondary);
    overflow-wrap: break-word;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    overflow: hidden;
}

/* ---- お知らせの行頭の絵（Components/Shared/NotificationKindBadge） ----
   2 種類ある。**出所**（承認依頼・お知らせ・全体通知）は発信元モジュールのアイコンを背景なしで出すだけなので
   既存の .alt-ico に乗る（濃色テーマの白抜きもそちらが持っている）。
   **状態**（完了・警告）だけがこの色付きチップで、**グリフは mask で塗る**
   ＝背景画像では SVG の色が黒に固定され、状態の色にも濃色テーマにも追随できない。
   mask なら currentColor を取るので、色の指定はチップ 1 か所で済む。 */
.alt-notif-ico { flex: none; }

.alt-notif-kind {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 22px;
    height: 22px;
    border-radius: 6px;
    background: var(--alt-accent-soft);
    color: var(--alt-text-secondary);
}

.alt-notif-kind::before {
    content: "";
    width: 14px;
    height: 14px;
    background-color: currentColor;
    -webkit-mask: var(--alt-notif-icon) center / 14px 14px no-repeat;
    mask: var(--alt-notif-icon) center / 14px 14px no-repeat;
}

.alt-notif-kind.is-completed {
    --alt-notif-icon: url('icons/check-circle.svg');
    background: var(--alt-success-bg);
    color: var(--alt-success-text);
}

.alt-notif-kind.is-warning {
    --alt-notif-icon: url('icons/alert-triangle.svg');
    background: var(--alt-warning-bg);
    color: var(--alt-warning-text);
}

/* ---- 対応が必要なもの（モジュールが名乗るダイジェスト） ----
   数字とリンクだけを受け取り、見せ方はここで決める（Core の IDashboardSummaryProvider）。
   幅に応じて 1〜4 列。カードの中身は「名前 …… 件数（＋金額）」の行を並べただけ。 */
.dash-panels-head { margin-top: 22px; }

.dash-panels {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 16px;
    align-items: start;
}

.dash-panel { margin: 0; padding: 14px 16px; }

.dash-panel-head {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 8px;
    font-size: 0.95rem;
    font-weight: 700;
}

.dash-panel-head a { color: inherit; text-decoration: none; }
.dash-panel-head a:hover { text-decoration: underline; }

/* 数字の行。行ごとリンクにして、押すとその数字を片付けられる画面へ飛ぶ。 */
.dash-stat {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    padding: 7px 2px;
    border-bottom: 1px solid var(--alt-border);
    text-decoration: none;
    color: inherit;
}

.dash-stat:last-of-type { border-bottom: none; }
.dash-stat:hover { background: var(--alt-accent-soft); }

.dash-stat-label { font-size: 0.88rem; color: var(--alt-text-secondary); }

.dash-stat-value { display: flex; align-items: baseline; gap: 8px; white-space: nowrap; }
.dash-stat-value .num { font-size: 1.25rem; font-weight: 700; line-height: 1.2; }
.dash-stat-value .amount { font-size: 0.82rem; color: var(--alt-text-secondary); }

/* 放っておくと困る度合い。色はシェルが決める（モジュールは強さだけを言う）。 */
.dash-stat.is-warn .num { color: var(--alt-warning-text); }
.dash-stat.is-danger .num { color: var(--alt-danger-text); }

/* 関連項目の並び（Workflow の関連課題・添付／Sales の関連チケット・添付）。
   **シェルに置く**＝2 つ以上のモジュールが使うため。モジュールのスタイルシートに置くと、
   そのモジュールを無効にした構成で別のモジュールの画面だけが崩れる（例外もログも出ない）。 */
.alt-related {
    margin-bottom: 16px;
}

.alt-related-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 3px 0;
    flex-wrap: wrap;
}

.alt-related-form {
    display: flex;
    gap: 8px;
    align-items: center;
    margin-top: 8px;
    max-width: 720px;
}

.alt-related-form > :nth-child(-n+2) {
    flex: 1;
    min-width: 0;
}

/* 絵だけのボタン（2026-09-05 に Pm の .pm-icon-btn から昇格）。
   要求したのが Pm（Markdown のツールバー・簡易ビュー）と Core の AnchorLinkButton
   （課題・申請・製造指図のタイムライン）の両方で、モジュール固有のものが 1 つも無い。
   **何が起きるかは必ず title と aria-label で伝える**＝絵だけにしない、が既存の約束。 */
/* 絵だけのボタン。**<a> にも着せる**（一覧の操作列でページごと移るもの）ので、
   下線と文字色はここで落とす＝リンクの体裁のまま絵を入れると、絵の下に線が残る。 */
.alt-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    background: none;
    border: 1px solid transparent;
    border-radius: var(--alt-radius-sm);
    color: inherit;
    text-decoration: none;
    cursor: pointer;
}

.alt-icon-btn:hover {
    background: var(--alt-bg-secondary);
    border-color: var(--alt-border);
}

/* 枠つき（GridCommandButton の Framed）。ツールバーに 1 つだけ置くときに使う
   ＝隣の DxButton が枠を持つので、絵だけ枠なしだと押せるものに見えない。
   一覧の操作列は行の中で静かにしていてほしいので、そちらは当てた時だけ枠が出る（既定）。 */
.alt-icon-btn-framed {
    border-color: var(--alt-border-strong);
}

/* 開いているボタン（添付など）は押し込んで見せる＝もう一度押すと閉じる、が読める。 */
.alt-icon-btn.is-on {
    background: var(--alt-bg-secondary);
    border-color: var(--alt-border);
}

/* 一覧の操作列（コマンドボタン）の並び（2026-09-05・TEST1-60）。
   **規約は docs/claude/module-wiring.md の「一覧の操作列」が正**（列の位置・絵・幅の決め方）。
   ここが持つのは見た目の理由 2 つだけ:
   ・**折り返さない**＝2 段になると行の高さが行ごとに変わり、一覧の目が滑る
   ・**操作列の中だけボタンを 24px**＝既定の 28px は SizeMode.Small の行（約 30px）に入れると
     上下の余白が消えて窮屈になる
   幅（列そのもの）は `GridDefaults.CommandColumnWidth` が持つ＝ここの 24px と 2px を画面が暗算しない。 */
.alt-grid-commands {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    gap: 2px;
    /* 名札の基準（下の `[data-alt-tip]` を参照）。 */
    position: relative;
}

/* **名札はかたまり全体の右に出す**＝ボタン 1 つ 1 つの右に出すと、隣のボタンを覆って
   次に押したいものが見えなくなる。**そのためにボタン側の `position` を外して**、
   名札の基準をこの `div` に移している（`[data-alt-tip]` の既定は自分基準）。 */
.alt-grid-commands [data-alt-tip] {
    position: static;
}

.alt-grid-commands .alt-icon-btn {
    width: 24px;
    height: 24px;
}

/* 「その他」（`GridCommandMenu`）を隣の絵と同じ大きさ・同じ枠に揃える。
   **DevExpress のボタンの内側まで潰す**＝既定では余白と枠を持っていて、隣の絵より一回り大きく出る
   （§7「DevExpress の内部スタイルに勝つには !important が要る場面がある」）。 */
.alt-grid-commands .alt-grid-menu {
    width: 24px !important;
    height: 24px !important;
    min-width: 24px !important;
    padding: 0 !important;
    background: none !important;
    border: 1px solid transparent !important;
    border-radius: var(--alt-radius-sm) !important;
    color: inherit !important;
    box-shadow: none !important;
}

.alt-grid-commands .alt-grid-menu:hover {
    background: var(--alt-bg-secondary) !important;
    border-color: var(--alt-border) !important;
}

/* 開く向きの矢印は出さない＝隣の絵と大きさを揃えるため。**消すのは DevExpress が足す `<svg>` の方**
   （実測。`DxDropDownButton` は入れ子を作らず `<button>` そのものに CssClass が付き、
   絵のあとに `use href="…#dx-dropdown-down"` の svg を 1 枚置く）。 */
.alt-grid-commands .alt-grid-menu > svg.dxbl-image {
    display: none !important;
}

/* 絵だけのボタンの名札（2026-09-06・TEST1-60）。**DevExpress Blazor には汎用のツールチップが無い**
   （25.2 で持っているのはグラフ・地図・スケジューラの専用品だけで、`TooltipController` は
   WebForms/MVC の道具）。`title` はブラウザが 1 秒ほど待ってから出すので「当てたら出る」にならない。
   そこで**当たった瞬間に出す名札を CSS で持つ**＝回線も JS も使わず、行が何百あっても増えない。
   読み上げは `aria-label` が担うので、この名札は `aria-hidden` と同じ扱いでよい。 */
[data-alt-tip] {
    position: relative;
}

/* **操作列のセルだけ、はみ出しを許す**（実測）＝グリッドのセルは既定で `overflow: hidden` なので、
   名札がセルの高さで切られて 2 文字ぶんしか見えない。全部のセルを開けると長い文字が隣の列へ
   流れ出すので、操作の絵が入っているセルに限る。 */
td:has(> .alt-grid-commands) {
    overflow: visible !important;
}

[data-alt-tip]:hover::after,
[data-alt-tip]:focus-visible::after {
    content: attr(data-alt-tip);
    position: absolute;
    /* **横に出す**（実測して 3 つ目に落ち着いた）。下は**カーソルが大きい設定だと矢印に隠れて読めない**、
       上は**一覧の 1 行目でヘッダー行の下に潜る**（セルの `overflow` を開けても、ヘッダーは別の面に
       描かれるので前に出せない）。横なら行の高さに収まるので、どちらにも当たらない。
       操作列は一番左と決まっている（`docs/claude/module-wiring.md`）ので、右に伸ばして画面から出ない。 */
    left: calc(100% + 6px);
    top: 50%;
    transform: translateY(-50%);
    z-index: 1200;
    padding: 3px 8px;
    border-radius: var(--alt-radius-sm);
    background: var(--alt-tooltip-bg);
    color: var(--alt-tooltip-fg);
    font-size: 12px;
    line-height: 1.5;
    white-space: nowrap;
    pointer-events: none;
}

/* 詳細画面の見出しに置く「番号・件名・リンク」のコピー（Core の CopyRefButtons。chaser から移植）。
   **枠のある小さなボタン**にしてあるのは chaser と同じ形＝見出しの操作行に並ぶので、
   リンク風の文字だと隣の DxButton と地続きに見えて押せるものが読めない。
   間隔は .linklike + .linklike と同じ .75rem（あいだに「コピーしました」が挟まるので gap で取る）。 */
.alt-copy-refs {
    display: inline-flex;
    align-items: center;
    gap: .75rem;
    margin-right: .75rem;
}

.alt-copy-btn {
    border: 1px solid var(--alt-border-strong);
    border-radius: 4px;
    background: var(--alt-surface);
    color: var(--alt-text-strong);
    font-size: 0.72rem;
    font-weight: 700;
    padding: 2px 8px;
    line-height: 1.4;
    cursor: pointer;
}

.alt-copy-btn:hover {
    background: var(--alt-bg-muted);
    border-color: var(--alt-text-muted);
}

/* コピーの「コピーしました」（js/clipboard.js が押された要素に .is-copied を付け外しする）。
   **出し入れを CSS に寄せてある**＝.NET 側に持たせると押すたびに回線を 1 往復する。 */
.alt-copied-notice {
    display: none;
}

.is-copied + .alt-copied-notice {
    display: inline;
}

/* タイムラインの行への直接リンク（Core の AnchorLinkButton・js/anchor-link.js と対。2026-09-05）。
   ハッシュ付きの URL で開いたとき、その行を一瞬光らせて「ここ」と分かるようにする。
   **光っている長さを決めるのはここだけ**＝JS はアニメーションの終わりを待ってクラスを外す。
   **終端は transparent**＝光らせる行は課題・申請・製造指図で背景が違うので、
   決め打ちの色へ戻すと元の背景を上書きしてしまう。 */
.alt-anchor-flash {
    animation: alt-anchor-flash 2.5s ease-out;
}

@keyframes alt-anchor-flash {
    0%, 40% { background-color: rgba(245, 210, 100, 0.4); }
    100% { background-color: transparent; }
}
