/* public/assets/site.css: 3 層。docs/design/taste2/style.css の写し → 本番用の追加 → taste3 の上書き層（末尾、
   正本は docs/design/taste3/style.css）。デザインを変えるときは正本も同じように直す。
   Three layers: copy of taste2/style.css, production additions, then the taste3 override layer (source:
   docs/design/taste3/style.css). Keep the sources in sync when changing the design.
   フォントは自前配信（/assets/fonts.css、scripts/vendor-fonts.ts が生成）: ページは LINE Seed JP、
   マクロ本文は Noto Sans JP（--macro-font）。アイコンは /assets/icons.svg のスプライト。
   Fonts are self-hosted (/assets/fonts.css): LINE Seed JP for pages, Noto Sans JP for macro text
   (--macro-font). Icons come from the /assets/icons.svg sprite. */

/* taste2: taste 案 + Game-icons + 意味を持つ余白・グルーピング + FF14 寄せ
   アクセントは金 1 色。ロール色（青・緑・赤）はデータの符号化にだけ使う */

/* ============ 1. 余白トークン（近接の法則） ============
   値は「どれだけ関係が近いか」を表す。数字が小さいほど同じものの一部。
   規則 A: 入れ物の内側の余白 >= 中身同士の最大の間隔（中身が外へ漏れて見えない）
   規則 B: 隣の入れ物との間隔 > 入れ物の内側の余白（入れ物ごとにまとまって見える）
   規則 C: 下のトークン以外の値で間隔を作らない */
:root {
  --gap-atom: 4px; /* 1 つのものの部品同士: アイコンとラベル、数と単位 */
  --gap-item: 8px; /* 同じ集合に並ぶ仲間: バッジ、タブ、スロット */
  --gap-group: 16px; /* 1 枚のウィンドウの中の、別のまとまり同士。ウィンドウの内側の余白もこれ */
  --gap-block: 24px; /* ウィンドウ同士、カード同士 */
  --gap-section: 56px; /* 話題の切り替わり: ページの節 */
  --pad-window: var(--gap-group);
}
@media (min-width: 960px) {
  :root {
    --gap-block: 28px;
    --gap-section: 72px;
    --pad-window: 20px;
  }
}

/* ============ 2. グルーピングの段（入れ物は 3 種類だけ） ============
   段 1 Window : 機能のまとまり。枠と見出しバーを持つ。ウィンドウの中にウィンドウを入れない
   段 2 Well   : ウィンドウの中の「物」。凹んだ面（マクロ本文、ジョブのスロット）
   段 3 Rule   : 並んだ行の区切り。箱にしない。1px の線だけ
   節の見出し（菱形 + 金の細線）は入れ物を持たない区切りで、下に続くウィンドウ群をまとめる */

/* ============ 3. 色 ============ */
:root {
  --bg: #0a0e18;
  --win-top: #192139;
  --win: #10172a;
  --win-edge: rgba(196, 210, 255, 0.15);
  --win-hi: rgba(255, 255, 255, 0.06);
  --bar: rgba(255, 255, 255, 0.025);
  --slot: #0a0f1d;
  --slot-edge: rgba(0, 0, 0, 0.55);
  --slot-hi: rgba(196, 210, 255, 0.08);
  --well: #060912;
  --well-ink: #e6e9f2;
  --well-muted: #67728c;
  --cmd: #8cc0ff;
  --ph: #f0b46a;
  --rule: rgba(196, 210, 255, 0.1);
  --ink: #e9ecf3;
  --muted: #9aa3b8;
  --accent: #e0b968;
  --accent-fill: #e0b968;
  --accent-top: #f0d08e;
  --on-accent: #1a1406;
  --accent-soft: rgba(224, 185, 104, 0.13);
  --ok: #6fd6a0;
  --focus: #ffd98a;
  --tank: #5b97ff;
  --healer: #4fd38a;
  --dps: #ff6476;
  --hand: #eab656;
  --shadow: 0 18px 36px -22px rgba(2, 6, 20, 0.95);
  --r-sm: 6px;
  --r: 10px;
  --font:
    "LINE Seed JP", "Hiragino Sans", "Hiragino Kaku Gothic ProN",
    "BIZ UDPGothic", "Yu Gothic UI", Meiryo, system-ui, sans-serif;
  --mono: "JetBrains Mono", "BIZ UDGothic", "Osaka-Mono", Consolas, monospace;
  /* マクロ本文。全角スペースで揃える本文があるので palt は付けない / no palt: bodies align with full-width spaces */
  --macro-font:
    "Noto Sans JP", "Hiragino Sans", "BIZ UDPGothic", Meiryo, sans-serif;
  color-scheme: dark;
}
@media (prefers-color-scheme: light) {
  :root {
    --bg: #eceff5;
    --win-top: #ffffff;
    --win: #f6f7fb;
    --win-edge: rgba(14, 22, 44, 0.16);
    --win-hi: #ffffff;
    --bar: rgba(14, 22, 44, 0.025);
    --slot: #e3e7f0;
    --slot-edge: rgba(14, 22, 44, 0.16);
    --slot-hi: #ffffff;
    --well: #0d1324;
    --well-muted: #7a86a3;
    --rule: rgba(14, 22, 44, 0.1);
    --ink: #121726;
    --muted: #535c71;
    --accent: #85600f;
    --accent-fill: #d9ae56;
    --accent-top: #e8c67e;
    --accent-soft: rgba(217, 174, 86, 0.18);
    --ok: #17784a;
    --focus: #8a5600;
    --tank: #2a62d4;
    --healer: #18834a;
    --dps: #c8283d;
    --hand: #9a6a0c;
    --shadow: 0 14px 28px -20px rgba(30, 50, 100, 0.45);
    color-scheme: light;
  }
}

/* ============ 4. 土台 ============ */
* {
  box-sizing: border-box;
}
html {
  -webkit-text-size-adjust: 100%;
}
body {
  margin: 0;
  min-height: 100dvh;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.7;
}
body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background: radial-gradient(
    52rem 30rem at 100% 0%,
    var(--accent-soft),
    transparent 70%
  );
}
body > * {
  position: relative;
  z-index: 1;
}
a {
  color: inherit;
}
:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}
.wrap {
  max-width: 1180px;
  margin: 0 auto;
  padding: 0 16px;
}
.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
.ph-fill {
  font-size: 18px;
  line-height: 1;
}
.gi {
  width: 18px;
  height: 18px;
  flex: none;
  fill: currentColor;
}
.gi--sm {
  width: 14px;
  height: 14px;
}
.gi--lg {
  width: 56px;
  height: 56px;
}

/* ============ 5. 部品: 入れ物 ============ */
/* 段 1 Window */
.window {
  position: relative;
  border: 1px solid var(--win-edge);
  border-radius: var(--r);
  background: linear-gradient(180deg, var(--win-top), var(--win) 140px);
  box-shadow:
    inset 0 1px 0 var(--win-hi),
    var(--shadow);
}
.window__bar {
  display: flex;
  align-items: center;
  gap: var(--gap-item);
  min-height: 44px;
  padding: 0 var(--gap-item) 0 var(--pad-window);
  background: var(--bar);
  border-radius: var(--r) var(--r) 0 0;
  position: relative;
}
/* 見出しバーの下の金の細線: 左から右へ消える。FF14 のウィンドウ見出しの記号 */
.window__bar::after {
  content: "";
  position: absolute;
  left: var(--pad-window);
  right: var(--pad-window);
  bottom: 0;
  height: 1px;
  background: linear-gradient(
    90deg,
    var(--accent) 0,
    color-mix(in srgb, var(--accent) 35%, transparent) 40%,
    transparent
  );
}
.window__title {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-item);
  margin: 0;
  margin-right: auto;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--ink);
}
.window__title .gi {
  color: var(--accent);
}
.window__meta {
  color: var(--muted);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  padding-right: var(--gap-item);
}
.window__body {
  padding: var(--pad-window);
}

