/*
 * 自前CSS。Bootstrapの配布物は改変せず、ここだけで上書きする。
 * Sassは使わない。上書きはBootstrapのCSS変数に対して行う。
 */

:root {
    /*
     * 本文と見出しのフォント。和文を先に置く。欧文を先に置くと、欧文だけが
     * その字体になり、かなと漢字は代替に落ちて、1行の中で字面が混ざる。
     * 字体そのものは配信しない。外部ホストを指さないため、読む側の環境に在る
     * ものから選ぶ。
     */
    --bs-body-font-family: "Hiragino Sans", "Noto Sans JP", "Yu Gothic UI", Meiryo,
        system-ui, -apple-system, "Segoe UI", "Helvetica Neue", sans-serif;
    --bs-body-font-size: 1.0625rem;
    --bs-body-line-height: 1.8;

    /* 本アプリ独自の値。Bootstrapの変数と衝突させないため接頭辞を分ける。 */
    --bp-content-max-width: 1140px;

    /* 配色。青1色を主とし、地は青みの淡い灰、面は白で浮かせる。 */
    --bp-primary: #176cf8;
    --bp-primary-dark: #0d55cf;
    --bp-primary-soft: #8fb6fb;
    --bp-surface: #fff;
    --bp-band: #f3f8fe;
    --bp-tile: #eef5fe;
    --bp-ink: #152742;
    --bp-ink-body: #3d4757;
    --bp-ink-muted: #5c677a;
    --bp-line: #e2eaf5;

    /* 3Dの枠の地。青みを持たない淡い灰——描く箱の青系の色が地から分かれ、黒い線も沈まない。 */
    --bp-viewer-ground: #e8eaed;

    /*
     * 表示名の2色。ロゴの絵（public/images/logo.svg）の紺と青と同じ値で、絵と字を
     * 1つの印として読ませる。見出しの紺（--bp-ink）とは別の値である——絵は <img> で
     * 読むので外の変数を読めず、字の側を絵の数値に合わせるしかない。
     */
    --bp-brand-ink: #0d2d55;
    --bp-brand-accent: #2e6ebc;

    /* 上の値をBootstrapの変数へ流す。配布物は改変しない。 */
    --bs-primary: var(--bp-primary);
    --bs-primary-rgb: 23, 108, 248;
    --bs-body-bg: var(--bp-band);
    --bs-body-color: var(--bp-ink-body);
    --bs-emphasis-color: var(--bp-ink);
    --bs-secondary-color: var(--bp-ink-muted);
    --bs-heading-color: var(--bp-ink);
    --bs-border-color: var(--bp-line);
    --bs-link-color: var(--bp-primary);
    --bs-link-color-rgb: 23, 108, 248;
    --bs-link-hover-color-rgb: 13, 85, 207;
    --bs-border-radius: 0.75rem;
    --bs-border-radius-sm: 0.5rem;
    --bs-border-radius-lg: 1rem;

    /* ナビとフッタは、地から浮いた面として置く。 */
    --bs-tertiary-bg: var(--bp-surface);
    --bs-tertiary-bg-rgb: 255, 255, 255;
}

/*
 * 和字と英数字のあいだの空き。字には和欧間の空白を置かず、空きはブラウザが組む。
 * コードの字は空きを足さない——写す字と、見える字の間合いが食い違う。
 * text-autospaceを知らないブラウザは規則を読み飛ばし、字は詰まったまま描く。
 */
body {
    text-autospace: normal;
}

code, pre, kbd, samp {
    text-autospace: no-autospace;
}

/*
 * 見出しは太さで段を作る。和文は字画が多く、大きさだけを変えても段が読めない。
 * 行間は既定の1.2では詰まりすぎる——かなと漢字は仮想ボディいっぱいまで
 * 字画が届くので、欧文と同じ行間だと行が接触して見える。
 */
h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
    font-weight: 700;
    line-height: 1.4;
    margin-bottom: 0.75rem;
}

h1, h2, .h1, .h2 {
    font-weight: 800;
    line-height: 1.3;
}

/*
 * 見出しの上は、下より広く取る。見出しは直後の文に属するので、上下が
 * 同じだけ空いていると、どちらに属する見出しかを読む側が決められない。
 * 先頭の見出しには付けない——囲みの内側の余白と二重になる。
 * 余白を明示している画面（`mt-*` / `mb-*`）はそちらが勝つ。ここで与えるのは、
 * 何も指定していない見出しの既定である。
 */
:is(h1, h2, .h1, .h2):not(:first-child) {
    margin-top: 2.5rem;
}

/* 小さい見出しは間を詰める。大きい見出しと同じだけ空けると、節の段が消える。 */
:is(h3, h4, h5, h6, .h3, .h4, .h5, .h6):not(:first-child) {
    margin-top: 1.75rem;
}

/*
 * 節の見出しには縦棒を付ける。囲みの中の小見出しも同じ`h2`なので、
 * 字の大きさだけでは、節の頭かどうかが読み分けられない。
 * 節の頭は`.h5`、囲みの中は`.h6`で書き分けられている。
 */
h2.h5:not(.modal-title) {
    padding-left: 0.75rem;
    border-left: 0.25rem solid var(--bp-primary);
}

