/* 個人サイト — 構造と共通の作り。
 * 見た目の値はすべてカスタムプロパティに出してあり、theme-*.css が上書きする。
 * ここには「どのテーマでも同じであるべき挙動」だけを置く。 */

:root {
  /* 色 */
  --bg: #0b0b0d;
  --bg-elev: #141418;
  --fg: #e8e8ea;
  --fg-dim: #8b8b96;
  --line: #26262e;
  --accent: #d7b26a;
  --scrim: linear-gradient(to top, rgba(0, 0, 0, .72) 0%, rgba(0, 0, 0, 0) 55%);

  /* 版面 */
  --page-max: none;
  --page-pad: 20px;
  --page-pad-top: 22px;

  /* グリッド */
  --col: 280px;
  --col-mobile: 150px;
  --gap: 12px;
  --row: 8px;
  --radius: 10px;

  /* 文字 */
  --font-ui: "Segoe UI", "Yu Gothic UI", system-ui, sans-serif;
  --font-cap: var(--font-ui);
  --font-num: ui-monospace, "Consolas", monospace;
  --fs-body: 15px;
  --fs-cap: 12px;
  --brand-size: 17px;
  --brand-weight: 650;
  --brand-track: .06em;
  --nav-size: 14px;
  --nav-track: 0;
  --nav-transform: none;

  /* タイル */
  --tile-hover-scale: 1.02;
  --tile-hover-bright: 1;
  --bar-bg: rgba(11, 11, 13, .82);
  --bar-blur: blur(12px);
}

* { box-sizing: border-box; }

html {
  background: var(--bg);
  scrollbar-color: #3a3a44 var(--bg);
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: var(--fs-body) / 1.6 var(--font-ui);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: inherit; text-decoration: none; }
::selection { background: var(--accent); color: #000; }

:where(a, button, .tile):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* 数字は幅を揃える（件数・尺・解像度が並ぶと揺れが目立つ） */
.n, .badge, .lb-info { font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------------- header */
.bar {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: baseline;
  gap: 22px;
  flex-wrap: wrap;
  padding: 13px var(--page-pad);
  background: var(--bar-bg);
  backdrop-filter: var(--bar-blur);
  border-bottom: 1px solid var(--line);
}

.brand {
  font-size: var(--brand-size);
  font-weight: var(--brand-weight);
  letter-spacing: var(--brand-track);
}

.r18tag {
  margin-left: 8px;
  padding: 1px 6px;
  border: 1px solid #7b3b3b;
  border-radius: 4px;
  color: #e08a8a;
  font-size: 11px;
  letter-spacing: .04em;
  vertical-align: 2px;
}

.bar nav { display: flex; align-items: baseline; gap: 2px; flex-wrap: wrap; }

.bar nav a {
  padding: 5px 12px;
  border-radius: 999px;
  color: var(--fg-dim);
  font-size: var(--nav-size);
  letter-spacing: var(--nav-track);
  text-transform: var(--nav-transform);
  transition: color .15s, background .15s, border-color .15s;
}

.bar nav a:hover { color: var(--fg); background: var(--bg-elev); }
.bar nav a.on { color: var(--bg); background: var(--fg); }
.bar nav a .n { margin-left: 7px; font-size: 11px; opacity: .55; }
.bar nav a.x { color: var(--accent); }

/* ---------------------------------------------------------------- page */
main {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: var(--page-pad-top) var(--page-pad) 80px;
}

.tagline {
  margin: 0 0 22px;
  color: var(--fg-dim);
}

/* 柱・扉・コロフォンは plate テーマの誌面構造。
   他テーマはヘッダのブランド表記で足りるので隠す。 */
.folio, .masthead { display: none; }

.sheet { position: relative; }

/* 彫り込み罫（上に暗い線、下に明るい線を重ねて凹んで見せる）。テーマが色を与える */
.rule {
  flex: 1;
  height: 3px;
  border-top: 1px solid var(--rule-hi, var(--line));
  border-bottom: 1px solid var(--rule-lo, transparent);
}

/* ---------------------------------------------------------------- toolbar */
.toolbar {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 18px;
  color: var(--fg-dim);
  font-size: 12px;
}

.toolbar[hidden] { display: none; }

.tb-sort { display: flex; align-items: center; gap: 7px; }
.tb-sort span { letter-spacing: .1em; }

.toolbar select {
  padding: 8px;
  min-height: 36px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--bg-elev);
  color: var(--fg);
  font: inherit;
  cursor: pointer;
}

.tb-liked {
  padding: 9px 14px;
  min-height: 36px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--fg-dim);
  font: inherit;
  cursor: pointer;
  transition: color .15s, border-color .15s, background .15s;
}