/* 節の見出し: 菱形 + 文字 + 右へ消える細線。入れ物を持たない */
.sect {
  display: flex;
  align-items: center;
  gap: var(--gap-item);
  margin: 0 0 var(--gap-group);
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.sect::before {
  content: "";
  flex: none;
  width: 9px;
  height: 9px;
  background: var(--accent);
  transform: rotate(45deg);
  margin: 0 var(--gap-atom);
}
.sect::after {
  content: "";
  flex: 1;
  height: 1px;
  min-width: 24px;
  order: 1;
  background: linear-gradient(
    90deg,
    color-mix(in srgb, var(--accent) 55%, transparent),
    transparent
  );
}
.sect small {
  order: 2;
  color: var(--muted);
  font-size: 13px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

/* 段 2 Slot: ゲームのホットバーのような凹み */
.slot {
  position: relative;
  display: grid;
  place-items: center;
  min-width: 44px;
  height: 48px;
  border-radius: var(--r-sm);
  background: var(--slot);
  box-shadow:
    inset 0 2px 4px var(--slot-edge),
    0 1px 0 var(--slot-hi);
  color: var(--ink);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-decoration: none;
  transition:
    box-shadow var(--motion-hover) var(--motion-ease-color),
    transform var(--motion-press) var(--motion-ease);
}
.slot::after {
  content: "";
  position: absolute;
  left: 10px;
  right: 10px;
  bottom: 6px;
  height: 2px;
  border-radius: 2px;
  background: var(--role);
  opacity: 0.9;
}
.slot:hover {
  box-shadow:
    inset 0 2px 4px var(--slot-edge),
    inset 0 0 0 1px var(--accent);
}
.slot:active {
  transform: scale(0.96);
}
.t {
  --role: var(--tank);
}
.h {
  --role: var(--healer);
}
.d {
  --role: var(--dps);
}
.c {
  --role: var(--hand);
}

/* 段 3 Rule */
.rows {
  margin: 0;
  padding: 0;
  list-style: none;
}
.rows > li + li {
  border-top: 1px solid var(--rule);
}

/* ============ 6. 部品: 操作 ============ */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-item);
  height: 44px;
  padding: 0 18px;
  border: 0;
  border-radius: var(--r-sm);
  background: linear-gradient(180deg, var(--accent-top), var(--accent-fill));
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.35),
    0 1px 0 rgba(0, 0, 0, 0.25);
  color: var(--on-accent);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition:
    transform var(--motion-press) var(--motion-ease),
    filter var(--motion-hover) var(--motion-ease-color);
}
.btn:hover {
  filter: brightness(1.05);
}
.btn:active {
  transform: translateY(1px) scale(0.98);
}
.btn--ghost {
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--win-edge);
  color: var(--ink);
}
.iconbtn {
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--win-edge);
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--ink);
  cursor: pointer;
}

.badge {
  position: relative;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: var(--gap-atom);
  height: 26px;
  padding: 0 8px 0 6px;
  border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--ink) 6%, transparent);
  color: var(--ink);
  font-size: 12px;
  font-weight: 600;
  text-decoration: none;
}
.badge .gi {
  color: var(--muted);
}
.badge--job .gi {
  color: var(--role);
}
.badge--content {
  background: var(--accent-soft);
  color: var(--accent);
}
.badge--content .gi {
  color: var(--accent);
}

/* ============ 7. ヘッダー ============ */
.top {
  position: sticky;
  top: 0;
  z-index: 20;
  background: color-mix(in srgb, var(--bg) 94%, transparent);
  border-bottom: 1px solid var(--rule);
}
.top .wrap {
  display: flex;
  align-items: center;
  gap: var(--gap-item);
  height: 64px;
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-right: auto;
  font-weight: 600;
  font-size: 19px;
  letter-spacing: -0.01em;
  text-decoration: none;
}
.brand__mark {
  width: 14px;
  height: 14px;
  border: 2px solid var(--accent);
  transform: rotate(45deg);
  border-radius: 2px;
}
.brand b {
  color: var(--accent);
  font-weight: 600;
}
/* 狭い幅でも出す。新着はロゴと同じ行き先なので狭い幅では隠す / always shown; 新着 hides when narrow (the logo goes there too) */
.nav {
  display: flex;
  gap: var(--gap-atom);
}
.nav a {
  position: relative;
  display: inline-flex;
  align-items: center;
  height: 44px;
  padding: 0 var(--gap-item);
  color: var(--muted);
  font-size: 14px;
  font-weight: 500;
  text-decoration: none;
  transition: color var(--motion-hover) var(--motion-ease-color);
}
.nav a:hover {
  color: var(--ink);
}
.nav a[aria-current="page"] {
  color: var(--ink);
}
.nav a[aria-current="page"]::after {
  content: "";
  position: absolute;
  left: var(--gap-item);
  right: var(--gap-item);
  bottom: 6px;
  height: 2px;
  background: var(--accent);
}
.nav a.nav__home {
  display: none;
}
/* サイト名が長いので 1 行に収める / keep the long site name and nav on one line at phone width */
.brand,
.nav a {
  white-space: nowrap;
}
@media (max-width: 479px) {
  .brand {
    gap: 6px;
    font-size: 15px;
  }
  .nav a {
    padding: 0 4px;
  }
}
@media (min-width: 820px) {
  .nav {
    margin-right: var(--gap-item);
  }
  .nav a {
    padding: 0 14px;
  }
  .nav a[aria-current="page"]::after {
    left: 14px;
    right: 14px;
  }
  .nav a.nav__home {
    display: inline-flex;
  }
}

/* ============ 8. 一覧 ============ */
.intro {
  display: grid;
  gap: var(--gap-block);
  padding: 40px 0 var(--gap-section);
}
@media (min-width: 960px) {
  .intro {
    grid-template-columns: 7fr 5fr;
    align-items: end;
    gap: 48px;
    padding-top: 64px;
  }
}
.intro h1 {
  margin: 0;
  font-size: clamp(30px, 6vw, 46px);
  line-height: 1.15;
  font-weight: 700;
  letter-spacing: -0.02em;
  text-wrap: balance;
}
.intro h1 em {
  font-style: normal;
  color: var(--accent);
}
.intro p {
  margin: var(--gap-group) 0 0;
  max-width: 34em;
  color: var(--muted);
}
.search {
  display: flex;
  align-items: center;
  gap: var(--gap-item);
  margin-top: var(--gap-block);
  max-width: 34rem;
  height: 52px;
  padding: 0 var(--gap-item) 0 var(--gap-group);
  border-radius: var(--r);
  background: var(--slot);
  box-shadow:
    inset 0 2px 4px var(--slot-edge),
    0 1px 0 var(--slot-hi);
  color: var(--muted);
}
.search label {
  flex: 1;
}
.search input {
  width: 100%;
  border: 0;
  background: transparent;
  color: var(--ink);
  font: inherit;
  outline: none;
}
.search input::placeholder {
  color: var(--muted);
}
.search:focus-within {
  box-shadow:
    inset 0 2px 4px var(--slot-edge),
    inset 0 0 0 1px var(--accent);
}

/* ジョブ: ロールごとにまとめる。まとまりの間 (group) > スロットの間 (item) */
.roles {
  display: grid;
  gap: var(--gap-group);
}
.roles__pair {
  display: grid;
  gap: var(--gap-group);
}
@media (min-width: 480px) {
  .roles__pair {
    grid-template-columns: 1fr 1fr;
  }
}
.role__name {
  display: flex;
  align-items: center;
  gap: var(--gap-atom);
  margin: 0 0 var(--gap-item);
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  letter-spacing: 0.04em;
}
.role__name .gi {
  color: var(--role);
}
.role__name span {
  margin-left: auto;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.role__slots {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(48px, 1fr));
  gap: var(--gap-atom);
}
.roles__pair .role__slots {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

/* カテゴリー: ウィンドウのタブ */
.tabs {
  display: flex;
  gap: var(--gap-atom);
  overflow-x: auto;
  margin: 0 0 var(--gap-block);
  padding: 0;
  border-bottom: 1px solid var(--rule);
  scrollbar-width: none;
  list-style: none;
}
.tabs::-webkit-scrollbar {
  display: none;
}
.tabs > li {
  flex: none;
}
.tab {
  position: relative;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: var(--gap-item);
  height: 44px;
  padding: 0 14px;
  border-radius: var(--r-sm) var(--r-sm) 0 0;
  color: var(--muted);
  font-size: 14px;
  font-weight: 500;
  text-decoration: none;
  transition:
    color var(--motion-hover) var(--motion-ease-color),
    background-color var(--motion-hover) var(--motion-ease-color);
}
.tab .gi {
  opacity: 0.8;
}
.tab:hover {
  color: var(--ink);
  background: color-mix(in srgb, var(--ink) 4%, transparent);
}
.tab[aria-current="true"] {
  color: var(--ink);
  font-weight: 600;
  background: linear-gradient(180deg, var(--accent-soft), transparent);
}
.tab[aria-current="true"] .gi {
  color: var(--accent);
  opacity: 1;
}
.tab[aria-current="true"]::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  background: var(--accent);
}

