/* =====================================================================
   /apps/ — 開発ノートの "Dot Matrix" テーマを黒地へ反転した上書きレイヤー
   =====================================================================

   このファイルは単独では成立しない。必ずこの順で読むこと:

       design-system.css → site-nav.css → notes.css → apps.css

   地の方眼・点線ルール・h2 のドットリーダー・ステータスドット・
   タイムラインのドット柱は、すべて notes.css が持っている。ここは
   そのトークンを反転して、apps だけのコンポーネントを足すだけ。

   なぜ複製せずに借りるか: ドット語彙の定義が 2 系統になった瞬間、
   --dot-pitch や --rule-size が必ずズレる。開発ノートと同じ見た目で
   あることがこのページの狙いなので、血縁のまま繋いでおく。

   notes.css は編集しないこと（18 本のノートページが依存している）。

   ★ body の背景はここで一切書かない。--nzw-bg と --dot を反転すれば
     notes.css の body 規則がそのまま黒地に白ドットを描く。
     background: のショートハンドを書くとドットが消える。
   ===================================================================== */


/* ---------------------------------------------------------------------
   1. トークン反転
   notes.css の後に読むので、同じ specificity で後勝ちする
   ------------------------------------------------------------------ */
:root {
    /* 紙とインクを入れ替える。地の黒は .site-header--ink と同じ #0D0E0C。
       ★ 面の分離は「コントラスト比」ではなく L*（知覚的な明るさ）で決めている。
         この暗さの領域では比の式が圧縮されて当てにならない（#24261F ですら
         対ページ 1.26:1 にしかならないが、目には明らかに別の面に見える）。
         隣り合う面は ΔL* 6〜8 あれば「別の面」として読める。 */
    --nzw-bg:            #0D0E0C;   /* L* 3.8 */
    --nzw-card:          #1D1F19;   /* L* 11.4 / ΔL* 7.5。カードが地から浮く */
    --nzw-surface-1:     #141610;   /* L*  6.8 / ΔL* 3.0。カードより沈む面 */
    --nzw-surface-2:     #26281F;
    --nzw-surface-3:     #2F3128;

    --nzw-border:        rgba(255, 255, 255, 0.16);
    --nzw-border-strong: rgba(255, 255, 255, 0.42);
    --nzw-border-subtle: rgba(255, 255, 255, 0.09);

    --nzw-text:          rgba(255, 255, 255, 0.94);
    --nzw-text-strong:   rgba(255, 255, 255, 0.98);
    --nzw-sub:           rgba(255, 255, 255, 0.76);
    --nzw-muted:         rgba(255, 255, 255, 0.60);
    --nzw-on-accent:     #0D0E0C;

    /* アクセントもインク。色相での強調はしない（notes と同じ掟） */
    --nzw-accent:        rgba(255, 255, 255, 0.94);
    --nzw-accent-strong: rgba(255, 255, 255, 0.98);
    --nzw-accent-deep:   rgba(255, 255, 255, 0.98);
    --nzw-accent-light:  rgba(255, 255, 255, 0.60);
    --nzw-accent-soft:   #26281F;
    --nzw-accent-bg:     #141610;

    --nzw-blue:          rgba(255, 255, 255, 0.82);
    --nzw-blue-strong:   rgba(255, 255, 255, 0.94);
    --nzw-success:       rgba(255, 255, 255, 0.94);
    --nzw-success-soft:  #26281F;
    --nzw-warning:       rgba(255, 255, 255, 0.82);
    --nzw-warning-light: rgba(255, 255, 255, 0.42);
    --nzw-warning-soft:  #26281F;
    --nzw-danger:        rgba(255, 255, 255, 0.94);
    --nzw-danger-soft:   #26281F;

    /* ---- 状態の色 ----
       開発ノートには「色を情報に使わない」という掟があるが、それは読み物の
       ページの掟。ここは状態を見比べる台帳なので、色を 3 本目の手がかりに使う。
       ただし色だけに意味を持たせない：ドットの形（塗り/中抜き/半分/薄い）と
       日本語ラベルを必ず併記する。色覚のシミュレーションでは β版 と
       リリース予定 が近づくが、形とラベルで区別できる。
       いずれもカード地 #1D1F19 に対して AA 以上。 */
    --st-live:    #7FD8CB;   /* 公開中。元の apps.css の「今も動いているもの」 */
    --st-beta:    #E8B45C;   /* β版 */
    --st-planned: #9DB8F5;   /* リリース予定 */
    --st-stopped: #C98A78;   /* 開発中止 */
    /* 開発ノート一覧（notes.css）だけで使っている状態。このページには今の
       ところ出ないが、定義を欠くと紙地用の濃い色がそのまま黒地に乗るので
       黒地用も置いておく */
    --st-dist:    #8FC7DE;   /* 配布中 */
    --st-ops:     #BDAEEA;   /* 運用中 */
    --st-review:  #AAB2CC;   /* 審査中 */
    --strike-ink: #E08163;   /* やめた判断の朱書き。元の #E0603F を黒地用に明るく */

    /* ---- ドット語彙 ---- */
    --dot:      rgba(255, 255, 255, 0.10);   /* 地の方眼。黒地では紙より濃く打たないと消える */
    --dot-ink:  rgba(255, 255, 255, 0.92);   /* データ点としてのドット */
    --dot-weak: rgba(255, 255, 255, 0.40);   /* 点線ルール。区切りとして見える濃さまで上げる */

    /* --dot-pitch / --rule-dots / --rule-size / --nzw-radius-* は
       notes.css のまま。目の細かさは開発ノートと揃えておく */

    /* 各ページの SVG 図版が参照する旧テーマの残り */
    --topic-brand: rgba(255, 255, 255, 0.98);
    --brand:       rgba(255, 255, 255, 0.98);
    --brand-deep:  rgba(255, 255, 255, 0.98);
    --brand-light: rgba(255, 255, 255, 0.42);
    --brand-soft:  #26281F;

    /* 徘徊するブラックホール（/static/js/bh-ambient.js）の濃さ。
       既定の .8/.65 のままだと、紫の降着円盤がページで唯一の彩度として浮く */
    --bh-front-opacity:  0.5;
    --bh-behind-opacity: 0.32;
}