/*
 * Markdownから組んだ本文（API仕様・クエリの数え方・規約類）。見出しの大きさと太さは、MarkdownをHTMLにする部品が
 * 段で付けるclass（`h5`・`h6`・`fw-bold`）が決め、2段目の見出しは節の見出し（`h2.h5`）の縦棒も持つ。
 * 2段目の見出しの上だけは、大きい見出しと同じだけ空ける——`.h5`は小さい見出しの間隔を引くので、すぐ下に続く
 * 3段目の見出しの上と同じ間隔になり、どちらに属する見出しかが読めない。
 * コードの塊は面に載せる——地の上では、どこまでが写して使う字かが読み取れない。
 */
.bp-prose h2:not(:first-child) {
    margin-top: 2.5rem;
}

.bp-prose pre {
    padding: 0.75rem 1rem;
    background-color: var(--bp-surface);
    border: 1px solid var(--bs-border-color);
    border-radius: var(--bs-border-radius-sm);
}

/*
 * 番号を字で持つ箇条の項目。Markdownから組んだ本文で、字が「(1)」のような番号で始まる項目に付く
 * （MarkdownをHTMLにする部品が付ける）。印を付けると、印と字の番号が重なる。消すのは印だけで、
 * 字下げは箇条のまま残す。
 */
.bp-self-numbered {
    list-style-type: none;
}

/* 本文へスキップするリンク。キーボード操作でのみ現れる。 */
.bp-skip:focus {
    position: fixed;
    z-index: 1080;
    top: 0.5rem;
    left: 0.5rem;
    padding: 0.5rem 0.75rem;
    background-color: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: var(--bs-border-radius);
}

/* 既定のフォーカスリングは背景によっては見えにくいため、太さを揃える。 */
:focus-visible {
    outline: 2px solid var(--bs-primary);
    outline-offset: 2px;
}

.container {
    max-width: var(--bp-content-max-width);
}

/*
 * ナビの表示名。前半を紺、後半（navigation.brand.accent）を青で書く。
 * Bootstrapは表示名の色を`.navbar`の変数で受けるので、そこを上書きする——
 * `.navbar-brand`のcolorを直接書くと、ホバー時の規則が変数の側の色へ戻す。
 */
.navbar {
    --bs-navbar-brand-color: var(--bp-brand-ink);
    --bs-navbar-brand-hover-color: var(--bp-brand-ink);
}

.bp-brand-accent {
    color: var(--bp-brand-accent);
}

/* 表示名の左のロゴ。字の大きさに追従させず、固定の正方形にする。 */
.bp-brand-logo {
    width: 2rem;
    height: 2rem;
}

/*
 * 共通ヘッダの項目の区切り。横に並べる幅でだけ、項目のあいだに字の高さの縦線を置く——
 * 項目が続けて並ぶと、語の切れ目が読みにくい。線は項目の当たりの外に出さず、当たりの大きさを変えない。
 */
@media (min-width: 992px) {
    .navbar-expand-lg .navbar-nav .nav-item {
        position: relative;
    }

    .navbar-expand-lg .navbar-nav .nav-item + .nav-item::before {
        content: "";
        position: absolute;
        top: 50%;
        left: 0;
        height: 1em;
        border-left: 1px solid var(--bs-border-color);
        transform: translateY(-50%);
    }
}

/* 横に並べる幅の狭い側では、項目の左右の余白を詰める（配布物の既定は0.5rem）——未ログインの項目を並べると余りが
   ほとんど無く、字の幅が広い字体では項目の字が折れる。 */
@media (min-width: 992px) and (max-width: 1199.98px) {
    .navbar-expand-lg .navbar-nav {
        --bs-navbar-nav-link-padding-x: 0.375rem;
    }
}

/* 共通ヘッダの分類の箱。広い画面では本文に重なって開くので、白い面に載せる。現在地の項目の地は、
   配布物が値で持つ既定の青を、このアプリの色に替える。 */
.dropdown-menu {
    --bs-dropdown-bg: var(--bp-surface);
    --bs-dropdown-link-active-bg: var(--bp-primary);
}

/* 畳む幅では、箱を開いたナビの中の段として描く——枠と面を外し、項目は箱の項目の余白の分だけ字下げして並ぶ。
   重なる箱の見た目のままだと、縦に並んだ項目の中に別の囲みが割り込む。 */
@media (max-width: 991.98px) {
    .navbar-nav .dropdown-menu {
        --bs-dropdown-bg: transparent;
        --bs-dropdown-border-width: 0;
        --bs-dropdown-padding-y: 0;
    }
}

/*
 * 地色を淡くした分、読ませるものは白い面に載せる。地と面が同じ色だと、
 * どこまでが1つのまとまりかが枠線の1pxだけで決まり、段が読めない。
 */
.border.rounded.p-3,
.table {
    background-color: var(--bp-surface);
}

.table {
    --bs-table-bg: var(--bp-surface);
}

/* 入力欄も面の側に置く。既定では地と同じ色になり、欄の位置が分からない。 */
.form-control,
.form-select {
    background-color: var(--bp-surface);
}

/*
 * チェックボックスとラジオも、中を面の色にする。枠は、白い面と地のどちらに対しても
 * 3:1以上の色にする——配布物の枠は罫の色（--bp-line）で、どちらの上でもほとんど
 * 見えず、どこに印を付けるのかが分からない。
 */