/* カード: 段 1（見出しバーなしのウィンドウ）。中は 見出し群 / 本文 / 足 の 3 まとまり */
.grid {
  display: grid;
  gap: var(--gap-block);
  margin: 0;
  padding: 0;
  list-style: none;
}
@media (min-width: 760px) {
  .grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--gap-group) var(--gap-block);
  }
}
@media (min-width: 1100px) {
  .grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .grid > .feature {
    grid-column: span 2;
  }
}
.card {
  display: grid;
  gap: var(--gap-group);
  align-content: start;
  padding: var(--pad-window);
  transition:
    border-color var(--motion-hover) var(--motion-ease-color),
    transform var(--motion-move) var(--motion-ease);
}
.card:hover {
  border-color: color-mix(in srgb, var(--accent) 50%, transparent);
  transform: translateY(-2px);
  /* 乗せたときはすぐ浮かせ、離すときは上の 260ms でゆっくり戻す / quick lift in, softer 260ms return out */
  transition-duration: var(--motion-hover);
}
.card__head {
  display: grid;
  gap: var(--gap-item);
}
.card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-atom);
}
.card h2 {
  margin: 0;
  font-size: 17px;
  line-height: 1.45;
  font-weight: 600;
  text-wrap: pretty;
}
.card h2 a {
  text-decoration: none;
}
.card h2 a::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--r);
}
.card:has(h2 a:focus-visible) {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
@supports selector(:has(*)) {
  .card h2 a:focus-visible {
    outline: none;
  }
}
.excerpt {
  margin: 0;
  padding: 0 14px;
  border-block: 12px solid var(--well);
  border-radius: var(--r-sm);
  background: var(--well);
  box-shadow: 0 0 0 1px rgba(150, 175, 230, 0.08);
  color: var(--well-ink);
  font-family: var(--macro-font);
  font-size: 12.5px;
  line-height: 1.75;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
  max-height: calc(3 * 1.75em + 24px);
}
.feature .excerpt {
  -webkit-line-clamp: 5;
  max-height: calc(5 * 1.75em + 24px);
}
.card__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap-item);
  margin-top: calc(var(--gap-atom) * -1);
  font-size: 13px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.quickcopy {
  position: relative;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: var(--gap-atom);
  height: 44px;
  padding: 0 12px;
  margin: -8px -10px -8px 0;
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.quickcopy:hover {
  background: color-mix(in srgb, var(--ink) 6%, transparent);
}
.quickcopy[data-copied] {
  color: var(--ok);
}

@media (prefers-reduced-motion: no-preference) {
  .grid > li {
    animation: rise var(--motion-enter) var(--motion-ease) both;
    /* 40ms は時間ではなく 1 枚ごとのずらし幅（Open Props に相当する値がない）。6 枚で合計 240ms
       a per-card step, not a duration; 6 cards = 240ms total */
    animation-delay: calc(var(--i, 0) * 40ms);
  }
  /* 何枚目かは CSS で決める（CSP で style 属性は使えない）。7 枚目以降は同じ遅れ
     The index comes from CSS (CSP forbids style attributes); the 7th card onward share one delay */
  .grid > li:nth-child(2) {
    --i: 1;
  }
  .grid > li:nth-child(3) {
    --i: 2;
  }
  .grid > li:nth-child(4) {
    --i: 3;
  }
  .grid > li:nth-child(5) {
    --i: 4;
  }
  .grid > li:nth-child(6) {
    --i: 5;
  }
  .grid > li:nth-child(n + 7) {
    --i: 6;
  }
  @keyframes rise {
    from {
      opacity: 0.001;
      transform: translateY(12px);
    }
  }
}

.pager {
  display: flex;
  justify-content: center;
  gap: var(--gap-atom);
  margin: var(--gap-block) 0 0;
  padding: 0;
  list-style: none;
  font-variant-numeric: tabular-nums;
}
.pager a,
.pager span {
  display: inline-grid;
  place-items: center;
  min-width: 44px;
  height: 44px;
  padding: 0 12px;
  border-radius: var(--r-sm);
  color: var(--muted);
  font-weight: 600;
  text-decoration: none;
}
.pager a:hover {
  background: color-mix(in srgb, var(--ink) 6%, transparent);
  color: var(--ink);
}
.pager [aria-current] {
  background: var(--slot);
  box-shadow:
    inset 0 2px 4px var(--slot-edge),
    inset 0 -2px 0 var(--accent);
  color: var(--ink);
}

/* 空の状態 */
.empty {
  display: grid;
  justify-items: center;
  gap: var(--gap-group);
  padding: 48px var(--pad-window);
  text-align: center;
}
.empty .gi {
  color: var(--accent);
  opacity: 0.9;
}
.empty h2 {
  margin: 0;
  font-size: 18px;
}
.empty p {
  margin: calc(var(--gap-item) * -1) 0 0;
  max-width: 28em;
  color: var(--muted);
}
.empty__acts {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--gap-item);
}

.foot {
  margin-top: var(--gap-section);
  border-top: 1px solid var(--rule);
  color: var(--muted);
  font-size: 13px;
}
.foot .wrap {
  display: grid;
  gap: var(--gap-item);
  padding: 28px 16px 40px;
}
@media (min-width: 760px) {
  .foot .wrap {
    grid-template-columns: 1fr auto;
    align-items: center;
  }
}
.foot ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0 20px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.foot a {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-atom);
  min-height: 44px;
  text-decoration: none;
}
.foot a:hover {
  color: var(--ink);
}
.foot p {
  margin: 0;
}
.credit {
  font-size: 12px;
}
/* 最下部の掲載メディア欄 / media-mention block above the footer */
.press {
  margin-top: var(--gap-section);
  border-top: 1px solid var(--rule);
  color: var(--muted);
  font-size: 13px;
}
.press .wrap {
  padding: 28px 16px 0;
}
.press h2 {
  margin: 0 0 8px;
  font-size: 13px;
  color: var(--ink);
}
.press ul {
  display: grid;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.press a {
  text-underline-offset: 2px;
}
.press span::before {
  content: " — ";
}
.press + .foot {
  margin-top: 0;
  border-top: 0;
}
.credit a {
  display: inline;
  min-height: 0;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ============ 9. 詳細 ============ */
.crumbs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-atom) var(--gap-item);
  margin: 28px 0 0;
  padding: 0;
  list-style: none;
  font-size: 13px;
  color: var(--muted);
}
.crumbs li + li::before {
  content: "/";
  margin-right: var(--gap-item);
  opacity: 0.5;
}
.crumbs a {
  text-decoration: none;
}
.crumbs a:hover {
  color: var(--ink);
}
.detail {
  display: grid;
  gap: var(--gap-block);
  padding: var(--gap-group) 0 0;
}
@media (min-width: 980px) {
  .detail {
    grid-template-columns: minmax(0, 1fr) 320px;
    gap: 40px;
    align-items: start;
  }
}
.detail__head {
  display: grid;
  gap: var(--gap-group);
  margin-bottom: var(--gap-block);
}
.detail h1 {
  margin: 0;
  font-size: clamp(26px, 4.6vw, 36px);
  line-height: 1.25;
  font-weight: 700;
  letter-spacing: -0.02em;
  text-wrap: balance;
}
.tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-item);
  margin: 0;
  padding: 0;
  list-style: none;
}
.tags .badge {
  height: 32px;
  padding: 0 12px 0 8px;
  font-size: 13px;
}