.tb-liked:hover { color: var(--fg); }
.tb-liked.on { background: var(--fg); border-color: var(--fg); color: var(--bg); }

#likecount { margin-left: auto; font-variant-numeric: tabular-nums; opacity: .8; }

/* 並べ替え中は月の区切りが意味を失うので、見出しと空になった葉を隠す */
body.sorting .leaf-head { display: none; }
body.sorting .leaf + .leaf { display: none; }

/* ---------------------------------------------------------------- 葉（月ごとの区切り） */
.leaf { margin-bottom: 44px; }
.leaf:last-child { margin-bottom: 0; }

.leaf-head {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 16px;
}

.leaf-label {
  color: var(--fg-dim);
  font-size: 12px;
  letter-spacing: .18em;
}

.leaf-note {
  color: var(--fg-dim);
  font-size: 11px;
  letter-spacing: .1em;
  font-variant-numeric: tabular-nums;
}

/* 葉が1つしかないなら見出しは冗長 */
.leaf:only-child .leaf-head { display: none; }

/* ---------------------------------------------------------------- colophon
   作品より前（扉の直下）に置く。末尾だと下までスクロールしきらないと読めない。 */
.colophon {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 26px var(--page-pad) 30px;
  border-bottom: 1px solid var(--line);
}

/* 本文左の列。見出しとアイコンが縦に並ぶ（見出しが無ければアイコンだけ） */
.col-aside {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.col-icon {
  display: block;
  width: 120px;
  height: 120px;
  border-radius: 999px;
  object-fit: cover;
}

.col-label {
  margin-bottom: 12px;
  color: var(--fg-dim);
  font-size: 11px;
  letter-spacing: .3em;
  text-transform: uppercase;
}

.col-body p { margin: 0; max-width: 36em; color: var(--fg); }

.col-links {
  display: flex;
  gap: 12px;
  margin-top: 10px;
  font-size: 12px;
  letter-spacing: .14em;
  text-transform: uppercase;
}

/* 文字だけだと高さ17px しか無く指で押しにくいので、上下に余白を持たせて
   44px 角の目安に近づける（負のマージンで見た目の間隔は元のままにする） */
.col-links a {
  padding: 12px 8px;
  margin: -12px -8px;
  color: var(--accent);
}

.col-links a:hover { text-decoration: underline; }

.empty {
  margin: 22vh auto;
  max-width: 520px;
  text-align: center;
  color: var(--fg-dim);
}

.empty code {
  display: inline-block;
  margin-top: 6px;
  color: var(--fg);
  font: 12px/1.7 var(--font-num);
  word-break: break-all;
}

.deskfoot {
  display: flex;
  justify-content: space-between;
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 22px var(--page-pad) 50px;
  color: var(--fg-dim);
  font-size: 11px;
  letter-spacing: .28em;
  text-transform: uppercase;
}

/* ---------------------------------------------------------------- grid
   grid-auto-rows を細かく刻み、各タイルの row span を JS が縦横比から計算する
   （= 高さのそろわないマス目でも隙間が出ないメーソンリー）。
   JS 無効時は grid-auto-rows: auto の素の均等グリッドとして成立する。 */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--col), 1fr));
  grid-auto-rows: auto;
  gap: var(--gap);
  /* 大ゴマ（2列ぶち抜き）の横に空く1列分の穴を、後続のコマで埋める */
  grid-auto-flow: row dense;
}

.js .grid { grid-auto-rows: var(--row); }

@media (max-width: 640px) {
  :root {
    --gap: 8px;
    --page-pad: 12px;
    --page-pad-top: 16px;
  }
  .grid { grid-template-columns: repeat(auto-fill, minmax(var(--col-mobile), 1fr)); }
}

.tile {
  position: relative;
  display: flex;
  flex-direction: column;
  margin: 0;
  cursor: zoom-in;
  outline: none;
}

/* display:flex は UA の [hidden]{display:none} に勝ってしまうので明示的に消す。
   これが無いと「イイネのみ」の絞り込みが効かない。 */
.tile[hidden] { display: none; }

/* span は行数単位に丸められるので数px の誤差が出る。
   frame を flex で伸縮させて、隙間も切れも出さずに吸収する。 */
.frame {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--bg-elev);
}