/* 彩度も落とす（色を情報に使わない掟に沿う）。完全な grayscale にしないのは、
   紫がわずかに残るほうが「Synapse Link のあれだ」と分かるため。
   開発ノートからブラックホールを外したとき（2026-09-19）に notes.css から移した */
.bh-ambient-canvas {
    filter: saturate(0.3);
}

/* ★ --nzw-card / --nzw-bg を半透明にしないこと。
   .status--live::before の box-shadow と .ms::before の background は
   「不透明な色で地を punch する」前提で、半透明だと二重丸のリングが抜ける。 */


/* ---------------------------------------------------------------------
   2. 明色の直書きを反転する
   notes.css は白地前提で #fff を数箇所に直書きしている。
   このページに出るのは下の 3 系統だけ。
   （.decision .d-head .v / .q .q-num / .steps .step::before /
     ul.check .box svg / .fig--ink も #fff 系だが、apps の
     マークアップには登場しない。将来足すときはここに反転を書き足すこと）
   ------------------------------------------------------------------ */
.logo { color: var(--nzw-bg); }

.filters .chip[aria-pressed="true"] { color: var(--nzw-bg); }
.filters .chip[aria-pressed="true"]::before { background: var(--nzw-bg); }
.filters .chip[aria-pressed="true"] .n { color: rgba(13, 14, 12, 0.62); }

.go { color: var(--nzw-bg); }

/* ★ アイコンはグレースケールにしない。
   notes.css は一覧の統一感を優先してモノクロにし、hover で色を出す。
   だがこのページではアイコンが「どのアプリか」を見分ける第一の手がかりで、
   灰色にすると 10 枚が判別できなくなる（実際それで読めなくなっていた）。 */
.logo img { filter: none; }
/* アイコンの下地。透過 PNG が黒地に溶けないよう中間色の板を敷く。
   文字だけのロゴ（G など）もこの板に載るので、字は明るい側にする
   （notes.css は白い板に濃い字を置く前提なので、そのままだと沈む） */
.logo {
    background-color: var(--nzw-surface-2);
    color: var(--nzw-text-strong);
}

/* ヘッダーのアクセント。既定の #7FD8CB はこのページ唯一の彩度になり、
   「色を情報に使わない」掟を破るのでインクへ寄せる。
   apps.css は /apps/ でしか読まないので他ページには波及しない */
.site-header--ink { --sh-accent: rgba(255, 255, 255, 0.92); }


/* ---------------------------------------------------------------------
   3. カード
   .note-card を base に、.app-card を variant として重ねる。
   notes では <a> だがここは <article> なので、リンクの手がかりを消す
   ------------------------------------------------------------------ */