.console .window__bar {
  background: transparent;
}
.console__copy {
  height: 36px;
  padding: 0 14px;
  font-size: 13px;
}
.console__copy[data-copied] {
  background: var(--ok);
  box-shadow: none;
}
.console .window__body {
  padding: var(--gap-item);
}
.console pre {
  margin: 0;
  padding: var(--gap-group) var(--gap-group) var(--gap-group) 0;
  border-radius: var(--r-sm);
  background: var(--well);
  box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.5);
  color: var(--well-ink);
  counter-reset: l;
  font-family: var(--macro-font);
  font-size: 14px;
  line-height: 1.85;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.console .ln {
  display: block;
  position: relative;
  padding-left: 3.4em;
}
.console .ln::before {
  counter-increment: l;
  content: counter(l);
  position: absolute;
  left: 0;
  width: 2.4em;
  text-align: right;
  color: var(--well-muted);
  user-select: none;
}
.console .c {
  color: var(--cmd);
}
.console .p {
  color: var(--ph);
}

.desc {
  margin-top: var(--gap-section);
  max-width: 40em;
}
.desc p {
  margin: 0 0 12px;
  color: color-mix(in srgb, var(--ink) 88%, var(--muted));
}
/* 説明は投稿者の改行を保つ / keep the author's line breaks in descriptions */
.desc p,
.preview .prose > p {
  white-space: pre-line;
}

.aside {
  display: grid;
  gap: var(--gap-group);
}
@media (min-width: 980px) {
  .aside {
    position: sticky;
    top: 88px;
  }
}
.facts {
  margin: 0;
  padding: var(--gap-atom) var(--pad-window);
}
.facts div {
  display: grid;
  grid-template-columns: 7em 1fr;
  gap: var(--gap-item);
  padding: 12px 0;
}
.facts > div + div {
  border-top: 1px solid var(--rule);
}
.facts dt {
  color: var(--muted);
  font-size: 13px;
}
.facts dd {
  margin: 0;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.facts dd a {
  color: var(--accent);
}
/* 共有ボタン（詳細ページの右欄）/ share buttons in the detail aside */
.share {
  display: grid;
  gap: var(--gap-atom);
  padding: var(--pad-window);
}
.share .btn {
  justify-content: center;
  width: 100%;
}
.share__msg {
  margin: 0;
  color: var(--muted);
  font-size: 13px;
  overflow-wrap: anywhere;
}
.share__msg:empty {
  display: none;
}

/* いいね（Task 12.7）。押した状態は like.js が aria-pressed で付ける / pressed state comes from like.js via aria-pressed */
.like {
  display: grid;
  gap: var(--gap-atom);
  margin: 0;
}
p.like {
  display: flex;
  align-items: center;
  gap: var(--gap-atom);
  color: var(--muted);
}
.like__btn {
  justify-content: center;
  width: 100%;
}
.like__count {
  margin-left: var(--gap-atom);
  font-variant-numeric: tabular-nums;
}
.like__btn[aria-pressed="true"] {
  border-color: var(--dps);
  color: var(--dps);
}
.like__msg {
  margin: 0;
  color: var(--muted);
  font-size: 13px;
}
.like__msg:empty {
  display: none;
}

.related {
  margin-top: var(--gap-section);
}
.related .rows a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap-group);
  min-height: 52px;
  padding: 0 var(--pad-window);
  font-weight: 600;
  text-decoration: none;
  transition: background-color var(--motion-hover) var(--motion-ease-color);
}
.related .rows a:hover {
  background: color-mix(in srgb, var(--ink) 4%, transparent);
}
.related .rows time {
  color: var(--muted);
  font-size: 13px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  flex: none;
}

