黒地のMarpテーマ(minorun-dark)でスライドを組むときのデザインバランスと検査。余白の測り方、縦のバランス、配色の決め方、表・コード・補足ボックスの確定デザイン、Marp固有の罠、書き出し後の検査手順。「スライドのバランスを整えて」「色を変えて」「余白が変」「黒地のテーマで作って」と言われたら読む。
npx skills add https://github.com/minorun365/minorun-marp-skill --skill slide-design-dark
黒地のスライドは、白地より粗が目立つ。余白の不揃い、沈んだ色、下端に張り付いた図は、投影した瞬間に分かる。このスキルは、作者(みのるん)が黒地テーマで登壇資料を作るなかで固めた規則と検査をまとめたもの。
テーマ本体は theme/minorun-dark.css、検査スクリプトは tools/ にある。
---
marp: true
paginate: true
theme: minorun-dark
---
| クラス | 用途 |
|---|---|
| top | タイトルスライド。中央寄せ、下の帯にテーマ色、ページ番号なし |
| crosshead | 中扉。上下中央、白文字、ページ番号なし |
| image-full | 見出しと大きな画像 |
| split | 左に本文、右に画像。![bg right:40% contain] と組み合わせる |
太字 は黄色、*斜体* は薄いシアンで表示される<style> か、そのスライドだけの <style scoped> に書く「もう少し上へ」「余白をあけて」と言われて、値を勘で足し引きしない。根拠の無い数字で触ると、直したつもりの箇所が別の要素とぶつかり、同じ指摘を何巡も受ける。
mutool draw -F stext -o - deck.pdf | rg '<line bbox=' # 本文の行ごとの位置
塗りの面(ボックスや帯)はテキスト抽出に出ないので、ページを画像に焼いて色の連なりから取る。測ったら、位置を足し算ではなく規則で決める。
左右の余白が167対168、上下が60対65のように両側の差が数pxなら、バランスは取れている。ずれていたら、その数字がそのまま直す量になる。
PDFの座標は960×540、MarpのCSSは1280×720が基準なので、係数0.75を掛けて換算する。
素材を差し替えただけで見せない。図や写真を入れ替えたら、同じ作業のなかで幅、四方の余白、見出しとの間隔、隣の要素との重なりまで整える。入れ替えは作業の半分で、残りの半分がレイアウトの調整である。
position: relative; top: <差の半分>px で下げるsection は display: block なので、margin: auto 0 では縦中央に寄らない。表も display: block なので、中央へ寄せるには display: table; width: auto; margin: <上の空き> auto 0 と書くデザインの直し方を発明しない。バランスが悪いと言われたら、まず同じ構成のスライドを過去のデッキから探して真似る。新しいCSSの型を作るのは最後の手段で、作るなら先に1スライドだけ試して見せる。
感覚で色を選び直さない。黒との明度比、トーン、面積の3つの物差しで決める。
def lin(c):
c /= 255
return c/12.92 if c <= 0.03928 else ((c+0.055)/1.055)**2.4
def L(h):
h = h.lstrip('#'); r,g,b = (int(h[i:i+2],16) for i in (0,2,4))
return 0.2126*lin(r) + 0.7152*lin(g) + 0.0722*lin(b)
def vs_black(h): return (L(h)+0.05)/0.05 # 黒背景との比
def vs_white(h): return 1.05/(L(h)+0.05) # 上に乗せる白文字との比
| 用途 | 黒との明度比の目安 |
|---|---|
| 見出し、線、枠(黒の上の文字と細い線) | 10〜12 |
| ベタ塗りの面(上に白文字を乗せる) | 6〜7 |
| 図の主役の箱の地(白文字あり) | 4.5〜5.5 |
| 本文に置く補足ボックスの地 | 2.5〜3.0 |
| 図の中の脇役の箱の地 | 1.5前後 |
基準として、シアン #00c4e4 は10.0、純黄 #ffff00 は19.6である。見出しの色が10を切ると、濃く沈んで見える。
本文に置いて読ませる補足ボックスを、脇役の箱と同じ1.5で作らない。背景と同化する。作者の例では #2f2f37(1.58)が沈み、#555561(2.86)で枠が立った。上限を決めるのは枠の中に置く強調色で、黄色の強調を載せるなら、地と黄色の比が6を切らないところで止める。
面を明るくするほど白文字が読めなくなる。白の大きな太字(25pt前後)を乗せるなら白との比3.0が下限、図の中の小さめの文字(17〜19px)なら4.0以上。白文字のまま面をもっと明るく、という要望は両立しないので、上限にあることを数字で示してから文字色を変える案を出す。
同じ色を、大きな塗りの面と細い文字の両方に使うと、面は明るく、文字は沈んで見える。「表紙の色はいいのに本文の色が濃い」と言われたら、まずこれを疑う。文字と細い線に使う色を、面の色より1〜2段明るくする。明度比が倍近く違っても、画面ではだいたい同じ明るさに見える。
色相環の距離だけで判断しない。明度と彩度が揃っていないほうが、原因として多い。片方が白を含む淡い色で、もう片方が原色だと、色相が近くてもぶつかる。
直す順番は、まず明度と彩度を相手に寄せる、それでも駄目なら色相を離す、である。色相を動かすと色の意味まで変わる(黄色の強調を緑にすると「成功」に読める)ので、最後の手段にする。
黒地の表や図がのっぺりして見えるなら、全部が白(明度比21)になっている。主役の色は動かさず、見出し、罫線、ラベルのほうを落として段差を作る。段差は倍々が目安(21 → 10 → 6 → 3)。1.5倍以内では変えた気がしない。投影する資料のヘッダは10前後で止める。会場のプロジェクタは黒が浮くので、7を切ると読みにくい。罫線は色と一緒に太さも落とす。
公式サイトのCSSやドキュメントの設定から色コードを取る。ブランド色をそのまま文字に使うと黒地では読みづらいので、用途で明度を変える。
色見本や数字だけでは決まらない。同じページを候補の数だけ書き出して、2×2のグリッドに並べる。本文の強調が乗るスライドと、図の中で使われるスライドの2つで比べる。1つだけだと、図の中の他の色との相性を見落とす。
「気にしない色」を除外条件にした検索を使わない。同じ行に対象の色と除外する色が両方あると、行ごと消えて見落とす。置き換える色そのもので探し、置換後に旧色が0件になることを確かめる。SVGに残りやすい。
rg -n -i '#00c4e4|#5ec4d0|#a8e0e8' deck.md images/*.svg
太字 を使わない。テーマ既定の表はセルがグレーなので、黄色が沈むどれも、何度か作り直して落ち着いた形である。
テーマ既定のグレー地の表も、黒いカード地にテーマ色の小見出しを付けた表も、洗練されて見えなかった。通ったのは、地を塗らず細い罫だけの形。
table { width:100%; border-collapse:collapse !important; background:transparent !important; border:none !important; font-size:22pt; }
table thead, table tbody, table tr { background:transparent !important; border:none !important; }
table th { background:transparent !important; color:#a09aa4 !important; font-weight:600; font-size:18pt; letter-spacing:.06em;
text-align:left; padding:0 .7em .55em; border:none !important; border-bottom:1px solid #3a3640 !important; }
table td { background:transparent !important; color:#e9e6ec !important; padding:.5em .7em; line-height:1.4;
border:none !important; border-bottom:1px solid #221f28 !important; vertical-align:top; }
table tr:last-child td { border-bottom:none !important; }
table td:first-child { color:#ffffff !important; font-weight:700; white-space:nowrap; }
td だけを透明にすると、テーマ既定の tr の背景が透けて、白地に白文字になる。table / thead / tbody / tr にも必ず当てるwhite-space: nowrap を当てて、はみ出したら文言を削る。自動の折り返しに任せると、最後の1文字だけが2行目に落ちるrgba(255,226,120,.16))。6行以上の比較表では必須td の padding を詰めるテーマ既定の白地の pre も、黒いウィンドウに信号機のドットを付けた形も、通らなかった。通ったのは、半透明のグラデーションの地に、上端へテーマ色のラインを引き、文字はモノトーンで要点だけ色を付けた形。
.win { position:relative; border-radius:18px; margin:8px 0 28px; padding:22px 0 4px; overflow:hidden;
background:linear-gradient(165deg, rgba(255,255,255,.10) 0%, rgba(255,255,255,.045) 100%);
border:1px solid rgba(255,255,255,.14); box-shadow:0 18px 44px rgba(0,0,0,.45); }
.win::before { content:""; position:absolute; left:0; right:0; top:0; height:3px;
background:linear-gradient(90deg, #00c4e4 0%, #7fe3f5 45%, rgba(127,227,245,0) 100%); }
.win pre { background:transparent !important; box-shadow:none; margin:0; padding:0 28px 16px; font-size:21.5pt; line-height:1.15; }
.win pre code { color:#f2f1f5; }
本文の下の空きへ、濃い灰色の角丸ボックスを置き、補足の1行を入れる型。
.gbox { position: absolute; left: 0; right: 0; margin: 0 auto;
width: fit-content; min-width: 990px; max-width: 1088px;
bottom: 64px; background: #555561;
border-radius: 18px; padding: 16px 70px; text-align: center; }
.gbox, .gbox p { font-size: 27pt; line-height: 1.38; }
.gbox p { margin: 0; }
.gbox.up { bottom: 104px; } /* 本文が短く、下の空きが広いスライド */
left:50% と translateX(-50%) で中央に寄せない。使える幅が画面の右半分だけになり、収まるはずの文が折り返すmin-width で、複数のスライドのボックス幅を揃える。いちばん長いスライドの自然な幅を測って下限にするfont-size は .gbox と .gbox p の両方に当てる。div の中のMarkdownは <p> が生成されないことがある強調枠を薄い網掛けにしない。黒地では沈んで読めない。テーマ色のベタ塗りに濃い色の太字を乗せる。
「0.35秒と1.34秒」のような比較は、数字を88ptで2つ並べ、下に1行。細い縦線1本で左右を分ければ足りる。料金の行や注記を足すと、文字が詰まり配色が崩れる。
箱の中には中身だけを入れる。箱が何であるかの名前は、箱の上14pxに小さく置く。
![bg right:40%] で置くと右端に密着する。![w:720 center] で中央に置き、border-radius:14px を掛ける。2枚を左右に並べるときは、縦横比を揃える。片方だけ縦長だと、説明の開始位置が左右でずれる。
強調 は効かず、アスタリスクがそのまま出る。<strong> で書く。書き出したPDFで確かめる mutool draw -F stext -o - deck.pdf | grep -c 'c="\*"' # 0 が正常
</div> の直後に空行なしで --- を書くと、スライドの区切りとして認識されず、ページが1つ減る。スクリプトでタグを削除したあとは、ページ数を確かめる<img> のインライン style 属性は落とされる。クラスで書く\n---\n で分割すると、先頭はフロントマターになる。最初のスライドは2番目の要素で、そこにはデッキ全体の <style> が同居していることが多い。表紙を作り直すつもりで丸ごと置き換えると、全ページのスタイルが消える。症状は表紙ではなく他のページに出るassert で確かめる--- を数えて対応付けると、フロントマターの区切りの分だけずれる。そのページだけ画像に焼き、写っている文言で原稿を検索して直す pdftoppm -png -r 80 -f 36 -l 36 deck.pdf /tmp/p36
<style scoped> の独自フォント指定を標準フォントへ差し替えるMarpは、版面からコンテンツがあふれてもエラーを出さない。書き出すたびに検査を通す。
marp --no-stdin deck.md --pdf --theme theme/minorun-dark.css --allow-local-files
python3 tools/check-dark-margins.py deck.pdf # 中身の下端と右端の空き。60px未満でNG
python3 tools/check-dark-gaps.py deck.pdf # 画像、図、コードの箱と隣の本文の間隔。36px未満でNG
python3 tools/check-figure-text.py deck.pdf # 図の中の16pt未満の文字、縁まで14px未満の文字
node tools/check-svg-box-fit.mjs images/*.svg # SVGを描画して文字と枠の余白を実測
黒地の下端は、テキストの位置ではなく、黒でないピクセルの最下行で測る。コードの箱も図も挿絵も拾える。
NGは全件を列挙してから要約する。先に要約すると、3件目を見落とす。
検査が全部OKでも、目視は省けない。検査は存在する要素を測る仕組みなので、要素が丸ごと描かれなかった崩れは1つも検出できない。検査OKの報告と、目視の報告は分けて書く。
pdftoppm -png -r 55 deck.pdf /tmp/all/p # 全ページを小さく焼き、数ページずつ貼り合わせて順に見る
目視でしか捕まらないものは、文字と挿絵や図形の重なり、下方向の余白のつぶれ、矢印の軸が隠れて矢尻しか見えない状態、見出しの大きさや位置のページ間の不揃い、不自然な改行、挿絵の入れ忘れである。
吹き出しのしっぽ、矢印、帯のように、別の図形を要素の上に重ねたものは、縮小した全ページ画像では合格に見える。崩れるのは付け根や継ぎ目の数pxで、そこは縮小画像では1〜2ピクセルにつぶれている。重ねたページだけ高解像度で焼き直し、付け根の周囲を300%に拡大して見る。
mutool draw -r 200 -o hi.png deck.pdf 2
magick hi.png -crop 420x300+880+500 +repage -resize 300% tail.png
1ページを直したら、同じ観点で全ページを点検してから報告する。1ページの指摘は、そのページの指摘ではなく検査の指示である。同じ条件を全ページに機械で当て、一覧を出してから直す。直したら同じ検査をもう一度全ページに当て、0件になったことを報告に書く。
Take minorun365/slide-design-dark from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.