[{"data":1,"prerenderedAt":678},["ShallowReactive",2],{"content-/tsukumi-demo-grid-layout":3,"related-/tsukumi-demo-grid-layout":630,"all-pages-for-dir":676,"og-image-/tsukumi-demo-grid-layout":677},{"id":4,"title":5,"body":6,"category":611,"description":612,"extension":613,"meta":614,"navigation":554,"path":615,"project_name":616,"published":617,"publishedAt":618,"seo":619,"stem":620,"tags":621,"todo":628,"unpublished":617,"updatedAt":628,"__hash__":629},"pages/2026-06/2026-06-14/tsukumi-demo-grid-layout.md","社内 AI デモページ3本に Müller-Brockmann グリッドを当てる — 写真の高さがガタついたのは subgrid と box-sizing と translateY のせい",{"type":7,"value":8,"toc":577},"minimark",[9,14,77,80,84,88,94,101,103,107,122,125,151,154,156,160,163,168,171,174,176,180,183,204,212,215,229,231,235,238,243,253,256,264,274,281,291,305,311,317,332,337,340,342,346,349,354,357,368,371,399,402,404,407,410,413,420,431,435,442,451,454,456,459,463,466,472,481,491,497,503,507,520,528,538,540,543],[10,11,13],"h2",{"id":12},"tldr","TL;DR",[15,16,17,21,24,48,74],"ul",{},[18,19,20],"li",{},"社内 AI ワークショップ用の3つのデモページ（お菓子店・美容室・飲食店）を 12 列モジュラーグリッドに乗せ替えた",[18,22,23],{},"最初はヒーローだけ subgrid で「整数比だから乗ってるはず」と目視で済ませた → ユーザーから「写真の高さが合ってない」と突き返された",[18,25,26,27,39,40,43,44,47],{},"検証ハーネスを走らせたら ",[28,29,30,34,35,38],"strong",{},[31,32,33],"code",{},"product-row"," で 16px、",[31,36,37],{},"info-grid"," で 20px ズレていた","。",[31,41,42],{},"gap"," を ",[31,45,46],{},"var(--gutter)"," に揃え忘れていた",[18,49,50,51,61,62,61,68],{},"根本原因は3つ重なっていた: ",[28,52,53,56,57,60],{},[31,54,55],{},"grid-template-columns"," の ",[31,58,59],{},"1fr"," 問題","・",[28,63,64,67],{},[31,65,66],{},"box-sizing"," が content-box のまま",[28,69,70,73],{},[31,71,72],{},"translateY"," の装飾が残骸として効いていた",[18,75,76],{},"最終的に 3 ページ全要素 0.03px 以下まで詰めて、固定ナビ追加とサイドバー削除も同じ流れで整えた",[78,79],"hr",{},[10,81,83],{"id":82},"きっかけ-グリッドのスキル使ってちょっと整えて","きっかけ: 「グリッドのスキル使ってちょっと整えて」",[85,86,87],"p",{},"朝、社内 AI ワークショップ用のデモページ3本のグリッドレイアウトを整える依頼が飛んできた。お菓子店・美容室・飲食店の3業種で、それぞれ独自のテーマ色とフォントを当ててある。",[89,90,91],"blockquote",{},[85,92,93],{},"このお菓子のページとかデモページ作ってるんですけど、あと美容室と飲食店の3つですね。今日追加したグリッドデザインのスキルを使って、いい感じにグリッドレイアウトで整えてくれませんか。",[85,95,96,97,100],{},"今日追加した ",[31,98,99],{},"muller-brockmann-grid-systems"," スキルを当てる初の実戦。色やフォントは各ページの世界観として残し、骨格だけ 12 列モジュラーグリッドに乗せ替える方針で進めることにした。",[78,102],{},[10,104,106],{"id":105},"序盤-既存の-grid-systemcss-に乗っかる","序盤: 既存の grid-system.css に乗っかる",[85,108,109,110,113,114,117,118,121],{},"ディレクトリを見ると、すでに ",[31,111,112],{},"grid-system.css"," と ",[31,115,116],{},"useGridOverlay.ts"," が用意されていた。誰も使っていない状態のスキャフォールド。自分で作りかけた ",[31,119,120],{},"tsukumi-grid.css"," を削除して、既存資産に乗ることにした。",[85,123,124],{},"最初の作業はこの順番で進めた。",[126,127,128,141,148],"ol",{},[18,129,130,133,134,137,138,140],{},[31,131,132],{},"nuxt.config.ts"," に ",[31,135,136],{},"css:"," を追加して ",[31,139,112],{}," を読み込ませる",[18,142,143,144,147],{},"各ページのルート要素に ",[31,145,146],{},".gs-wrap .gs-grid"," を当てる",[18,149,150],{},"ヒーローセクションだけ subgrid 化して、タイトルを col 1-5、写真を col 6-12 に並べる",[85,152,153],{},"ここまではスムーズに動いた。グリッドオーバーレイを当てるとコラム1-5にタイトル、コラム6-12に写真がきれいに乗る。「いい感じだな」と思いながら、3ページとも同じ手順で進めて報告を投げた。",[78,155],{},[10,157,159],{"id":158},"ユーザーからの差し戻し-ちゃんと縦とか横とか揃えてくれていますか","ユーザーからの差し戻し: 「ちゃんと縦とか横とか揃えてくれていますか？」",[85,161,162],{},"報告を投げた直後、ユーザーから返ってきた。",[89,164,165],{},[85,166,167],{},"ごめん、待って。ちゃんと縦とか横とか揃えてくれていますか？スキルの検証ハーネス使って、ちゃんと確認してくれていますかね。",[85,169,170],{},"ここで手が止まった。正直に言うとヒーローセクションだけ subgrid で 0px 一致を確認していて、それ以外（ギフトセクション、商品行、料理行、店舗情報、FAQ など）は「整数比で目視で乗ってるはず」というレベルで放置していた。スキルが用意している verify ハーネスは一度も回していなかった。",[85,172,173],{},"謝罪して、検証ハーネスを全セクションで走らせることにした。",[78,175],{},[10,177,179],{"id":178},"verify-を回したら-16px-と-20px-ズレていた","verify を回したら 16px と 20px ズレていた",[85,181,182],{},"検証スクリプトで全主要グリッド要素の左右と基準コラム line の差分を測る。結果はすぐ出た。",[15,184,185,195],{},[18,186,187,188,191,192],{},"お菓子店ページの ",[31,189,190],{},".product-row"," が ",[28,193,194],{},"16px ズレ",[18,196,197,198,191,201],{},"美容室ページの ",[31,199,200],{},".info-grid",[28,202,203],{},"20px ズレ",[85,205,206,207,191,209,211],{},"原因は単純で、内部の ",[31,208,42],{},[31,210,46],{},"（24px）になっていなかった。6:6 の対称分割でも、内部 gap が外側の 24px と違うとコラム line と一致しない。整数比で乗っているように見えても、ピクセル単位では合っていなかった。",[85,213,214],{},"ここで作業を切り替えた。",[15,216,217,220,226],{},[18,218,219],{},"非対称分割（7:5 など）は素直に subgrid 化する",[18,221,222,223,225],{},"対称分割は gap を ",[31,224,46],{}," に揃える",[18,227,228],{},"フルブリードのセクションは内側ラッパーを追加して、その中でグリッドを継続する",[78,230],{},[10,232,234],{"id":233},"写真の高さが揃わない-これなんで写真の高さが合ってないんですか","写真の高さが揃わない: 「これなんで写真の高さが合ってないんですか？」",[85,236,237],{},"verify が通ったと報告したら、ユーザーからスクリーンショットが飛んできた。",[89,239,240],{},[85,241,242],{},"ごめん、だからマジでびっくりするんですけど、これなんで写真の高さが合ってないんですか？",[85,244,245,246,113,249,252],{},"美容室ページのスタイルカードが上下にガタついていた。verify は左右の ",[31,247,248],{},"left",[31,250,251],{},"right"," しか測っていなかったから、縦のズレを見落としていた。",[85,254,255],{},"ここでバグが3つ重なっていることが判明した。",[257,258,260,261,263],"h3",{"id":259},"原因1-translatey-の装飾が残っていた","原因1: ",[31,262,72],{}," の装飾が残っていた",[85,265,266,269,270,273],{},[31,267,268],{},".style-card:nth-child(even) { transform: translateY(...) }"," で偶数番目のカードを意図的に下にずらすデザインが残っていた。グリッドに乗せたあと、これを消し忘れていた。さらに ",[31,271,272],{},".style-card.reveal { translate: -28px 0 }"," の横スライドインが viewport 外で残っていて、初期状態のままだとカードが 28px 横にズレた状態で居座っていた。",[85,275,276,277,280],{},"縦スライドに変えて、",[31,278,279],{},"is-visible"," 前でも横ズレが起きないように修正。",[257,282,284,285,56,288,290],{"id":283},"原因2-grid-template-columns-repeat12-1fr-の-1fr-が拡張されていた","原因2: ",[31,286,287],{},"grid-template-columns: repeat(12, 1fr)",[31,289,59],{}," が拡張されていた",[85,292,293,294,296,297,300,301,304],{},"これが一番ハマった。",[31,295,59],{}," は内部的に ",[31,298,299],{},"minmax(auto, 1fr)"," として扱われる。子要素の ",[31,302,303],{},"min-content"," が大きいと、その列だけ拡張される。「スタイルと店内」の h2 が2段に折れていたのもこの影響で、box が狭くなって h2 の min-content と衝突していた。",[85,306,307,310],{},[31,308,309],{},"minmax(0, 1fr)"," に変えて、列幅が子要素に引っ張られないように固定。",[257,312,314,315,67],{"id":313},"原因3-box-sizing-が-content-box-のまま","原因3: ",[31,316,66],{},[85,318,319,320,323,324,327,328,331],{},"最大の地雷。プロジェクト全体に ",[31,321,322],{},"* { box-sizing: border-box }"," が当たっていなかった。",[31,325,326],{},".gs-wrap"," の中の要素はすべて content-box で計算され、padding を足すと box width が想定より大きくなる。",[31,329,330],{},".steps-section"," の box が 1703px になっていたのはこれが原因。",[85,333,334,336],{},[31,335,326],{}," 配下を border-box に統一して、ようやく計算と実測が一致するようになった。",[85,338,339],{},"修正後に再 verify を走らせて、お菓子店・美容室・飲食店すべて 0.03px 以下（事実上 0px）まで詰まった。",[78,341],{},[10,343,345],{"id":344},"縦に並んでしまう-subgrid-の継承が切れていた","縦に並んでしまう: subgrid の継承が切れていた",[85,347,348],{},"ユーザーから次の指摘が飛んできた。",[89,350,351],{},[85,352,353],{},"ここなんですが、レイアウトが普通に縦に並んでしまい、見づらいですね。",[85,355,356],{},"お菓子店ページを開くと、商品カードが横並びにならず縦1列で表示されていた。subgrid を指定しているのに2列扱いになっている。",[85,358,359,360,363,364,367],{},"詳細を追うと、",[31,361,362],{},".product-list"," の親 ",[31,365,366],{},".menu-section"," が block レイアウトだった。subgrid は親が grid container でないと継承できない。途中に block 要素が挟まると、そこで subgrid のチェーンが切れて単独 grid 扱いになる。",[85,369,370],{},"修正は素直だった。",[15,372,373,382,392],{},[18,374,375,377,378,381],{},[31,376,366],{}," を grid 化（",[31,379,380],{},".gs-grid"," を当てる）",[18,383,197,384,387,388,391],{},[31,385,386],{},".info-section","、飲食店ページの ",[31,389,390],{},".access-section"," も同じ問題があったので、まとめて grid 化",[18,393,394,395,398],{},"逆に ",[31,396,397],{},".access-inner"," は自分が独立 12 列 grid container だったため、subgrid 指定を追加していたのが裏目に出ていた。subgrid 指定を消して元に戻す",[85,400,401],{},"3 ページとも再 verify を通して、横並びが復活した。",[78,403],{},[10,405,406],{"id":406},"固定ナビとサイドバー削除",[85,408,409],{},"最後に2つ整えた。",[257,411,412],{"id":412},"各ページに固定ナビを追加",[85,414,415,416,419],{},"3 ページとも、上部に固定ナビを追加した。お菓子店ページなら「ギフト / 商品 / 店舗情報 / FAQ」のように、ページ内アンカーで section にジャンプできるようにした。",[31,417,418],{},"scroll-margin-top"," を 88px ほど確保して、ナビ下にちゃんと余白が残るように調整。",[85,421,422,423,426,427,430],{},"dev server が途中で落ちて再起動したり、リビルドで数十秒待たされたりしたが、3 ページとも ",[31,424,425],{},"#gift"," などに ",[31,428,429],{},"top=87.875"," で固定されてスクロールするのを確認できた。",[257,432,434],{"id":433},"index-ページのサイドバー-toc-を削除","index ページのサイドバー TOC を削除",[85,436,437,438,441],{},"index ページ（",[31,439,440],{},"/tsukumi-ai-workshop"," 自体）にはスクショ付きで「ここはいらない」と指摘されたサイドバーの目次があった。",[89,443,444],{},[85,445,446,450],{},[447,448,449],"span",{},"スクリーンショット"," 今回ここはいらないですね。",[85,452,453],{},"サイドバー TOC を消して、代わりに上部中央に他ページと同じ固定ナビ（チラシ文面 / 当日の進行 / 成果物 / プロンプト / 運用）を追加。メインコンテンツを 12 列フル幅に拡張して、メトリクスカードを col 1-3 / 4-6 / 7-9 / 10-12 でちょうど 4 等分に並ぶように組み直した。",[78,455],{},[10,457,458],{"id":458},"学び",[257,460,462],{"id":461},"verify-ハーネスを最初から回す","verify ハーネスを最初から回す",[85,464,465],{},"直接の敗因は、スキルが用意している verify ハーネスを最初から回さず「目視と理屈で済ませた」こと。ヒーローだけ subgrid で 0px 一致を確認した時点で「他も整数比だから乗ってるはず」と判断してしまった。実際は 16px と 20px ズレていた。",[85,467,468,469,471],{},"「整数比で計算上は乗っているはず」は、",[31,470,42],{}," の値が違うだけで一発で破綻する。スキル側に検証ハーネスが用意されているなら、最初から全要素で走らせるのが正解だった。",[257,473,475,477,478,480],{"id":474},"_1fr-ではなく-minmax0-1fr-を使う",[31,476,59],{}," ではなく ",[31,479,309],{}," を使う",[85,482,483,296,485,487,488,490],{},[31,484,287],{},[31,486,299],{}," 扱いになり、子要素の min-content で列幅が拡張される。Müller-Brockmann グリッドのように 12 列を厳密に守りたいときは、最初から ",[31,489,309],{}," で書くのが安全。",[257,492,494,496],{"id":493},"box-sizing-は最初に統一する",[31,495,66],{}," は最初に統一する",[85,498,499,500,502],{},"プロジェクトに ",[31,501,322],{}," が当たっていない状態でグリッドに乗せると、padding 付きの要素が想定より大きくなって計算が合わなくなる。グリッドシステムを導入する最初のステップで、ラッパー配下を border-box に統一しておくと後段の verify で詰まらない。",[257,504,506],{"id":505},"subgrid-の継承は親の-display-で切れる","subgrid の継承は親の display で切れる",[85,508,509,510,513,514,516,517,519],{},"subgrid を効かせたいときは、上位の grid container から子孫まで全部 grid container でつないでおく必要がある。途中に block の ",[31,511,512],{},"section"," を挟むとそこで継承が切れ、子の subgrid 指定は単独 grid container として扱われる。今回の ",[31,515,366],{}," → ",[31,518,362],{}," の縦並びはこれが原因だった。",[257,521,523,524,527],{"id":522},"装飾の-translate-は-viewport-外で残ることがある","装飾の ",[31,525,526],{},"translate"," は viewport 外で残ることがある",[85,529,530,531,534,535,537],{},"スクロール演出で ",[31,532,533],{},"translate: -28px 0"," のような初期状態を持たせていると、",[31,536,279],{}," 前のカードが横にズレた状態で居座る。verify が「初期状態」を測定するときに、装飾が verify を汚すケースがある。グリッド規律を厳密に守るページでは、初期状態が viewport 内に入らない設計にしておくか、縦方向のスライドに切り替える。",[78,539],{},[10,541,542],{"id":542},"残タスク",[15,544,547,560,566],{"className":545},[546],"contains-task-list",[18,548,551,556,557,559],{"className":549},[550],"task-list-item",[552,553],"input",{"disabled":554,"type":555},true,"checkbox"," 同じグリッドシステムを ",[31,558,440],{}," 配下の他のページにも展開する",[18,561,563,565],{"className":562},[550],[552,564],{"disabled":554,"type":555}," verify ハーネスを CI で走らせて、リグレッションを自動検知できるようにする",[18,567,569,571,572,43,574,576],{"className":568},[550],[552,570],{"disabled":554,"type":555}," ",[31,573,309],{},[31,575,112],{}," のデフォルトに昇格させる",{"title":578,"searchDepth":579,"depth":579,"links":580},"",2,[581,582,583,584,585,586,595,596,600,610],{"id":12,"depth":579,"text":13},{"id":82,"depth":579,"text":83},{"id":105,"depth":579,"text":106},{"id":158,"depth":579,"text":159},{"id":178,"depth":579,"text":179},{"id":233,"depth":579,"text":234,"children":587},[588,591,593],{"id":259,"depth":589,"text":590},3,"原因1: translateY の装飾が残っていた",{"id":283,"depth":589,"text":592},"原因2: grid-template-columns: repeat(12, 1fr) の 1fr が拡張されていた",{"id":313,"depth":589,"text":594},"原因3: box-sizing が content-box のまま",{"id":344,"depth":579,"text":345},{"id":406,"depth":579,"text":406,"children":597},[598,599],{"id":412,"depth":589,"text":412},{"id":433,"depth":589,"text":434},{"id":458,"depth":579,"text":458,"children":601},[602,603,605,607,608],{"id":461,"depth":589,"text":462},{"id":474,"depth":589,"text":604},"1fr ではなく minmax(0, 1fr) を使う",{"id":493,"depth":589,"text":606},"box-sizing は最初に統一する",{"id":505,"depth":589,"text":506},{"id":522,"depth":589,"text":609},"装飾の translate は viewport 外で残ることがある",{"id":542,"depth":579,"text":542},"dev","社内 AI ワークショップで作った3つのデモページ（お菓子店・美容室・飲食店）を、Müller-Brockmann グリッドシステムのスキルで12列モジュラーグリッドに乗せ替えた。最初は subgrid 継承ミスでカードが縦に並び、写真の高さも揃わず画面がガタついた。検証ハーネスを最初から回さず目視で済ませたのが直接の敗因。verify を走らせて 0px 一致まで詰めたあと、ナビ追加・サイドバー削除まで一気通貫で整えた記録。","md",{},"/tsukumi-demo-grid-layout","mdx-playground",false,"2026-06-14T00:00:00.000Z",{"title":5,"description":612},"2026-06/2026-06-14/tsukumi-demo-grid-layout",[622,623,624,625,66,626,627],"Müller-Brockmann","グリッドデザイン","Nuxt","CSS Subgrid","デモページ","デザインシステム",null,"0H5OJPPdPvFZFViaKLCkRlHBc_I-dZbd08KQLlcl5Sk",[631,642,651,660,668],{"title":632,"description":633,"path":634,"tags":635,"publishedAt":618,"updatedAt":628},"D2を試したら結局SVGダイアグラム・スキルを書き直すことになった話 — 同じページの6枚を全部Grid版で出し直す","テキストで図を書ける作図DSL「D2」をsvg-diagramスキルに組み込めるか検証した。D2は手書きSVGに完敗し、次に「装飾を厚くする」V2方向も実はアンチパターンだったと気づき、最終的にMüller-Brockmannグリッドに乗せる方向に着地。svg-diagramスキルに新しい grid-alignment.md ルールを追加し、同じページの6枚のSVG全部をGrid版で書き直した記録。","/svg-diagram-skill-upgrade",[636,637,638,639,640,622,627,641],"D2","SVG","Diagram","Vue","スキル設計","グリッド",{"title":643,"description":644,"path":645,"tags":646,"publishedAt":650,"updatedAt":628},"2026年1月26日の開発日記 - 月シミュレーター完成と税務アシスタントUI大改修","PR#55の月シミュレーター対応、日食・月食機能追加、tax-assistantのデザインシステム分割・勘定科目マスターDB化実装、3つの計画書策定を完了した充実の1日","/2026-01-26-diary",[647,639,624,627,648,649],"日記","DB設計","シミュレーター","2026-01-26T00:00:00.000Z",{"title":652,"description":653,"path":654,"tags":655,"publishedAt":618,"updatedAt":628},"カメラの露出シミュレーターを Nuxt のページに移植して、SS/F値/ISO の三角関係を体感する","logcamera.com の露出シミュレーターを参考に、シャッタースピード・絞り・ISO の3パラメータをスライダーで動かせるブラウザシミュレーターを Vue ページとして実装した。最初は『SS を変えると明るさだけが変わってブレが出ない』バグに気づき、効果学習モードと露出学習モードの2モードに分けて解決した記録。","/camera-exposure-simulator",[639,624,637,656,657,649,658,659],"カメラ","露出","EV","UI",{"title":661,"description":662,"path":663,"tags":664,"publishedAt":618,"updatedAt":628},"2026年6月14日の開発日記 — グリッドの夜が明けて、宅建Phase 1.5・台湾AIサーバー6社・Yahoo経由の貯蓄ゼロ報道を一次まで剥がす","/fudosan-toshi の9章を5STEPでグルーピングしてイントロを足し、ガイド全体のSVGをMüller-Brockmannグリッドに乗せ替え、その勢いで宅建教科書 Phase 1.5・カメラ露出シミュレーター・台湾AIサーバー半導体6社・Yahoo配信の『単身世帯3人に1人貯蓄ゼロ』報道の原典Excel検証まで進めた1日","/2026-06-14-diary",[647,622,641,637,665,666,667],"宅建","AIサーバー","統計リテラシー",{"title":669,"description":670,"path":671,"tags":672,"publishedAt":618,"updatedAt":628},"不動産投資ガイド /fudosan-toshi に5STEP構成のイントロを足し、9章すべてにパンクズを通した","tokibo の intro パターンを fudosan-toshi に転用し、9章を「全体観 / 何を買うか / 仕組み / 運営と出口 / 拡大とリスク」の5STEPでグルーピングしたイントロページを追加した。あわせて、ハブから章ページまで13ページに layout 経由でパンクズを差し込んで戻り導線を統一した記録。","/fudosan-toshi-intro-5step",[673,674,675,637,624],"fudosan-toshi","イントロダクション","パンクズリスト",[],"https://log.eurekapu.com/og/blog/tsukumi-demo-grid-layout.png?v=2026-06-14T00%3A00%3A00.000Z&title=%E7%A4%BE%E5%86%85%20AI%20%E3%83%87%E3%83%A2%E3%83%9A%E3%83%BC%E3%82%B83%E6%9C%AC%E3%81%AB%20M%C3%BCller-Brockmann%20%E3%82%B0%E3%83%AA%E3%83%83%E3%83%89%E3%82%92%E5%BD%93%E3%81%A6%E3%82%8B%20%E2%80%94%20%E5%86%99%E7%9C%9F%E3%81%AE%E9%AB%98%E3%81%95%E3%81%8C%E3%82%AC%E3%82%BF%E3%81%A4%E3%81%84%E3%81%9F%E3%81%AE%E3%81%AF%20subgrid%20%E3%81%A8%20box-sizing%20%E3%81%A8%20translateY%20%E3%81%AE%E3%81%9B%E3%81%84&author=Kei%20Komatsu&sig=aef3c2afd9301b08",1781483080639]