/* ============ 10. トークン見本ページ ============ */
.tok {
  display: grid;
  gap: var(--gap-block);
  padding: 40px 0 0;
}
.scale {
  display: grid;
  gap: var(--gap-item);
}
.scale li {
  display: grid;
  grid-template-columns: 9em 4em 1fr;
  align-items: center;
  gap: var(--gap-group);
  padding: 10px 0;
}
.scale code {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--accent);
}
.scale b {
  display: block;
  height: 14px;
  background: var(--accent);
  border-radius: 2px;
}
.scale p {
  grid-column: 1 / -1;
  margin: 0;
  color: var(--muted);
  font-size: 13px;
}
@media (min-width: 760px) {
  .scale li {
    grid-template-columns: 10em 4em 120px 1fr;
  }
  .scale p {
    grid-column: auto;
  }
}
.levels {
  display: grid;
  gap: var(--gap-block);
}
@media (min-width: 900px) {
  .levels {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
.levels h3 {
  margin: 0 0 var(--gap-item);
  font-size: 15px;
}
.levels p {
  margin: 0;
  color: var(--muted);
  font-size: 13px;
}
.demo-slots {
  display: flex;
  gap: var(--gap-atom);
  margin-top: var(--gap-group);
}
.demo-slots .slot {
  width: 48px;
}

@media (prefers-reduced-motion: reduce) {
  * {
    transition: none !important;
    animation: none !important;
  }
}

/* ============ 本番用の追加 / production additions ============ */
/* マクロ本文: 行番号スパンを使わないので左の余白を戻す（white-space は spec 9.1）
   Macro body: no per-line number spans, so restore left padding */
.macro-body {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.console pre.macro-body {
  padding-left: var(--gap-group);
}
/* 複数マクロ: 1 つずつ見出しとコピーボタン / several macros: a heading and copy button per macro */
.console__part + .console__part {
  margin-top: var(--gap-group);
}
.console__parthead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap-item);
  margin-bottom: var(--gap-atom);
}
.console__parthead small {
  margin-left: var(--gap-item);
  color: var(--muted);
}
.card__desc {
  margin: 0;
  color: var(--muted);
  font-size: 14px;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
}
/* レベルは右上に固定、下段は いいね（左）と日付（右）だけ / level pinned top-right; foot holds only likes (left) and date (right) */
.card__lv {
  margin-left: auto;
  align-self: center;
  color: var(--muted);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
/* カードのいいね数（Task 12.8）/ like count on cards (Task 12.8) */
.card__likes {
  align-items: center;
  color: var(--muted);
  display: inline-flex;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  gap: 4px;
}
.pager {
  align-items: center;
  gap: var(--gap-item);
}
.pager .btn {
  min-width: 0;
}
.pager__pos {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* ===== taste3: ゲーム UI 寄せの上書き（2026-10-15 採用、正本は docs/design/taste3/style.css）/ game-UI chrome override (adopted) =====
   公式素材は使わず、窓の縁・帯状のタブ・凹んだ面・ステータス行の「作り」だけを CSS で再現する。
   No official assets: only the construction (window rim, ribbon tabs, recessed wells, stat rows) in CSS.
   ゲーム UI に明るいテーマはないので、この層はライト設定でも暗い窓にする（:root を後ろで上書き）。
   The game UI has no light theme, so this layer keeps dark windows in light mode too. */
:root {
  --bg: #121212;
  --win-top: rgba(62, 61, 58, 0.97);
  --win: rgba(30, 30, 29, 0.97);
  --win-edge: rgba(224, 220, 210, 0.36);
  --win-hi: rgba(255, 255, 255, 0.09);
  --rim-in: rgba(0, 0, 0, 0.75);
  --bar: linear-gradient(
    180deg,
    rgba(255, 255, 255, 0.07),
    rgba(255, 255, 255, 0)
  );
  --slot: #161616;
  --slot-edge: rgba(0, 0, 0, 0.7);
  --slot-hi: rgba(255, 255, 255, 0.07);
  --well: #121212;
  --well-ink: #ecebe6;
  --well-muted: #7d7b74;
  --rule: rgba(224, 220, 210, 0.14);
  --ink: #eceae4;
  --muted: #a8a59c;
  --label: #c9c5ba;
  --accent: #dcc48a;
  --accent-fill: #d8bb73;
  --accent-top: #eed9a2;
  --on-accent: #1d1708;
  --accent-soft: rgba(220, 196, 138, 0.14);
  --ok: #8fd37a;
  --focus: #f3dc9c;
  --tank: #6b9cf0;
  --healer: #7ccf6a;
  --dps: #e0606e;
  --hand: #d9b25a;
  --shadow: 0 14px 28px -16px rgba(0, 0, 0, 0.95);
  --r: 9px;
  --r-sm: 5px;
  color-scheme: dark;
}

body {
  background:
    radial-gradient(
      1200px 600px at 20% -10%,
      rgba(120, 104, 70, 0.16),
      transparent 60%
    ),
    radial-gradient(
      900px 500px at 110% 10%,
      rgba(70, 80, 96, 0.14),
      transparent 60%
    ),
    var(--bg);
  background-attachment: fixed;
}

/* 窓: 明るい外縁 + 暗い内線 + 上端の艶 / window: light rim, dark inner line, top gloss */
.window {
  border: 1px solid var(--win-edge);
  background: linear-gradient(180deg, var(--win-top), var(--win) 96px);
  box-shadow:
    inset 0 0 0 1px var(--rim-in),
    inset 0 2px 0 0 var(--win-hi),
    var(--shadow);
}
.window__bar {
  background: var(--bar);
}
.window__bar::after {
  background: linear-gradient(
    90deg,
    rgba(224, 220, 210, 0.45),
    rgba(224, 220, 210, 0.08) 70%,
    transparent
  );
}
.window__title {
  color: var(--label);
  letter-spacing: 0.08em;
}

/* 節見出し: アイコン相当の菱形 + 灰ベージュの見出し + 右へ消える線 / section heading */
.sect {
  color: var(--label);
  font-size: 17px;
  font-weight: 700;
}
.sect::after {
  background: linear-gradient(90deg, rgba(224, 220, 210, 0.4), transparent);
}

/* カード: 小さな窓。左端にロール色のゲージ、見出しは帯 / card as a small window with a role gauge */
.card {
  position: relative;
  gap: 12px;
  padding: 0 0 12px;
  overflow: hidden;
}
.card::before {
  content: "";
  position: absolute;
  left: 6px;
  top: 12px;
  bottom: 12px;
  width: 3px;
  border-radius: 2px;
  background: var(--role, var(--accent));
  box-shadow: 0 0 6px
    color-mix(in srgb, var(--role, var(--accent)) 60%, transparent);
  opacity: 0.85;
}
.card[data-role="t"] {
  --role: var(--tank);
}
.card[data-role="h"] {
  --role: var(--healer);
}
.card[data-role="d"] {
  --role: var(--dps);
}
.card[data-role="c"] {
  --role: var(--hand);
}
.card:hover {
  transform: translateY(-1px);
  border-color: rgba(238, 230, 210, 0.6);
}
.card__head {
  gap: 8px;
  padding: 10px 14px 10px 18px;
  /* 見出しの下線は本文と同じ内側の余白（左 18px・右 14px）に収め、暗い線の下に淡い光を置いて凹ませる */
  /* The rule under the title sits inside the same padding as the body (18px left, 14px right) and is engraved: dark line over a faint highlight */
  background:
    linear-gradient(
      180deg,
      rgba(0, 0, 0, 0.7) 0 1px,
      rgba(255, 255, 255, 0.09) 1px 2px
    )
    18px 100% / calc(100% - 32px) 2px no-repeat,
    var(--bar);
}
.card h2 {
  font-size: 16px;
  letter-spacing: 0.01em;
}
.card .excerpt,
.card__foot {
  margin-inline: 14px 14px;
  margin-left: 18px;
}

/* 帯状のタブ（ゲームのタブと同じ横長の六角形）/ ribbon tabs: elongated hexagon like the game's tabs */
/* 形は疑似要素 2 枚で描く: ::before が外縁 1px、::after が 1px 内側の面。本体に clip-path を掛けないので影（drop-shadow）が切れない */
/* Two pseudo layers draw the shape: ::before is the 1px rim, ::after the face 1px inside. No clip-path on the box itself, so the drop shadow is not clipped */
.badge {
  --cut: 7px;
  --rim: linear-gradient(180deg, #8d8a82, #4b4944 55%, #262522);
  --face: linear-gradient(180deg, #5d5b55, #393834 55%, #2c2b28);
  height: 24px;
  padding: 0 13px;
  border-radius: 0;
  background: none;
  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.75));
  color: var(--ink);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.8);
}
.badge::before,
.badge::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  clip-path: polygon(
    var(--cut) 0,
    calc(100% - var(--cut)) 0,
    100% 50%,
    calc(100% - var(--cut)) 100%,
    var(--cut) 100%,
    0 50%
  );
}
.badge::before {
  background: var(--rim);
}
/* 面の上端に 1px の艶 / 1px gloss along the top of the face */
.badge::after {
  inset: 1px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.12) 0 1px, transparent 1px),
    var(--face);
}
.badge--content {
  --rim: linear-gradient(180deg, #b39c64, #5f5135 55%, #2d2618);
  --face: linear-gradient(180deg, #6e6248, #463d2a 55%, #352e1f);
  color: var(--accent-top);
}
.badge--job {
  color: var(--ink);
}
.badge--job .gi {
  color: var(--role);
  filter: drop-shadow(0 0 3px color-mix(in srgb, var(--role) 70%, transparent));
}
.tags .badge {
  --cut: 9px;
  height: 30px;
  padding: 0 16px;
  font-size: 13px;
}

/* 凹んだ面（本文）/ recessed wells */
.excerpt,
.console pre {
  background: var(--well);
  border: 1px solid rgba(0, 0, 0, 0.85);
  box-shadow:
    inset 0 2px 6px rgba(0, 0, 0, 0.7),
    0 1px 0 rgba(255, 255, 255, 0.07);
}
/* 上下の余白は同色の枠線で取る（overflow で 4 行目が余白に見えないように）/ vertical padding via same-colour border so clamped lines never show */
.excerpt {
  padding: 0 12px;
  border: 0;
  border-block: 10px solid var(--well);
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.85),
    inset 0 2px 6px rgba(0, 0, 0, 0.7),
    0 1px 0 1px rgba(255, 255, 255, 0.06);
  max-height: calc(3 * 1.75em + 20px);
}

/* カード下段: レベルは金の小さな大文字、日付は右 / card foot */
.card__foot {
  margin-top: 0;
}
.card__lv {
  color: var(--accent);
  font-weight: 700;
  letter-spacing: 0.08em;
  font-size: 12px;
}

/* ボタン: 灰の面取り。金はアイコンだけ / beveled grey buttons, gold only on the icon */
.btn {
  border: 1px solid rgba(232, 226, 210, 0.42);
  border-radius: 999px;
  background: linear-gradient(180deg, #6a6862, #44433e 50%, #34332f);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.22),
    inset 0 -1px 0 rgba(0, 0, 0, 0.5),
    0 2px 4px rgba(0, 0, 0, 0.5);
  color: var(--ink);
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.7);
  transition:
    filter var(--motion-hover) var(--motion-ease-color),
    transform var(--motion-press) var(--motion-ease);
}
.btn .gi {
  color: var(--accent);
}
.btn:hover {
  filter: brightness(1.15);
}
.btn--ghost {
  background: linear-gradient(180deg, #3e3d39, #2b2a27);
}
.console__copy[data-copied] {
  background: linear-gradient(180deg, #5f8f4e, #3d6a2f);
}

/* マクロ情報: ステータス行（ラベル左・値右寄せ）/ stat rows */
.facts div {
  grid-template-columns: 1fr auto;
  padding: 9px 0;
}
.facts dt {
  color: var(--label);
}
.facts dd {
  text-align: right;
}

/* ページ送り / pager */
.pager__pos {
  color: var(--label);
}

/* ============ 検索フォーム（Task 9.8）/ search form ============ */
.searchform {
  margin-bottom: var(--gap-section);
}
.searchform .search {
  margin-top: 0;
  max-width: none;
}
.filter {
  margin-top: var(--gap-block);
}
.filter > summary {
  cursor: pointer;
  min-height: 44px;
  display: flex;
  align-items: center;
  font-weight: 600;
}
.fgroup {
  margin: var(--gap-item) 0 0;
  padding: 0;
  border: 0;
  min-width: 0;
}
.fgroup legend {
  padding: 0;
  margin-bottom: var(--gap-atom);
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  letter-spacing: 0.04em;
}
.fgroup__items {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-atom);
}
.chk {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-atom);
  min-height: 44px;
  padding: 0 var(--gap-item);
  border-radius: var(--r-sm);
  background: var(--slot);
  cursor: pointer;
}
.chk:has(input:checked) {
  box-shadow: inset 0 0 0 1px var(--accent);
}
.chk:has(input:focus-visible) {
  outline: 2px solid var(--accent);
}
/* 名前は一覧へのリンク。下線で「押すと移動」を示す / the name links to its hub; the underline says it navigates */
.chk a {
  color: inherit;
  text-underline-offset: 0.2em;
}
.searchform__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gap-item);
  margin-top: var(--gap-block);
}
.field {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-atom);
}
.field input,
.field select {
  min-height: 44px;
  padding: 0 var(--gap-item);
  border: 0;
  border-radius: var(--r-sm);
  background: var(--slot);
  color: var(--ink);
  font: inherit;
}
.field input[type="number"] {
  width: 5em;
}