.app-card::after { content: none; }                  /* 右下の "→" */
.app-card:hover { transform: none; border-color: var(--nzw-border-strong); }
.app-card:hover .card-foot time { opacity: 1; }      /* 日付を隠さない */

/* 本文を伸ばして、行内のカードの .card-foot の高さを揃える
   （notes では .desc がこの役をしている） */
.app-card .app-body { flex: 1 1 auto; }

.app-card .app-body p {
    margin: 0 0 var(--nzw-space-3);
    font-size: var(--nzw-text-sm);
    line-height: var(--nzw-leading-normal);
}
.app-card .app-body p:last-child { margin-bottom: 0; }

/* 何をするアプリか。カードで最初に読む行なので本文色で出す */
.app-card .desc { color: var(--nzw-text); }
/* 次に何が出るか */
.app-card .next { color: var(--nzw-sub); }
/* やめた判断。このページの声だが、理解の主役ではないので一段落とす */
.app-card .drop { color: var(--nzw-muted); font-size: var(--nzw-text-xs); }

/* 行の頭に、その行が何の行かを名乗らせる。色では区別できないので文字で */
.app-card .k {
    display: inline-block;
    margin-right: 0.6em;
    font-family: var(--nzw-font-mono);
    font-size: var(--nzw-text-xs);
    font-weight: var(--nzw-weight-bold);
    letter-spacing: 0.08em;
    color: var(--nzw-muted);
    border-bottom: 1px dotted var(--nzw-border-strong);
}

/* やめた判断の朱書き。元の apps ページが持っていた語彙を戻す。
   取り消し線だけだと、やめたのか続いているのかが黒地では読み取りにくい */
.strike {
    color: var(--strike-ink);
    text-decoration: line-through;
    text-decoration-color: rgba(224, 129, 99, 0.6);
    text-decoration-thickness: 1px;
}

.app-card .links-row { margin: var(--nzw-space-4) 0 var(--nzw-space-3); }

/* 詳細・ノート・更新履歴への細いリンク列 */
.app-card .more {
    display: flex; flex-wrap: wrap;
    gap: var(--nzw-space-2) var(--nzw-space-4);
    margin: 0 0 var(--nzw-space-4);
    font-family: var(--nzw-font-mono);
    font-size: var(--nzw-text-xs);
}
.app-card .more a {
    color: var(--nzw-sub);
    text-decoration: none;
    border-bottom: 1px dotted var(--nzw-border-strong);
}
.app-card .more a:hover { color: var(--nzw-text-strong); border-bottom-color: var(--nzw-text-strong); }

/* 開発を終えたものは、朱書きの明るい色ではなく落ち着いた色で名乗る。
   中止したアプリの名前が公開中のものより目立つのは順序が逆になる */
.app-card.is-stopped .card-head h3 .strike {
    color: var(--st-stopped);
    text-decoration-color: rgba(201, 138, 120, 0.55);
}

/* まだ出ていないものは枠を点線にする。押せるボタンも置かない */
.app-card.is-planned { border-style: dashed; background: var(--nzw-surface-1); }

/* 状態の色。ドットと文字の両方に効かせる（currentColor 経由で形も色づく） */
.status--live    { color: var(--st-live); }
.status--beta    { color: var(--st-beta); }
.status--planned { color: var(--st-planned); }
.status--stopped { color: var(--st-stopped); }
.status--live::before    { background: currentColor; box-shadow: 0 0 0 2px var(--nzw-card), 0 0 0 3px currentColor; }
.status--beta::before    { background: transparent; box-shadow: inset 0 0 0 2px currentColor; }
.status--stopped::before { background: transparent; box-shadow: inset 0 0 0 1.5px currentColor; }

/* 状態はカードの左端にも帯で出す。一覧を縦に走らせたとき、
   カードの中身を読まなくても状態の並びが分かる */
.app-card { border-left: 2px solid var(--nzw-border); }
.app-card[data-status="live"]    { border-left-color: var(--st-live); }
.app-card[data-status="beta"]    { border-left-color: var(--st-beta); }
.app-card[data-status="planned"] { border-left-color: var(--st-planned); }
.app-card[data-status="stopped"] { border-left-color: var(--st-stopped); }