.form-check-input {
    --bs-form-check-bg: var(--bp-surface);
    border-color: var(--bp-ink-muted);
}

/*
 * 主ボタンの色は`--bs-primary`では変わらない。Bootstrapの`.btn-primary`は
 * `--bs-btn-bg`に色を直接書いているので、ボタン側の変数を上書きする。
 */
/*
 * 角丸は上の`--bs-border-radius*`から来るので、ボタン側では指定しない。
 * ここで固定すると、`.btn-lg`・`.btn-sm`の大きさごとの角丸まで潰れる。
 */
.btn {
    --bs-btn-font-weight: 700;
}

.btn-primary {
    --bs-btn-bg: var(--bp-primary);
    --bs-btn-border-color: var(--bp-primary);
    --bs-btn-hover-bg: var(--bp-primary-dark);
    --bs-btn-hover-border-color: var(--bp-primary-dark);
    --bs-btn-active-bg: var(--bp-primary-dark);
    --bs-btn-active-border-color: var(--bp-primary-dark);
    --bs-btn-disabled-bg: var(--bp-primary);
    --bs-btn-disabled-border-color: var(--bp-primary);
    --bs-btn-focus-shadow-rgb: 23, 108, 248;
}

.btn-outline-secondary {
    --bs-btn-color: var(--bp-ink);
    --bs-btn-border-color: var(--bp-line);
    --bs-btn-hover-color: var(--bp-ink);
    --bs-btn-hover-bg: var(--bp-tile);
    --bs-btn-hover-border-color: var(--bp-primary-soft);
    --bs-btn-active-color: var(--bp-ink);
    --bs-btn-active-bg: var(--bp-tile);
    --bs-btn-active-border-color: var(--bp-primary-soft);
}

.btn-outline-primary {
    --bs-btn-color: var(--bp-primary);
    --bs-btn-border-color: var(--bp-primary);
    --bs-btn-hover-bg: var(--bp-primary);
    --bs-btn-hover-border-color: var(--bp-primary);
    --bs-btn-active-bg: var(--bp-primary);
    --bs-btn-active-border-color: var(--bp-primary);
    --bs-btn-disabled-color: var(--bp-primary);
    --bs-btn-disabled-border-color: var(--bp-primary);
    --bs-btn-focus-shadow-rgb: 23, 108, 248;
}

/*
 * Bootstrapが既定の青を値として書いている箇所。変数からは届かないので、
 * 規則ごと上書きする。配布物は改変しない。
 */
.form-check-input:checked,
.form-check-input[type="checkbox"]:indeterminate {
    background-color: var(--bp-primary);
    border-color: var(--bp-primary);
}

.form-control:focus,
.form-select:focus,
.form-check-input:focus {
    border-color: var(--bp-primary-soft);
    box-shadow: 0 0 0 0.25rem rgba(23, 108, 248, 0.25);
}

.nav-link:focus-visible {
    box-shadow: 0 0 0 0.25rem rgba(23, 108, 248, 0.25);
}

.nav-pills {
    --bs-nav-pills-link-active-bg: var(--bp-primary);
}

.list-group {
    --bs-list-group-active-bg: var(--bp-primary);
    --bs-list-group-active-border-color: var(--bp-primary);
}

/*
 * Bootstrapが埋め込んで持っている絵。ナビの開閉・選択欄の矢印・閉じるボタンは、
 * 配布物の中に画像として書かれており、色だけを変える手段が無いので、
 * 同じ形を自前で書き直して差し替える。
 */
.navbar-toggler-icon {
    --bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%23152742' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2.5' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
}

.form-select {
    --bs-form-select-bg-img: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23152742' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
}

.btn-close {
    --bs-btn-close-color: var(--bp-ink);
    --bs-btn-close-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23152742'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e");
}

/* 数値の桁を揃える。寸法・個数の表で桁がずれると読み違える。 */
.bp-numeric {
    font-variant-numeric: tabular-nums;
    text-align: right;
}

/* 語の途中で折らない。折ってよい所は、字の間に`<wbr>`で置く。 */
.bp-keep-words {
    word-break: keep-all;
}

/*
 * 区分の段と規格のプルダウンの、見出しとプルダウンの並び。見出しの列はいちばん長い見出しの幅になり、どの段でもプルダウンの
 * 左端がそろう。段の行を包む要素（.bp-carton-levels・.bp-carton-level）は箱を作らず、見出しとプルダウンが
 * そのまま格子の升に入る——段の数は区分の字で決まり、画面のJavaScriptが行を足しても列はそろったままになる。
 */
.bp-carton-choice {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr);
    gap: 0.25rem 0.5rem;
    align-items: center;
}

.bp-carton-levels,
.bp-carton-level {
    display: contents;
}

/* 見出しの字は、隣のプルダウン（.form-select-sm）と同じ大きさにする。 */
.bp-carton-level-label {
    font-size: 0.875rem;
}

/*
 * 外部リンクの印。開く先がこのアプリの外であることを、字の後ろの絵で示す。絵は四角から右上へ矢印が抜ける形で、
 * 形だけをmaskに持ち、色はリンクの字の色（currentColor）に従う——ホバーの色も、リンクの規則のまま変わる。
 * 絵1つだけのリンクは字のリンクより小さいので、押せる広さを24×24 px以上に取る。
 */