/* ============ 静的ページ / static pages ============ */
.prose {
  max-width: 720px;
  margin-inline: auto;
  line-height: 1.8;
}
/* 本文の下に続くフォーム（/contact）は本文と同じ幅に / a form after the prose (/contact) matches its width */
.prose ~ .macroform {
  max-width: 720px;
  margin-inline: auto;
}
.prose h2 {
  margin-top: var(--gap-block);
}
.prose a {
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ============ UX 監査の対応（2026-10-18、docs/design/ux-audit-2026-10-18.md）/ UX audit fixes ============ */
/* 固定ヘッダーの下にフォーカス先やアンカーが隠れないようにする / keep focused targets clear of the sticky header */
html {
  scroll-padding-top: 80px;
}

/* #11 本文へ移動（フォーカス時だけ表示）/ skip link, visible on focus only */
.skip {
  position: absolute;
  left: 16px;
  top: -100px;
  z-index: 30;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 var(--gap-group);
  border-radius: var(--r-sm);
  background: var(--slot);
  color: var(--ink);
}
.skip:focus {
  top: 10px;
}

/* #14 小さいタップ領域を見た目を変えずに広げる / enlarge small tap areas without changing the look */
.brand {
  min-height: 44px;
}
.credit a {
  padding-block: 14px;
  margin-block: -14px;
}

/* #6 iOS の自動ズームを防ぐため入力系は 16px / 16px inputs so iOS does not zoom on focus */
.search input,
.field input,
.field select {
  font-size: 16px;
}

/* #17 キーワード欄のフォーカスを他と同じ 2px に / 2px focus ring on the keyword field, like elsewhere */
.search:focus-within {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
/* 入力欄の高さいっぱいを押せるようにする / make the full height of the field hit the input */
.search label {
  align-self: stretch;
  display: flex;
}
.search input {
  height: 100%;
}

/* #4 キーワードと検索ボタンを常に見せ、細かい条件は畳む / keyword + submit always visible, filters folded */
.searchform__key {
  display: flex;
  gap: var(--gap-item);
  align-items: center;
}
.searchform__key .search {
  flex: 1;
  margin-top: 0;
  max-width: none;
  min-width: 0;
}
.searchform__key .btn {
  flex: none;
  height: 52px;
}

/* #5 開閉できることが分かる印と、選択数 / disclosure chevron and selected count */
.filter > summary {
  gap: var(--gap-item);
  list-style: none;
}
.filter > summary::-webkit-details-marker {
  display: none;
}
.filter > summary::before {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  margin: 0 4px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
  opacity: 0.7;
}
.filter[open] > summary::before {
  transform: rotate(45deg);
}
@media (prefers-reduced-motion: no-preference) {
  /* 矢印は中身の伸び縮みと同じ速さで回す / the chevron turns with the panel, same duration */
  .filter > summary::before {
    transition: transform var(--motion-expand) var(--motion-ease);
  }
}
.filter__count {
  padding: 2px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 22%, transparent);
  color: var(--ink);
  font-size: 12px;
  font-weight: 600;
}
.filter--more {
  margin-top: var(--gap-item);
}
.filter--more > .filter {
  margin-top: 0;
}
.filter--more > .filter,
.filter--more > .fgroup,
.filter--more > .searchform__row {
  margin-left: var(--gap-group);
}

/* 検索フォームを 1 行にまとめ、ファーストビューを押し下げない（2026-10-21）。
   キーワード・検索ボタン・「絞り込む」を同じ行に置き、開いた条件はその下に全幅で出す。
   details 自体をグリッドにして（display: contents は使わない。開閉の状態が読み上げから落ちることがあるため）、
   1 行目の左にキーワード欄を重ねる。
   One-row search form so it does not push the first view down (2026-10-21). Keyword, submit and the
   filter toggle share a row; opened filters appear full width below. The details stays a real box
   (no display: contents, which can drop its state from the accessibility tree) laid out as a subgrid,
   with the keyword field placed over the left of its first row. */
.searchform {
  margin-block: var(--gap-block);
}
.searchform > .window__body {
  display: grid;
  grid-template-columns: 1fr auto;
  column-gap: var(--gap-item);
  align-items: start;
  padding: var(--gap-item);
}
.searchform .searchform__key {
  grid-area: 1 / 1;
  position: relative;
  z-index: 1;
}
.searchform .filter--more {
  grid-column: 1 / -1;
  grid-row: 1;
  display: grid;
  grid-template-columns: subgrid;
  margin-top: 0;
}
.searchform .filter--more > summary {
  grid-column: 2;
  grid-row: 1;
  min-height: 52px;
  padding-inline: var(--gap-item) var(--gap-group);
  border-radius: var(--r-sm);
  white-space: nowrap;
}
.searchform .filter--more::details-content,
.searchform .filter--more > :not(summary) {
  grid-column: 1 / -1;
}
.searchform .filter--more[open] > summary {
  color: var(--ink);
}
/* 開いた条件の 1 段目と、上の行の間をあける / space between the row and the opened filters */
.searchform .filter--more > :nth-child(2) {
  margin-top: var(--gap-item);
}
@media (max-width: 479px) {
  /* 狭い画面では「条件で」を省き、検索ボタンは虫眼鏡だけにして、キーワード欄の幅を残す（ボタン名は読み上げ用に残す）
     Narrow screens: drop 条件で and show only the magnifier on submit to keep the field wide
     (the label stays for screen readers) */
  .filter__wide {
    display: none;
  }
  .searchform__key .btn {
    width: 52px;
    padding: 0;
    justify-content: center;
  }
  .searchform__key .btn__label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
  .searchform .filter--more > summary {
    padding-inline: 0 var(--gap-item);
  }
}

/* コンテンツ選択: 拡張ごとに畳み、高難易度は段ごとに色の帯で見分ける（2026-10-18 提案）
   Content picker: folded per expansion; high-end tiers marked with a colored edge (proposal 2026-10-18)
   色だけに頼らないよう、段の見出し（極・幻 / 零式・滅 / 絶）を必ず添える / always paired with the tier legend text */
:root {
  --tier-extreme: #7fa8d8;
  --tier-savage: #d8665e;
  --tier-chaotic: #a985db;
  --tier-ultimate: #e2bd6a;
}
.chk[data-tier="extreme"] {
  --tier-c: var(--tier-extreme);
}
.chk[data-tier="savage"] {
  --tier-c: var(--tier-savage);
}
.chk[data-tier="chaotic"] {
  --tier-c: var(--tier-chaotic);
}
.chk[data-tier="ultimate"] {
  --tier-c: var(--tier-ultimate);
}
.chk[data-tier] {
  box-shadow: inset 3px 0 0 var(--tier-c);
}
.chk[data-tier]:has(input:checked) {
  box-shadow:
    inset 3px 0 0 var(--tier-c),
    inset 0 0 0 1px var(--accent);
}
.fgroup--tier legend {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--ink);
}
.fgroup--tier:has([data-tier="extreme"]) legend::before,
.fgroup--tier:has([data-tier="savage"]) legend::before,
.fgroup--tier:has([data-tier="ultimate"]) legend::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 2px;
  transform: rotate(45deg);
}
.fgroup--tier:has([data-tier="extreme"]) legend::before {
  background: var(--tier-extreme);
}
.fgroup--tier:has([data-tier="savage"]) legend::before {
  background: var(--tier-savage);
}
.fgroup--tier:has([data-tier="ultimate"]) legend::before {
  background: var(--tier-ultimate);
}
.filter--ex > .fgroup,
.filter--ex > .filter {
  margin-left: var(--gap-group);
}
.filter--normal > .fgroup {
  margin-left: var(--gap-group);
}
.filter__total {
  color: var(--muted);
  font-size: 12px;
  font-weight: 400;
}
/* 入れ子が 4 段になるので、狭い画面では字下げをやめる / 4 levels of nesting: drop indents on narrow screens */
@media (max-width: 479px) {
  .filter--more > .filter,
  .filter--more > .fgroup,
  .filter--more > .searchform__row,
  .filter--ex > .fgroup,
  .filter--ex > .filter,
  .filter--normal > .fgroup {
    margin-left: 0;
  }
}