/* ステータス：リリース予定＝半分塗り。
   塗り(公開中) / 中抜き(β) / 半分(予定) / 薄い中抜き(中止) の 4 シルエット。
   notes.css の .status--review と同じ幾何を、apps の語彙で別名にした */
.status--planned::before {
    background: linear-gradient(90deg, currentColor 50%, transparent 50%);
    box-shadow: inset 0 0 0 1.5px currentColor;
}


/* ---------------------------------------------------------------------
   4. 狭い画面
   ------------------------------------------------------------------ */
@media (max-width: 480px) {
    /* notes.css は 480px で .card-foot time の hover 制御を戻すが、
       こちらは常時表示なので何もしなくていい。
       .more は折り返しが効いているので追加指定も不要 */
    .app-card .k { margin-right: 0.4em; }
}


/* ---------------------------------------------------------------------
   5. 上段のスクリーンショット一覧
   スマホで動くアプリだけを横一列に並べる。ページを開いた瞬間に
   「何があるか」が絵で入るようにするための帯。
   ------------------------------------------------------------------ */
.gallery { margin: 0 0 var(--nzw-space-10); }

.gallery-strip {
    display: grid;
    /* ★ 列数を固定しないこと。repeat(6, ...) を直書きしていたころ、
       7 本目（Engly）が 2 行目に落ちて帯が折り返した。
       列を自動で増やす形にしておけば、アプリを足しても 1 行のまま。 */
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: var(--nzw-space-4);
}

.shot {
    display: block;
    text-decoration: none;
    color: inherit;
}

/* 画面そのもの。端末の枠は描かず、角丸の板として置く */
.shot-screen {
    display: block;
    position: relative;
    aspect-ratio: 600 / 1205;
    overflow: hidden;
    border-radius: 12px;
    background: var(--nzw-surface-2);
    border: 1px solid var(--nzw-border-strong);
    transition: border-color var(--nzw-duration) var(--nzw-ease),
                transform var(--nzw-duration) var(--nzw-ease);
}
.shot-screen img {
    width: 100%; height: 100%;
    object-fit: cover;
    object-position: top center;
    display: block;
}
.shot:hover .shot-screen,
.shot:focus-visible .shot-screen {
    border-color: var(--nzw-text-strong);
    transform: translateY(-3px);
}
.shot:focus-visible { outline: none; }
.shot:focus-visible .shot-screen { outline: 2px solid var(--nzw-text-strong); outline-offset: 2px; }

/* 名前と状態。下の一覧と同じ .status を使うので、色と形の意味が揃う */
.shot-cap {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin-top: var(--nzw-space-2);
}
.shot-name {
    font-size: var(--nzw-text-sm);
    font-weight: var(--nzw-weight-bold);
    color: var(--nzw-text-strong);
    line-height: 1.3;
}
.shot .status { font-size: 11px; }
.shot .status::before { width: 6px; height: 6px; flex-basis: 6px; }

.gallery-note {
    margin: var(--nzw-space-4) 0 0;
    font-family: var(--nzw-font-mono);
    font-size: var(--nzw-text-xs);
    color: var(--nzw-muted);
}

/* 飛び先のカードがヘッダーの下に隠れないようにする */
.app-card { scroll-margin-top: 96px; }

/* 狭い画面では縮めずに横スクロールさせる。
   7 枚を 375px に押し込むと 1 枚 50px になって何も見えないため */
@media (max-width: 860px) {
    .gallery-strip {
        display: flex;
        overflow-x: auto;
        scroll-snap-type: x proximity;
        -webkit-overflow-scrolling: touch;
        /* 画面端まで帯を伸ばしつつ、1 枚目は本文と同じ位置から始める */
        margin: 0 calc(-1 * var(--nzw-space-4));
        padding: 0 var(--nzw-space-4) var(--nzw-space-3);
        /* これが無いとスナップが padding を食って 1 枚目が画面端に貼り付く */
        scroll-padding-left: var(--nzw-space-4);
    }
    .shot {
        flex: 0 0 128px;
        scroll-snap-align: start;
    }
    /* スクロールバーもドットの語彙に寄せる */
    .gallery-strip::-webkit-scrollbar { height: 3px; }
    .gallery-strip::-webkit-scrollbar-thumb { background: var(--dot-weak); border-radius: 2px; }
    .gallery-strip::-webkit-scrollbar-track { background: transparent; }
}

@media (prefers-reduced-motion: reduce) {
    .shot-screen { transition: none; }
    .shot:hover .shot-screen { transform: none; }
}