.bp-external-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 24px;
    min-height: 24px;
    vertical-align: middle;
}

.bp-external-icon {
    display: inline-block;
    width: 1em;
    height: 1em;
    background-color: currentColor;
    mask: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='M7 3H4a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V9M8 8l5-5M9 3h4v4'/%3e%3c/svg%3e") center / contain no-repeat;
}

/*
 * 押せない転倒禁止の欄（未ログインの画面）は当たりを持たない。HTMLは押せない欄へのclickを届けないので、当たりを
 * 外して押した所を欄の枠（data-bp-upright-cell）に届け、画面のJavaScriptがそこで登録の案内を開く。
 */
[data-bp-cargo-upright]:disabled {
    pointer-events: none;
}

/* 結果がまだ無いときの枠。計算の前後で高さが変わるとレイアウトがずれるため、
   空のときも同じ高さを保つ。 */
.bp-empty {
    min-height: 22rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

/* そこが3Dであることを、押す前に伝えるための薄い図。 */
.bp-empty-figure {
    width: 8rem;
    height: 6rem;
    border-style: dashed !important;
    opacity: 0.5;
}

/*
 * 入力と結果の左右の割り方。lg未満では縦に積む。lg以上では左を入力に要る幅で置き、余った幅をすべて
 * 結果に回す——広い画面でも左は増やさない。掴んで動かした幅は、画面のJavaScriptが --bp-left-widthに
 * 入れる。段（data-bp-stage）は、1が入力と結果、2が結果だけ、3が3Dだけの全面である。
 * どの段でも、見せ方だけを変える——要素はDOMから外さない。
 */
.bp-split {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

.bp-split-edge {
    display: none;
}

@media (min-width: 992px) {
    .bp-split {
        flex-direction: row;
        gap: 0;
    }

    .bp-split-input {
        flex: 0 0 var(--bp-left-width, 400px);
        min-width: 0;
    }

    .bp-split-result {
        flex: 1 1 0;
        min-width: 0;
    }

    /* 境目。上に畳む・開くのボタン、その下に掴む帯。 */
    .bp-split-edge {
        display: flex;
        flex: 0 0 auto;
        flex-direction: column;
        align-items: center;
        width: 2rem;
    }

    .bp-split[data-bp-stage="2"] .bp-split-input,
    .bp-split[data-bp-stage="1"] [data-bp-expand],
    .bp-split[data-bp-stage="2"] [data-bp-collapse] {
        display: none;
    }
}

@media (min-width: 1200px) {
    .bp-split-input {
        flex-basis: var(--bp-left-width, 480px);
    }
}

.bp-split-toggle {
    padding-inline: 0.4rem;
    line-height: 1.2;
}

/* 掴む帯。見える線は1pxで、掴める幅はそれより広く取る——線そのものを掴ませると、外して空振りする。 */
.bp-split-handle {
    flex: 1 1 auto;
    width: 0.75rem;
    margin-top: 0.5rem;
    background: linear-gradient(var(--bp-primary-soft), var(--bp-primary-soft)) center / 1px 100% no-repeat;
    cursor: col-resize;
    touch-action: none;
}

.bp-split-handle:hover,
.bp-split-handle:focus-visible {
    background-image: linear-gradient(var(--bp-primary), var(--bp-primary));
    background-size: 3px 100%;
}

/* 畳んでいるあいだは、帯は線だけで、掴めない。 */
.bp-split[data-bp-stage="2"] .bp-split-handle {
    cursor: auto;
    pointer-events: none;
}

/*
 * md未満の入力と結果のタブ。選んでいるタブは、色と下の線の両方で示す——色だけで伝えない。
 */
.bp-tabs {
    display: flex;
    border-bottom: 1px solid var(--bs-border-color);
}

.bp-tab {
    flex: 1 1 0;
    padding: 0.5rem 0.75rem;
    color: var(--bs-secondary-color);
    font-weight: 700;
    background: none;
    border: 0;
    border-bottom: 0.25rem solid transparent;
}

.bp-tab[aria-selected="true"] {
    color: var(--bp-primary);
    border-bottom-color: var(--bp-primary);
}

/* 画面の下の帯の計算ボタンの文。結果の出ている結果のタブでだけ「もう一度計算する」と読ませる（下のmd未満の規則）。 */
.bp-calculate-again {
    display: none;
}

/*
 * md未満。左右に割れないので、入力と結果をタブで切り替える（data-bp-tab）。**隠す側はdisplay: noneにする**——
 * 3Dビューアは、枠が画面に入っているかで描くかを決め（IntersectionObserver）、visibilityやopacityで隠した枠は
 * 入っていると答える。入力のタブに居るあいだ、3Dを描かず、詰める順の再生も進めない。
 *
 * 計算ボタンの帯は、割り方の枠の下端に置き、画面の下に留める（sticky）。枠は画面の高さを下回らないので、中身が
 * 短くても帯は画面の下に在る。fixedにしないのは、ページの終わりでフッタを覆わないため——覆わないための余白を
 * 取るには、止まった理由の行で変わる帯の高さを測らなければならない。要素を見える所まで送るときは、帯の高さの
 * 分だけ下を空ける（scroll-padding-bottom）——空けないと、送った要素が帯の下に入る。
 */
@media (max-width: 767.98px) {
    .bp-split {
        min-height: 100vh;
        min-height: 100svh;
    }

    .bp-split[data-bp-tab="input"] .bp-split-result,
    .bp-split[data-bp-tab="result"] .bp-split-input {
        display: none;
    }

    .bp-action-bar {
        position: sticky;
        bottom: 0;
        z-index: 1020;
        margin-top: auto;
        margin-inline: calc(var(--bs-gutter-x, 1.5rem) * -0.5);
        padding: 0.75rem calc(var(--bs-gutter-x, 1.5rem) * 0.5) calc(0.75rem + env(safe-area-inset-bottom, 0px));
        background-color: var(--bp-surface);
        border-top: 1px solid var(--bs-border-color);
    }

    .bp-split[data-bp-tab="result"]:has([data-bp-result]:not(.d-none)) .bp-calculate-first {
        display: none;
    }

    .bp-split[data-bp-tab="result"]:has([data-bp-result]:not(.d-none)) .bp-calculate-again {
        display: inline;
    }

    html:has(.bp-action-bar) {
        scroll-padding-bottom: 7rem;
    }

    /*
     * 表を1行1カードに組み替える（bp-cards）。列を横に並べたまま狭い幅に入れると、入力欄が1文字ぶんになる。
     * 列見出しの代わりに、欄のラベル（data-label）を値の前に、単位（data-unit）を値の後ろに出す。行の見出しはカードの
     * 見出しになり、［×］（bp-card-close）はその右に置く。選んでいる行は、カードごと背景を替える。
     */
    .bp-cards,
    .bp-cards > tbody {
        display: block;
        background-color: transparent;
    }

    .bp-cards > thead {
        display: none;
    }

    .bp-cards > tbody > tr {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        align-items: center;
        gap: 0.25rem 0.5rem;
        margin-bottom: 0.5rem;
        padding: 0.5rem 0.75rem;
        background-color: var(--bp-surface);
        border: 1px solid var(--bs-border-color);
        border-radius: var(--bs-border-radius);
    }

    .bp-cards > tbody > tr.table-active {
        background-color: var(--bp-tile);
        border-color: var(--bp-primary-soft);
    }

    /* 閉じた行（画面のJavaScriptが開け閉めする）。md以上では、表のすべての行が見える。 */
    .bp-cards > tbody > tr[data-bp-cargo-closed] {
        display: none;
    }

    .bp-cards > tbody > tr > * {
        grid-column: 1 / -1;
        display: flex;
        align-items: center;
        gap: 0.5rem;
        padding: 0;
        background-color: transparent;
        border: 0;
        box-shadow: none;
    }

    .bp-cards > tbody > tr > th {
        grid-column: 1;
        font-weight: 700;
    }

    .bp-cards > tbody > tr > .bp-card-close {
        grid-column: 2;
        grid-row: 1;
    }

    .bp-cards td[data-label]::before {
        content: attr(data-label);
        flex: 0 0 4em;
        color: var(--bs-secondary-color);
    }

    .bp-cards th[data-label]::before {
        content: attr(data-label);
    }

    .bp-cards td[data-unit]::after {
        content: attr(data-unit);
        flex: 0 0 1.5em;
    }
}

/*
 * 3Dだけの全面（段3）。3Dの部品ごとを、ページの見出しの行の下から画面の下端まで広げる。ほかの部品は
 * 見えなくするだけである。ページはスクロールさせない——見出しの行がずれると、全面の枠との間が開く。
 */
html:has(.bp-split[data-bp-stage="3"]),
html:has(.bp-split[data-bp-stage="3"]) body {
    overflow: hidden;
}

.bp-split[data-bp-stage="3"] {
    visibility: hidden;
}

.bp-split[data-bp-stage="3"] .bp-viewer {
    position: fixed;
    inset: var(--bp-full-top, 0) 0 0 0;
    z-index: 1030;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.75rem 1rem;
    visibility: visible;
    background-color: var(--bp-surface);
    border-top: 1px solid var(--bs-border-color);
}

.bp-split[data-bp-stage="3"] .bp-viewer-tools {
    margin-bottom: 0;
}

.bp-split[data-bp-stage="3"] .bp-viewer-frame {
    flex: 1 1 auto;
    height: auto;
    min-height: 0;
}

/* 全面のときだけ出す部品と、全面では出さない部品（全面では、描いている名前を上端の帯が受け持つ）。 */
.bp-split:not([data-bp-stage="3"]) [data-bp-full-only],
.bp-split[data-bp-stage="3"] .bp-viewer-name {
    display: none;
}

/* 表で選んでいる行。印（>）と背景の両方で示す——色だけで伝えない。印の幅は選んでいない行にも空けておき、名前が動かない。 */
.bp-row-select {
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-align: start;
}

.bp-row-mark {
    display: inline-block;
    width: 1.25em;
    visibility: hidden;
}

.bp-row-select[aria-current="true"] .bp-row-mark {
    visibility: visible;
}

tr[data-bp-row] {
    cursor: pointer;
}

/*
 * 3Dビューア。道具の行と全面の帯は、左右の端に寄せ、入らなければ折り返す——順は変えない。
 */
.bp-viewer-tools,
.bp-viewer-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

.bp-viewer-tools {
    margin-bottom: 0.5rem;
}

.bp-viewer-bar-group {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.bp-viewer-angle {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    margin: 0;
}

.bp-viewer-angle .form-control {
    width: 4.5em;
}

/*
 * 描く枠。地は淡い灰で、描く面（canvas）は透かして地を見せる。高さは決めておき、中身だけが入れ替わる——
 * 描いても描かなくても、周りが動かない。
 */
.bp-viewer-frame {
    position: relative;
    height: 22rem;
    overflow: hidden;
    background-color: var(--bp-viewer-ground);
    border: 1px solid var(--bs-border-color);
    border-radius: var(--bs-border-radius);
}

@media (min-width: 992px) {
    .bp-viewer-frame {
        height: clamp(22rem, 60vh, 40rem);
    }
}

.bp-viewer-canvas,
.bp-viewer-canvas > canvas {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
}

/* 描く面の絵は、縦横の倍率を保ったまま枠の中に収める。描く面の画素の数は、枠の大きさが変わり終えたときにだけ
   合わせ直す（3DビューアのJavaScript）——そのあいだに枠いっぱいへ引き伸ばすと、描いた立体が縦横で違う倍率に伸びる。
   収まらない余白には、枠の地が見える。 */
.bp-viewer-canvas > canvas {
    object-fit: contain;
}

/* 指の操作を、ページのスクロールではなく絵の操作として受ける。描いていない枠は見えなくしてあり、効かない。 */
.bp-viewer-canvas {
    touch-action: none;
    cursor: grab;
}

/* 枠の中の左上。描いている名前と、何個目の箱を描くかのボタン。そのあいだをつかんでも絵を回せる。 */
.bp-viewer-label {
    position: absolute;
    top: 0.5rem;
    left: 0.75rem;
    right: 0.75rem;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    pointer-events: none;
}

/* 枠の中の下端。詰める順の再生の帯で、出し入れしても枠の大きさを変えない。そのあいだをつかんでも絵を回せる。 */
.bp-viewer-replay {
    position: absolute;
    bottom: 0.5rem;
    left: 0.75rem;
    right: 0.75rem;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    pointer-events: none;
}

.bp-viewer-label > *,
.bp-viewer-replay > * {
    pointer-events: auto;
}

.bp-viewer-packages {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
}

/* ［1個目］［2個目］…の横の、描いている箱の充填率。ボタンの高さの真ん中にそろえる。 */
.bp-viewer-package-fill {
    align-self: center;
    margin-inline-start: 0.25rem;
}

.bp-viewer-message {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0;
    padding: 1rem;
    text-align: center;
    color: var(--bs-secondary-color);
}

/* 見出しの中の、印（badge）を置く行。印の無い見出しでも、印が収まる高さを空けておく——並べた枠の行数が
   揃い、枠の下に置くボタンの高さが、枠をまたいで揃う。 */
.bp-badge-line {
    min-height: 1.5em;
}

/*
 * 2要素認証のQRコード。読み取るには周りに白い余白が要るが、Fortifyが描くQRコードは
 * 余白を持たない。地（--bp-band）は青みを帯びるので、白い面を敷いて余白にする。
 */
.bp-qr {
    display: inline-block;
    padding: 1rem;
    background-color: var(--bp-surface);
}

/*
 * 挿絵はアイコンとして文字の横に置く。大きさは画面の幅によらず固定する——
 * 幅に追従させると、狭い画面で絵だけが大きく残り、文字との主従が入れ替わる。
 * 下地と角丸は絵そのものが持つ（documents/design/screens.mdの挿絵の節）。
 */
.bp-art {
    flex: 0 0 auto;
    width: 3.5rem;
    height: 3.5rem;
}

/* 必須の印。色だけで伝えないよう、記号そのものを置く。 */
.bp-required {
    color: var(--bs-danger);
    font-weight: 700;
}

/* エラー画面。本文が短いため上下の余白を広げる。 */
.bp-notice {
    max-width: 40rem;
    margin-inline: auto;
    padding-block: 3rem;
    text-align: center;
}

.bp-notice .display-1 {
    color: var(--bs-secondary-color);
}

/*
 * クエリの数え方の図（documents/design/screens.mdの図解の部品）。絵は図解の部品の絵だけで、答え・回数・矢印は字で
 * 置き、Bootstrapのグリッドで並べる——字は狭い画面でも同じ大きさで読め、読み上げにも乗る。
 * 詰められた答えの緑と、詰められなかった答えの枠の灰は、この図の中でだけ使う。灰は箱の絵の線と同じ系統の色。
 */
.bp-query-figure {
    --bp-query-packed: #157347;
    --bp-query-line: #8a94a3;
}

.bp-query-caption {
    font-size: 0.9375rem;
}

.bp-query-label {
    font-size: 0.875rem;
    font-weight: 700;
    color: var(--bp-ink);
}

.bp-query-note {
    font-size: 0.875rem;
    color: var(--bp-ink-muted);
}

/* 矢印と「＋」。lg未満で縦に積む図は、矢印を下向きの字に替える（字の入れ替えはビューが持つ）。 */
.bp-query-arrow {
    font-size: 1.5rem;
    line-height: 1;
    color: var(--bp-ink-muted);
}

/* 組の絵（.bp-query-cargo）は欄の幅に追従させ、上限を置く——広い画面で絵だけが大きくなると、字との主従が入れ替わる。 */
.bp-query-cargo {
    width: 100%;
    max-width: 9rem;
    height: auto;
}

/* 箱の絵（.bp-query-carton）は固定の正方形。大きさの違いを見せる図は、同じ絵を幅で描き分ける。 */
.bp-query-carton {
    width: 4.5rem;
    height: 4.5rem;
}

.bp-query-carton-a {
    width: 3rem;
    height: 3rem;
}

.bp-query-carton-b {
    width: 3.75rem;
    height: 3.75rem;
}

.bp-query-carton-c {
    width: 4.5rem;
    height: 4.5rem;
}

.bp-query-carton-d {
    width: 5.25rem;
    height: 5.25rem;
}

.bp-query-carton-step {
    width: 3.5rem;
    height: 3.5rem;
}

.bp-query-engine {
    display: inline-block;
    padding: 0.5rem 1rem;
    font-weight: 700;
    color: var(--bp-ink);
    background-color: var(--bp-tile);
    border: 2px solid var(--bp-primary);
    border-radius: var(--bs-border-radius-sm);
}

.bp-query-engine-step {
    padding: 0.125rem 0.5rem;
    font-size: 0.8125rem;
}

/* 計算しなかった段。点線で、計算した段と形でも分ける——色だけで伝えない。 */
.bp-query-engine-stopped {
    color: var(--bp-ink-body);
    background-color: var(--bp-surface);
    border: 2px dashed var(--bp-query-line);
}

.bp-query-answers {
    max-width: 22rem;
}

/* 答え。詰められた答えは緑の枠と字で、ほかは灰の枠。答えの字そのものが違うので、色だけで伝えていない。 */
.bp-query-answer {
    display: block;
    padding: 0.25rem 0.75rem;
    font-size: 0.9375rem;
    font-weight: 700;
    line-height: 1.5;
    text-align: start;
    color: var(--bp-ink-body);
    background-color: var(--bp-surface);
    border: 2px solid var(--bp-query-line);
    border-radius: var(--bs-border-radius-sm);
}

.bp-query-answer-packed {
    color: var(--bp-query-packed);
    border-color: var(--bp-query-packed);
}

/* 電話の幅では、答えと計算の段の左右の余白を詰める——欄が狭く、余白のぶんで答えの語が途中で折れる。 */
@media (max-width: 575.98px) {
    .bp-query-answer {
        padding-inline: 0.5rem;
    }

    .bp-query-engine-step {
        padding-inline: 0.25rem;
    }
}

/* 答えに添えるAPIの応答のstatus。写して使う字なので、和欧間の空きを足さない。 */
.bp-query-status {
    display: block;
    font-family: var(--bs-font-monospace);
    font-size: 0.75rem;
    font-weight: 400;
    color: var(--bp-ink-muted);
    text-autospace: no-autospace;
}

.bp-query-request {
    display: inline-block;
    padding: 0.25rem 1rem;
    font-weight: 700;
    color: var(--bp-ink);
    background-color: var(--bp-surface);
    border: 2px solid var(--bp-ink);
    border-radius: 50rem;
}

/* 数えた回数。数えない段は、点線の白抜きで形でも分ける。 */
.bp-query-count {
    display: inline-block;
    padding: 0.125rem 0.75rem;
    font-size: 0.875rem;
    font-weight: 700;
    color: #fff;
    white-space: nowrap;
    background-color: var(--bp-primary);
    border-radius: 50rem;
}

.bp-query-total {
    font-size: 1rem;
    background-color: var(--bp-primary-dark);
}

.bp-query-uncounted {
    color: var(--bp-ink-muted);
    background-color: var(--bp-surface);
    border: 2px dashed var(--bp-query-line);
}

/* 図の中の、終わり方ごとの段。図の面（白）の上で、地の色で段を分ける。 */
.bp-query-lane {
    padding: 0.75rem;
    background-color: var(--bp-band);
    border-radius: var(--bs-border-radius-sm);
}

/*
 * トップのヒーロー。絵を字の後ろの層として敷き、字は絵の空いた側にだけ重ねる。
 * lg未満は縦長の絵を幅いっぱいに置き、小見出し・見出し・一文を絵の上の空きに重ね、入口と帯を絵の下に積む。
 * 絵は上下を切って正方形にする——上の空きの半分と下の端の段ボール箱を落とし、ノートPCは残す。字が空きより
 * 長いときは、絵を字の下へ押し下げる（絵は空きの高さだけ字の行に食い込む）——字をノートPCに掛けない。
 * lg以上は横長の絵を節いっぱいに敷き、高さに上限を付ける。切るのは左の空きの側で、ノートPCは残す。
 */
.bp-hero {
    --bp-hero-room: 30vw;
    position: relative;
    display: grid;
    grid-template-columns: 100%;
    background-color: var(--bp-surface);
}

.bp-hero-copy {
    position: relative;
    z-index: 1;
    grid-area: 1 / 1;
    min-height: var(--bp-hero-room);
    padding-top: 1.25rem;
}

.bp-hero-picture {
    grid-area: 2 / 1;
    margin-top: calc(-1 * var(--bp-hero-room));
}

/* 正方形に切ると、縦長の絵の上から30%（幅の0.3倍）が落ち、残る空きは幅の0.3倍になる。上の端は地へぼかす——
   字が長くて絵を押し下げたとき、絵の上の端が線に見えない。 */
.bp-hero-image {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 1 / 1;
    object-fit: cover;
    object-position: center 60%;
    -webkit-mask-image: linear-gradient(to bottom, transparent, #000 12%);
    mask-image: linear-gradient(to bottom, transparent, #000 12%);
}

.bp-hero-entrances {
    grid-area: 3 / 1;
    padding: 1.25rem 0 1.5rem;
}

.bp-hero-band {
    grid-area: 4 / 1;
    padding: 1.5rem 0;
    border-top: 1px solid var(--bp-line);
}

.bp-hero-band .bp-art {
    width: 3rem;
    height: 3rem;
}

/* 英字の小見出し。節の主題を、見出しの上で短く名指す。 */
.bp-eyebrow {
    margin-bottom: 0.5rem;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.3em;
    color: var(--bp-ink-muted);
}

.bp-hero-title {
    margin-bottom: 0.75rem;
    font-size: clamp(1.875rem, 1.1rem + 3.6vw, 4.75rem);
    font-weight: 900;
    line-height: 1.25;
    color: var(--bp-brand-ink);
}

.bp-hero-accent {
    color: var(--bp-primary);
}

.bp-hero-lead {
    margin-bottom: 0;
    font-size: clamp(0.9375rem, 0.82rem + 0.45vw, 1.375rem);
    line-height: 1.75;
    color: var(--bp-ink);
}

/* 入口の組。md未満は縦に積んで幅いっぱい、md以上は左右に並べる。一言は入口ごとに下へ添える。 */
.bp-entrances {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.bp-entrance {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
}

.bp-entrance .btn {
    width: 100%;
}

.bp-entrance-note {
    margin: 0.375rem 0 0;
    font-size: 0.875rem;
    color: var(--bp-ink-muted);
}

/* ボタンの後ろの「›」。字に混ぜない——入口の字は、ほかの画面の同じ行き先の入口と同じ字である。 */
.bp-go::after {
    content: "";
    display: inline-block;
    width: 0.5em;
    height: 0.5em;
    margin-left: 0.75em;
    vertical-align: 0.1em;
    border-top: 0.125em solid currentColor;
    border-right: 0.125em solid currentColor;
    transform: rotate(45deg);
}

/* 白抜きのボタンにも白い地を持たせる。地が透けると、写真の上で縁だけが残る。 */
.bp-go.btn-outline-secondary {
    --bs-btn-bg: var(--bp-surface);
}

.bp-band-title {
    margin-bottom: 0.25rem;
    font-size: 1.0625rem;
    font-weight: 800;
}

/* 節の見出し。英字の小見出しの下に大きく置く。 */
.bp-section-title {
    font-size: clamp(1.5rem, 1.2rem + 1.2vw, 2.25rem);
    font-weight: 900;
}

/* 小見出しの直後の見出しは、上を空けない。見出しの上の余白（:is(h1, h2…):not(:first-child)）は小見出しが持つ。
   その規則より詳細度を高くするため、同じ:not(:first-child)を重ねる。 */
.bp-eyebrow + :is(h1, h2):not(:first-child) {
    margin-top: 0;
}

/* 2つ目の入口の節。色を変えた枠に収め、ページの終わりで入口を見つけやすくする。 */
.bp-start {
    padding: 2rem 1.5rem;
    text-align: center;
    background-color: var(--bp-tile);
    border-radius: var(--bs-border-radius-lg);
}

@media (min-width: 768px) {
    .bp-entrances {
        flex-direction: row;
        flex-wrap: wrap;
    }

    .bp-entrance .btn {
        width: auto;
    }
}

@media (min-width: 992px) {
    .bp-hero {
        grid-template-rows: auto auto 1fr auto;
        min-height: min(66.667vw, 50rem);
    }

    .bp-hero-picture {
        position: absolute;
        inset: 0;
        grid-area: 1 / 1 / -1 / -1;
        margin-top: 0;
    }

    .bp-hero-image {
        height: 100%;
        aspect-ratio: auto;
        object-position: right center;
        -webkit-mask-image: none;
        mask-image: none;
    }

    .bp-hero-copy {
        min-height: 0;
        padding-top: 4rem;
    }

    /* 一言は写真の段ボール箱に掛かる。白い地を敷いて読ませる。 */
    .bp-entrance-note {
        display: inline-block;
        padding: 0 0.5rem;
        background-color: rgba(255, 255, 255, 0.85);
        border-radius: var(--bs-border-radius-sm);
    }

    .bp-hero-copy .container > * {
        max-width: min(36rem, 44vw);
    }

    .bp-hero-entrances {
        position: relative;
        grid-area: 2 / 1;
        padding: 2rem 0 3rem;
    }

    .bp-hero-band {
        position: relative;
        grid-area: 4 / 1;
        background-color: rgba(255, 255, 255, 0.92);
        border-top: 0;
    }
}

/* xxl以上は帯の特徴をすべて横に並べる。本文の幅（--bp-content-max-width）のままでは1列が狭く、帯の見出しが折れるので、
   ヒーローの中だけ幅を広げ、字と帯の左端をそろえる。 */
@media (min-width: 1400px) {
    .bp-hero .container {
        max-width: 1320px;
    }
}