/* #13 使用レベルの補足 / hint after the level input */
.field__hint {
  color: var(--muted);
  font-size: 13px;
}

/* #2 コピーの結果。失敗の案内だけ見せ、成功は読み上げのみ / copy result: failure hint is visible, success is announced only */
.console__msg {
  margin: 0;
  padding: var(--gap-item) var(--gap-group) 0;
  font-size: 13px;
  color: var(--ink);
}
.console__msg:empty {
  display: none;
}
.console:has(.console__copy[data-copied]) .console__msg {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
}
.console__copy[data-copy-failed] {
  box-shadow: inset 0 0 0 1px var(--accent);
}

/* #15 ページ番号 / page numbers */
.pager__nums {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--gap-atom);
  margin: 0;
  padding: 0;
  list-style: none;
}
/* 狭い画面では番号を 1 行に、前後のリンクをその下に / on narrow screens, numbers get their own row above prev/next */
@media (max-width: 479px) {
  .pager {
    flex-wrap: wrap;
  }
  .pager__nums {
    order: -1;
    flex-basis: 100%;
  }
}
.pager__gap {
  display: inline-grid;
  place-items: center;
  min-width: 24px;
  height: 44px;
  color: var(--muted);
}

/* #8 404 / 410 */
.notfound h1 {
  margin: 0;
  font-size: 22px;
}
.notfound .searchform__key {
  width: 100%;
  max-width: 34rem;
}

/* ============ 操作の手応えと動き（2026-10-21）/ press feedback and motion ============
   方針（emil-design-eng・ui-ux-pro-max §2 §7）: 押したら 100ms 以内に反応、UI の動きは 300ms 未満、
   入るときは ease-out、動かすのは transform と opacity だけ。何度も触る部分ほど控えめにする。
   Rules: react within 100ms of a press, keep UI motion under 300ms, ease-out on enter,
   animate only transform/opacity, and keep frequently used controls subtle. */
/* 動きの値はすべて Open Props（/assets/open-props.css、scripts/vendor-open-props.ts）から取り、
   用途ごとの名前をここで付ける。部品のルールは --motion-* だけを使う。
   Every motion value comes from Open Props (/assets/open-props.css); this block names them by purpose,
   and component rules use only --motion-*. */
:root {
  /* 入る・押す・動く / enter, press, move */
  --motion-ease: var(--ease-out-4);
  /* 色や影の変化 / color and shadow changes */
  --motion-ease-color: var(--ease-3);
  /* 120ms 押した反応 / press */
  --motion-press: var(--duration-quick-2);
  /* 180ms ホバーの色 / hover color */
  --motion-hover: var(--duration-moderate-1);
  /* 180ms 開閉・状態の切り替え / open, state change */
  --motion-open: var(--duration-moderate-1);
  /* 260ms 絞り込みの開閉 / filter expand and collapse */
  --motion-expand: var(--duration-moderate-2);
  /* 260ms カードの浮き / card lift */
  --motion-move: var(--duration-moderate-2);
  /* 320ms 一覧が出るとき / list entrance */
  --motion-enter: var(--duration-gentle-1);
  /* 2px 開いた中身が現れるときのぼかし（Open Props にないので transitions-dev の基準値）
     2px blur on revealed content (not in Open Props; transitions-dev's value) */
  --motion-blur: 2px;
}

/* 標準のタップの青い光を消し、下の :active で代わりの反応を出す。ダブルタップの拡大待ちもなくす
   Replace the default tap flash with our own :active states, and drop the double-tap zoom delay */
a,
button,
summary,
label,
select,
input {
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

/* 押したときの沈み込み（チップ・開閉・ページ送り・タグ・カード）/ press-down on chips, toggles, pager, tags, cards */
.chk,
.filter > summary,
.pager a,
.tag-link,
.quickcopy {
  transition:
    transform var(--motion-press) var(--motion-ease),
    background-color var(--motion-press) var(--motion-ease-color),
    box-shadow var(--motion-press) var(--motion-ease-color);
}
.chk:active,
.pager a:active,
.tag-link:active,
.quickcopy:active {
  transform: scale(0.96);
}
.filter > summary:active {
  transform: scale(0.98);
  transform-origin: left center;
}
/* カードは大きいので沈みは浅く / cards are large, so the press is shallow */
.card:active {
  transform: scale(0.985);
  transition-duration: var(--motion-press);
}
/* 文字だけのリンクは沈ませず、押した瞬間に薄くする / text links fade on press instead of moving */
.nav a:active,
.crumbs a:active,
.foot a:active,
.empty p a:active,
.prose a:active {
  opacity: 0.6;
}

/* チップのホバー（マウスのときだけ）/ chip hover, mouse only */
@media (hover: hover) and (pointer: fine) {
  .chk:hover {
    background: color-mix(in srgb, var(--ink) 8%, var(--slot));
  }
  .filter > summary:hover {
    color: var(--ink);
  }
}
/* タッチ端末ではホバーで浮いたままにしない / touch devices: no sticky hover lift */
@media (hover: none) {
  .card:hover {
    transform: none;
  }
}

/* チェックを入れた瞬間に軽く弾ませる（状態が変わったことを示す）/ a small pop when a chip gets checked */
@media (prefers-reduced-motion: no-preference) {
  .chk input:checked {
    animation: chk-pop var(--motion-open) var(--motion-ease);
  }
}
@keyframes chk-pop {
  from {
    /* 0.9 より小さいと弾みでなく拡大に見える / below 0.9 it reads as a zoom, not a pop */
    transform: scale(0.94);
  }
}

/* 開閉は高さごと伸び縮みさせ、何が開いて何が閉じたかを見せる（Material の展開・折りたたみ）。
   ::details-content と interpolate-size に対応しないブラウザは、今までどおり即時に開閉する。
   interpolate-size は継承されるので .filter に限る（サイト全体の height: auto を動かさない）。
   Expand and collapse by height so the change is visible (Material expand/collapse). Browsers without
   ::details-content / interpolate-size keep the instant toggle. interpolate-size inherits, so it is
   scoped to .filter rather than :root. */
@media (prefers-reduced-motion: no-preference) {
  .filter {
    interpolate-size: allow-keywords;
  }
  .filter::details-content {
    block-size: 0;
    opacity: 0;
    filter: blur(var(--motion-blur));
    overflow: clip;
    transition:
      block-size var(--motion-expand) var(--motion-ease),
      opacity var(--motion-expand) var(--motion-ease),
      filter var(--motion-expand) var(--motion-ease),
      content-visibility var(--motion-expand) allow-discrete;
  }
  .filter[open]::details-content {
    block-size: auto;
    opacity: 1;
    filter: none;
  }
}
/* コピー結果のメッセージが出るとき / copy status message entrance */
@keyframes fold-in {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
}

/* コピー結果のメッセージ / copy status message */
@media (prefers-reduced-motion: no-preference) {
  .console__msg:not(:empty) {
    animation: fold-in var(--motion-open) var(--motion-ease);
  }
}

/* ボタンの文言の切り替え（transitions-dev の text morph。組み立ては copy.js）。共通部分は動かさず、
   違う部分だけを同じマスに重ねてぼかしで入れ替え、マスの幅をなめらかに変える。
   Button label change (transitions-dev text morph; copy.js builds it). Shared letters stay; the differing
   parts share one grid cell and cross-blur while the cell's width eases. */
.t-morph-swap {
  display: inline-grid;
  vertical-align: bottom;
  justify-items: start;
  white-space: nowrap;
  transition: width var(--motion-move) var(--motion-ease);
}
.t-morph-swap > span {
  grid-area: 1 / 1;
  white-space: pre;
  transition:
    opacity var(--motion-open) var(--motion-ease),
    filter var(--motion-open) var(--motion-ease);
}
.t-morph-new {
  opacity: 0;
  filter: blur(var(--motion-blur));
}
.t-morph-swap.is-morphing .t-morph-old {
  opacity: 0;
  filter: blur(var(--motion-blur));
}
.t-morph-swap.is-morphing .t-morph-new {
  opacity: 1;
  filter: none;
}

/* ページ間の移動はブラウザの View Transitions で重ねて切り替える（同じオリジンの通常のリンク移動だけ）
   Cross-document View Transitions crossfade same-origin navigations (no JS) */
@view-transition {
  navigation: auto;
}
/* タイトルと本文の変形（--motion-move）と同じ長さにして、ページ全体だけ先に終わらないようにする
   Same length as the title/body morphs so the page crossfade does not finish first */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: var(--motion-move);
  animation-timing-function: var(--motion-ease);
}
/* 上の全体の reduce 指定は ::view-transition-* に届かないので、ここで止める
   The global reduce rule does not reach ::view-transition-*, so turn transitions off here */