.tile .m {
  display: block;
  width: 100%;
  height: 100%;
  aspect-ratio: var(--ar);
  object-fit: cover;
  background: var(--bg-elev);
  transition: transform .4s cubic-bezier(.2, .6, .2, 1), filter .3s, opacity .45s;
}

/* クリップは「遅延読み込みされる静止画」の上に、再生する分だけ video を重ねる。
   高さを決めるのは常に静止画側なので、video は絶対配置で流れから外す。 */
.tile .clip-video {
  position: absolute;
  inset: 0;
  z-index: 1;
  opacity: 0;
}

.tile .clip-video.ready { opacity: 1; }

.tile figcaption { flex: 0 0 auto; }

.tile:hover .m {
  transform: scale(var(--tile-hover-scale));
  filter: brightness(var(--tile-hover-bright));
}

/* 画像は読み込み完了でふわっと出す。
   JS 無効時は .js が付かない＝フェードの仕掛けごと無効にして必ず見えるようにする。 */
.js .tile img.m { opacity: 0; }
.js .tile img.m.loaded { opacity: 1; }

/* ホバー時だけ下から情報を出す。スクリムを敷かないと明るい絵で文字が読めない。
   z-index は重ねた video(1) より上に置く必要がある。 */
.tile .scrim {
  position: absolute;
  inset: 0;
  z-index: 2;
  background: var(--scrim);
  opacity: 0;
  transition: opacity .25s;
  pointer-events: none;
}

.tile:hover .scrim { opacity: 1; }

.badge {
  position: absolute;
  z-index: 3;
  right: 9px;
  bottom: 8px;
  color: #fff;
  font: 11px/1 var(--font-num);
  letter-spacing: .02em;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .6);
  opacity: 0;
  transition: opacity .25s;
  pointer-events: none;
}

.tile:hover .badge { opacity: 1; }

/* ---------------------------------------------------------------- イイネ */
.like {
  position: absolute;
  z-index: 3;
  top: 7px;
  right: 7px;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: rgba(0, 0, 0, .38);
  color: #fff;
  cursor: pointer;
  opacity: 0;
  transition: opacity .2s, background .2s, transform .12s;
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}

.like svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 1.7; }

/* 集計がある場合の件数。ボタンは右端に固定されているので、数字は左へ伸びる */
.like:has(.like-n) { width: auto; padding: 0 8px; gap: 4px; grid-auto-flow: column; }

.like-n {
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.like-n:empty { display: none; }

/* 指で押せる大きさ（44px角）まで当たり判定だけを広げる。見た目は変えない。
   タイルの角に寄せてあるので、内側に向かって広がり隣のコマには重ならない。 */
.like::after {
  content: "";
  position: absolute;
  inset: -7px;
  border-radius: inherit;
}

.tile:hover .like, .tile:focus-within .like { opacity: 1; }

/* 押したものは常に見えていないと「押したか」が分からない */
.like.on { opacity: 1; color: #ff6b81; }
.like.on svg { fill: currentColor; stroke: currentColor; }
.like:hover { background: rgba(0, 0, 0, .58); }
.like:active { transform: scale(.9); }

.like.pop { animation: likepop .32s ease-out; }

@keyframes likepop {
  0% { transform: scale(1); }
  38% { transform: scale(1.32); }
  100% { transform: scale(1); }
}

/* ライトボックス内 */
.like.big {
  position: static;
  width: auto;
  height: 30px;
  padding: 0 14px;
  margin: 0 auto 10px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .08);
  opacity: 1;
}

.like.big svg { width: 18px; height: 18px; }

#likecount { margin-left: 10px; opacity: .7; }

@media (prefers-reduced-motion: reduce) {
  .like, .like.pop { transition: none; animation: none; }
}

/* 指で操作する端末はホバーが無いので常時表示 */
@media (hover: none) {
  .like { opacity: .85; }
}

/* キャプション行は「図版番号 + loop 印 + 本文」の3要素。
   plate テーマは全部使うが、他テーマは本文だけ（無ければ行ごと出さない）。 */
figcaption {
  display: none;
  padding: 8px 10px 10px;
  color: var(--fg-dim);
  font: var(--fs-cap) / 1.5 var(--font-cap);
  overflow: hidden;
}

figcaption:has(.cap-text) { display: block; }
.plate, .loop { display: none; }

.cap-text {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* 動きを控えたい設定のときは自動再生せず、ポスター＋▶ にする */
@media (prefers-reduced-motion: reduce) {
  .tile .m { transition: none; }
  .tile.clip::after {
    content: "▶";
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    font-size: 26px;
    color: rgba(255, 255, 255, .8);
    text-shadow: 0 2px 8px rgba(0, 0, 0, .5);
    pointer-events: none;
  }
}

/* ---------------------------------------------------------------- lightbox */
.lb {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  grid-template-rows: 1fr auto;
  background: rgba(6, 6, 8, .95);
  backdrop-filter: blur(6px);
}

.lb[hidden] { display: none; }

.lb-stage {
  display: grid;
  place-items: center;
  min-height: 0;
  padding: 44px 56px 8px;
}

.lb-stage > * {
  max-width: 100%;
  /* スマホのブラウザは URL バーの出入りで表示高が変わる。100vh はバーを含んだ
     高さなので、拡大表示がブラウザUIの裏に隠れる。dvh は実際に見えている高さ。 */
  max-height: calc(100vh - 130px);
  max-height: calc(100dvh - 130px);
  border-radius: 4px;
  background: #000;
  box-shadow: 0 20px 60px rgba(0, 0, 0, .6);
}

.lb-info {
  padding: 10px 20px 22px;
  text-align: center;
  color: var(--fg-dim);
  font-size: 12px;
}

.lb-info .cap {
  display: block;
  margin-bottom: 5px;
  color: var(--fg);
  font: 14px/1.5 var(--font-cap);
}

.lb-info .line { letter-spacing: .03em; }

.lb-info .meta {
  display: block;
  margin: 10px auto 0;
  max-width: 900px;
  max-height: 120px;
  overflow: auto;
  text-align: left;
  white-space: pre-wrap;
  word-break: break-word;
  font: 11px/1.6 var(--font-num);
  opacity: .7;
}

.lb button {
  position: absolute;
  z-index: 2;
  border: 0;
  background: rgba(255, 255, 255, .07);
  color: var(--fg);
  cursor: pointer;
  border-radius: 8px;
  transition: background .15s;
}

.lb button:hover { background: rgba(255, 255, 255, .16); }
.lb-close { top: 12px; right: 12px; width: 38px; height: 38px; font-size: 16px; }
.lb-prev, .lb-next { top: 50%; transform: translateY(-50%); width: 40px; height: 76px; font-size: 26px; }
.lb-prev { left: 10px; }
.lb-next { right: 10px; }

@media (max-width: 640px) {
  .lb-stage { padding: 44px 8px 8px; }
  .lb-prev, .lb-next { height: 54px; width: 32px; font-size: 20px; }
}

/* ---------------------------------------------------------------- R18 gate */
.gate {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: grid;
  place-items: center;
  padding: 20px;
  background: #08080a;
}

.gate-passed .gate { display: none; }

.gate-box {
  max-width: 460px;
  padding: 30px 28px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg-elev);
  text-align: center;
}

.gate-box h1 { margin: 0 0 14px; font-size: 19px; letter-spacing: .04em; }
.gate-box p { margin: 0 0 22px; color: var(--fg-dim); font-size: 14px; text-align: left; }
.gate-btns { display: flex; flex-direction: column; gap: 10px; }

#gate-yes {
  padding: 11px;
  border: 0;
  border-radius: 8px;
  background: var(--fg);
  color: var(--bg);
  font: 600 14px var(--font-ui);
  cursor: pointer;
}

.gate-no { padding: 9px; color: var(--fg-dim); font-size: 13px; }
.gate-no:hover { color: var(--fg); }

/* ゲート表示中は背後をスクロールさせない＆中身を見せない */
html:not(.gate-passed) body[data-rating="r18"] { overflow: hidden; }
html:not(.gate-passed) body[data-rating="r18"] main,
html:not(.gate-passed) body[data-rating="r18"] .bar { filter: blur(22px); }

/* ---------------------------------------------------------------- theme 切替（確認用） */
.themebar {
  position: fixed;
  z-index: 50;
  left: 50%;
  bottom: 16px;
  transform: translateX(-50%);
  display: flex;
  gap: 2px;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(18, 18, 22, .92);
  backdrop-filter: blur(10px);
  box-shadow: 0 8px 30px rgba(0, 0, 0, .5);
}

.themebar button {
  padding: 6px 14px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: #8b8b96;
  font: 12px var(--font-ui);
  letter-spacing: .04em;
  cursor: pointer;
}

.themebar button:hover { color: #e8e8ea; }
.themebar button.on { background: #e8e8ea; color: #111; }