@media (prefers-reduced-motion: reduce) {
  @view-transition {
    navigation: none;
  }
}

/* 一覧のカードの見出しと詳細の見出しをつなぐ（Material の共有要素の遷移。一覧側の名前は
   public/assets/page-transition.js が付ける）。幅を文字に合わせ、切り取った画像が引き伸ばされないようにする。
   Shared title between a list card and the detail heading (Material shared-element transition;
   page-transition.js names the card side). Widths hug the text so snapshots are not stretched. */
.card h2,
.detail__head h1 {
  width: fit-content;
}
.detail__head h1 {
  view-transition-name: macro-title;
}
::view-transition-group(macro-title) {
  animation-duration: var(--motion-move);
  animation-timing-function: var(--motion-ease);
}
::view-transition-old(macro-title),
::view-transition-new(macro-title) {
  height: 100%;
  width: auto;
}

/* カードの枠が詳細の本文の窓へ広がる（Material のコンテナ変形。一覧側の名前は page-transition.js）。
   切り取った画像を枠に合わせて伸ばすと文字が倍に膨らむので、画像は原寸のまま左上に置き、広がる枠で切り抜く。
   枠そのものは窓と同じ地と縁で描き、画像が入れ替わる間も「1 つの窓が広がる」ように見せる。
   The card frame grows into the detail body window (Material container transform; page-transition.js names
   the card). Scaling the snapshots to the frame doubles the text size, so they stay at natural size, pinned
   top-left and clipped by the growing frame. The frame paints the window surface and edge itself, so it reads
   as one window growing while the snapshots crossfade. */
.detail .console {
  view-transition-name: macro-body;
}
::view-transition-group(macro-body) {
  animation-duration: var(--motion-move);
  animation-timing-function: var(--motion-ease);
  overflow: clip;
  border: 1px solid var(--win-edge);
  border-radius: var(--r);
  background: var(--win);
}
::view-transition-old(macro-body),
::view-transition-new(macro-body) {
  width: auto;
  height: auto;
  object-fit: none;
  object-position: left top;
  inset: -1px auto auto -1px;
}

/* ============ 投稿・編集フォーム / post & edit form (12.9) ============ */
/* 入力欄は縦積み・幅いっぱい。テキストエリアは検索欄と同じ凹んだスロット。
   Fields stack and fill the width; textareas reuse the recessed slot of the search inputs. */
.macroform .field {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--gap-atom);
  margin-bottom: var(--gap-group);
}
.macroform .field input,
.macroform .field textarea {
  box-sizing: border-box;
  max-width: 100%;
  padding: var(--gap-item);
  border: 0;
  border-radius: var(--r-sm);
  background: var(--slot);
  color: var(--ink);
  font: inherit;
  font-size: 16px; /* iOS の自動ズーム防止 / avoid iOS zoom */
}
.macroform .field input:not([type="number"]),
.macroform .field textarea {
  width: 100%;
}
.macroform .field input {
  min-height: 44px;
}
.macroform .field textarea {
  min-height: 6em;
  resize: vertical;
}
.macroform .field input:focus-visible,
.macroform .field textarea:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
/* マクロ本文は等幅で / the macro body in monospace */
.macroform textarea[name="body"] {
  font-family: var(--macro-font);
}
/* マクロ本文の入力欄: 左に行番号、右に textarea。折り返さず、行の高さと上の余白をそろえて番号と行を合わせる。
   高さは 15 行（ゲームの 1 マクロ）＋横スクロールバーの分。
   Macro boxes: line numbers left, textarea right. No wrapping; same line height and top padding keep numbers
   aligned with lines. Height fits 15 lines (one in-game macro) plus a horizontal scrollbar. */
.macrobody {
  min-width: 0;
  margin-inline: 0;
  padding: 0;
  border: 0;
}
.macrobox {
  display: flex;
  flex-direction: column;
  gap: var(--gap-atom);
}
.macrobox__label {
  color: var(--muted);
  font-size: 13px;
}
.macrobox__edit {
  display: flex;
  border-radius: var(--r-sm);
  background: var(--slot);
}
.macrobox__ln,
.macroform .macrobox textarea {
  font-family: var(--macro-font);
  font-size: 16px;
  line-height: 1.6;
}
.macrobox__ln {
  margin: 0;
  padding: var(--gap-item) 0 var(--gap-item) var(--gap-item);
  min-width: 2em;
  color: var(--muted);
  text-align: right;
  user-select: none;
}
.macroform .macrobox textarea {
  flex: 1;
  min-width: 0;
  min-height: 0;
  block-size: calc(15lh + 2 * var(--gap-item) + 16px);
  resize: none;
  white-space: pre;
  overflow-x: auto;
}
/* フォーカス枠は行番号ごと囲む / the focus ring wraps the line numbers too */
.macroform .macrobox textarea:focus-visible {
  outline: 0;
}
.macrobox__edit:focus-within {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
.macrobox__add {
  align-self: flex-start;
}
/* .btn の display より優先する（JS なし・上限到達で隠す）/ beat .btn's display (hidden without JS or at the cap) */
.macrobox__add[hidden] {
  display: none;
}
.macroform .filter,
.macroform .fgroup {
  margin-bottom: var(--gap-group);
}
.macroform .cf-turnstile {
  margin-block: var(--gap-group);
}
.macroform__acts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-item);
}

/* エラーは赤系トークン + 文言で示す（色だけに頼らない）/ errors use the red token plus text, never color alone */
.field__error {
  color: var(--dps);
  font-size: 13px;
}
.field__error::before {
  content: "! ";
  font-weight: 700;
}
.form-errors {
  margin-bottom: var(--gap-block);
  padding: var(--gap-group);
  border: 1px solid var(--dps);
  border-radius: var(--r);
  background: var(--slot);
  color: var(--ink);
  overflow-wrap: anywhere;
}
.form-errors p {
  margin: 0 0 var(--gap-item);
  font-weight: 700;
}
.form-errors ul {
  margin: 0;
  padding-left: 1.2em;
}

/* 送信前プレビュー（窓の下に間隔だけ足す）/ pre-submit preview: spacing below the window only */
.preview {
  margin-bottom: var(--gap-block);
  overflow-wrap: anywhere;
}

/* ============ ログイン・マイページ / login and my page ============ */
/* 話題ごとに窓を分け、窓同士は --gap-block、窓の中は --gap-group で区切る */
/* One window per topic: --gap-block between windows, --gap-group inside */
.me {
  display: grid;
  gap: var(--gap-block);
  max-width: 720px;
  margin-inline: auto;
}
/* 上の余白は他ページの h1 と同じまま、下は grid の gap に任せる / keep the usual top margin; gap handles the bottom */
.me h1 {
  margin-bottom: 0;
}
.me__body {
  display: grid;
  gap: var(--gap-group);
  line-height: 1.8;
}
.me__body p {
  margin: 0;
}
.me__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-item);
  margin: 0;
}
.me__account {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap-group);
}
.me__account form {
  margin: 0;
}

/* 自分のマクロ: 1 行 = 状態・タイトル・操作 / my macros: one row = status, title, actions */
.mylist {
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
}
.mylist__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gap-item);
  padding-block: var(--gap-item);
  border-top: 1px solid var(--rule);
}
.mylist__row:first-child {
  border-top: 0;
  padding-top: 0;
}
.mylist__row:last-child {
  padding-bottom: 0;
}
.mylist__title {
  flex: 1 1 12em;
  min-width: 0;
  overflow-wrap: anywhere;
}
.mylist__ops {
  display: flex;
  gap: var(--gap-item);
}
