L-011 Layout medium

Editorial Bento Grid エディトリアルベントーグリッド

Magazine typography layout with geometric cards and instant category filtering between Design, Art, and All views. 雑誌風タイポグラフィと幾何学カードのカテゴリ別表示切替UI。

ライブデモ Live Demo

ISSUE VOL. 08

ARCHIVE DISPATCH

DESIGN

Brutalist Geometry in Modern Web

Examining raw grid structures and monospace hierarchy in contemporary digital publications.

ART

Neo-Chromatic Forms

High-contrast abstractions and vibrant saturation.

DESIGN

Modular Kinetic Type

Variable font weights powering responsive systems.

概要・用途・特徴Overview, Usage & Features

何ができるかWhat it does

Magazine typography layout with geometric cards and instant category filtering between Design, Art, and All views.

雑誌風タイポグラフィと幾何学カードのカテゴリ別表示切替UI。

どこで使うかWhere to use

Portfolio, product showcase, landing page.

ポートフォリオ、製品紹介、ランディングページ。

特徴Key features

Magazine typography layout with geometric cards and instant category filtering between Design, Art, and All views.

雑誌風タイポグラフィと幾何学カードのカテゴリ別表示切替UI。

調整可能パラメータ Adjustable Parameters

Parameter Default Description
--demo-accent#c2410cAccent color for the panel border and keyboard focus ring.

実装コード Implementation Code

<div class="demo-stage eb-root" role="region" aria-label="Editorial Bento Grid"><div class="eb-container"><div class="eb-header"><div class="eb-title-meta"><span class="eb-kicker">ISSUE VOL. 08</span><h3 class="eb-heading">ARCHIVE DISPATCH</h3></div><div class="eb-filter-group" role="group" aria-label="Filter articles"><button type="button" class="eb-btn eb-active" data-filter="all" aria-pressed="true" aria-label="Show all articles">All</button><button type="button" class="eb-btn" data-filter="design" aria-pressed="false" aria-label="Filter by Design category">Design</button><button type="button" class="eb-btn" data-filter="art" aria-pressed="false" aria-label="Filter by Art category">Art</button></div></div><div class="eb-grid"><div class="eb-card eb-card-lg" data-category="design"><span class="eb-tag">DESIGN</span><h4 class="eb-card-title">Brutalist Geometry in Modern Web</h4><p class="eb-card-snippet">Examining raw grid structures and monospace hierarchy in contemporary digital publications.</p></div><div class="eb-card eb-card-sm" data-category="art"><span class="eb-tag">ART</span><h4 class="eb-card-title">Neo-Chromatic Forms</h4><p class="eb-card-snippet">High-contrast abstractions and vibrant saturation.</p></div><div class="eb-card eb-card-sm" data-category="design"><span class="eb-tag">DESIGN</span><h4 class="eb-card-title">Modular Kinetic Type</h4><p class="eb-card-snippet">Variable font weights powering responsive systems.</p></div></div></div></div>
<script>
document.querySelectorAll('.eb-root').forEach(root => {
  const filterBtns = root.querySelectorAll('.eb-btn');
  const cards = root.querySelectorAll('.eb-card');
  if (!filterBtns.length || !cards.length) return;
  filterBtns.forEach(btn => {
    btn.addEventListener('click', () => {
      filterBtns.forEach(b => {
        b.classList.remove('eb-active');
        b.setAttribute('aria-pressed', 'false');
      });
      btn.classList.add('eb-active');
      btn.setAttribute('aria-pressed', 'true');
      const filter = btn.dataset.filter;
      cards.forEach(card => {
        const match = filter === 'all' || card.dataset.category === filter;
        card.style.display = match ? 'flex' : 'none';
      });
    });
  });
});
</script>
.eb-root {
  box-sizing: border-box;
  width: 100%;
  max-width: 560px;
  max-height: 420px;
  min-width: 0;
  margin: 0 auto;
  padding: 16px;
  background: #f4efe6;
  border-radius: 16px;
  border: 1px solid #dfd7c9;
  box-shadow: 0 16px 36px rgba(0, 0, 0, 0.15);
  font-family: Georgia, serif;
  color: #1a1917;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.eb-root *, .eb-root *::before, .eb-root *::after {
  box-sizing: border-box;
  min-width: 0;
}
.eb-root .eb-container {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.eb-root .eb-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  border-bottom: 2px solid #1a1917;
  padding-bottom: 8px;
  flex-wrap: wrap;
  gap: 8px;
}
.eb-root .eb-title-meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.eb-root .eb-kicker {
  font-family: system-ui, sans-serif;
  font-size: 8px;
  letter-spacing: 1.5px;
  font-weight: 800;
  color: #78716c;
}
.eb-root .eb-heading {
  margin: 0;
  font-size: 18px;
  font-weight: 900;
  letter-spacing: -0.5px;
  color: #1a1917;
}
.eb-root .eb-filter-group {
  display: flex;
  gap: 4px;
}
.eb-root .eb-btn {
  appearance: none;
  border: 1px solid #1a1917;
  background: transparent;
  color: #1a1917;
  padding: 4px 10px;
  border-radius: 4px;
  font-family: system-ui, sans-serif;
  font-size: 11px;
  font-weight: 700;
  cursor: pointer;
}
.eb-root .eb-btn.eb-active {
  background: #1a1917;
  color: #f4efe6;
}
.eb-root .eb-btn:focus-visible {
  outline: 2px solid #ea580c;
  outline-offset: 2px;
}
.eb-root .eb-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
}
.eb-root .eb-card {
  background: #ffffff;
  border: 1px solid #dcd5c7;
  border-radius: 8px;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.eb-root .eb-tag {
  font-family: system-ui, sans-serif;
  font-size: 8px;
  font-weight: 800;
  color: #c2410c;
  letter-spacing: 0.5px;
}
.eb-root .eb-card-title {
  margin: 0;
  font-size: 13px;
  font-weight: 800;
  line-height: 1.25;
  color: #0c0a09;
}
.eb-root .eb-card-snippet {
  margin: 0;
  font-family: system-ui, sans-serif;
  font-size: 10px;
  color: #57534e;
  line-height: 1.4;
}
@media (prefers-reduced-motion: no-preference) {
  .eb-root .eb-btn {
    transition: background 0.15s ease, color 0.15s ease, transform 0.1s ease;
  }
  .eb-root .eb-btn:active {
    transform: scale(0.95);
  }
  .eb-root .eb-card {
    transition: transform 0.2s ease, box-shadow 0.2s ease;
  }
  .eb-root .eb-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  }
}
.eb-root{max-height:none;--demo-accent:#c2410c;border-color:var(--demo-accent)}.eb-root button:focus-visible{outline-color:var(--demo-accent)}
.eb-root .eb-grid{grid-template-columns:1.15fr 1fr}.eb-root .eb-card-lg{grid-row:span 2;position:relative;padding-bottom:70px;overflow:hidden;background:#fb6b38}.eb-root .eb-card-lg::after{content:"";position:absolute;width:90px;height:90px;border:18px solid #1a1917;border-radius:50%;bottom:-20px;right:-10px;transform:rotate(-20deg)}.eb-root .eb-card-lg .eb-tag{color:#29211b}.eb-root .eb-card-lg .eb-card-snippet{color:#312821}.eb-root .eb-card-sm:nth-child(2){background:repeating-linear-gradient(135deg,#ebe5ff 0 8px,#f2edff 8px 16px)}.eb-root .eb-card-sm:nth-child(3){background:#fff4bf}@media(max-width:360px){.eb-root .eb-grid{gap:6px}.eb-root .eb-card{padding:9px}}
import { useState } from "react";
import "./L-011.css";
function EditorialBentoGrid() {
  const [filter, setFilter] = useState("all");
  return <div className="demo-stage eb-root" role="region" aria-label="Editorial Bento Grid"><div className="eb-container"><div className="eb-header"><div className="eb-title-meta"><span className="eb-kicker">{"ISSUE VOL. 08"}</span><h3 className="eb-heading">{"ARCHIVE DISPATCH"}</h3></div><div className="eb-filter-group" role="group" aria-label="Filter articles"><button type="button" data-filter="all" aria-label="Show all articles" className={"eb-btn" + (filter === "all" ? " eb-active" : "")} aria-pressed={filter === "all"} onClick={() => setFilter("all")}>{"All"}</button><button type="button" data-filter="design" aria-label="Filter by Design category" className={"eb-btn" + (filter === "design" ? " eb-active" : "")} aria-pressed={filter === "design"} onClick={() => setFilter("design")}>{"Design"}</button><button type="button" data-filter="art" aria-label="Filter by Art category" className={"eb-btn" + (filter === "art" ? " eb-active" : "")} aria-pressed={filter === "art"} onClick={() => setFilter("art")}>{"Art"}</button></div></div><div className="eb-grid"><div className="eb-card eb-card-lg" data-category="design" style={{ display: filter === "all" || filter === "design" ? "flex" : "none", gridRow: filter === "all" && true ? "span 2" : "auto", gridColumn: filter === "art" ? "1 / -1" : "auto" }}><span className="eb-tag">{"DESIGN"}</span><h4 className="eb-card-title">{"Brutalist Geometry in Modern Web"}</h4><p className="eb-card-snippet">{"Examining raw grid structures and monospace hierarchy in contemporary digital publications."}</p></div><div className="eb-card eb-card-sm" data-category="art" style={{ display: filter === "all" || filter === "art" ? "flex" : "none", gridRow: filter === "all" && false ? "span 2" : "auto", gridColumn: filter === "art" ? "1 / -1" : "auto" }}><span className="eb-tag">{"ART"}</span><h4 className="eb-card-title">{"Neo-Chromatic Forms"}</h4><p className="eb-card-snippet">{"High-contrast abstractions and vibrant saturation."}</p></div><div className="eb-card eb-card-sm" data-category="design" style={{ display: filter === "all" || filter === "design" ? "flex" : "none", gridRow: filter === "all" && false ? "span 2" : "auto", gridColumn: filter === "art" ? "1 / -1" : "auto" }}><span className="eb-tag">{"DESIGN"}</span><h4 className="eb-card-title">{"Modular Kinetic Type"}</h4><p className="eb-card-snippet">{"Variable font weights powering responsive systems."}</p></div></div></div></div>;
}
export {
  EditorialBentoGrid as default
};
.eb-root {
  box-sizing: border-box;
  width: 100%;
  max-width: 560px;
  max-height: 420px;
  min-width: 0;
  margin: 0 auto;
  padding: 16px;
  background: #f4efe6;
  border-radius: 16px;
  border: 1px solid #dfd7c9;
  box-shadow: 0 16px 36px rgba(0, 0, 0, 0.15);
  font-family: Georgia, serif;
  color: #1a1917;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.eb-root *, .eb-root *::before, .eb-root *::after {
  box-sizing: border-box;
  min-width: 0;
}
.eb-root .eb-container {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.eb-root .eb-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  border-bottom: 2px solid #1a1917;
  padding-bottom: 8px;
  flex-wrap: wrap;
  gap: 8px;
}
.eb-root .eb-title-meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.eb-root .eb-kicker {
  font-family: system-ui, sans-serif;
  font-size: 8px;
  letter-spacing: 1.5px;
  font-weight: 800;
  color: #78716c;
}
.eb-root .eb-heading {
  margin: 0;
  font-size: 18px;
  font-weight: 900;
  letter-spacing: -0.5px;
  color: #1a1917;
}
.eb-root .eb-filter-group {
  display: flex;
  gap: 4px;
}
.eb-root .eb-btn {
  appearance: none;
  border: 1px solid #1a1917;
  background: transparent;
  color: #1a1917;
  padding: 4px 10px;
  border-radius: 4px;
  font-family: system-ui, sans-serif;
  font-size: 11px;
  font-weight: 700;
  cursor: pointer;
}
.eb-root .eb-btn.eb-active {
  background: #1a1917;
  color: #f4efe6;
}
.eb-root .eb-btn:focus-visible {
  outline: 2px solid #ea580c;
  outline-offset: 2px;
}
.eb-root .eb-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
}
.eb-root .eb-card {
  background: #ffffff;
  border: 1px solid #dcd5c7;
  border-radius: 8px;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.eb-root .eb-tag {
  font-family: system-ui, sans-serif;
  font-size: 8px;
  font-weight: 800;
  color: #c2410c;
  letter-spacing: 0.5px;
}
.eb-root .eb-card-title {
  margin: 0;
  font-size: 13px;
  font-weight: 800;
  line-height: 1.25;
  color: #0c0a09;
}
.eb-root .eb-card-snippet {
  margin: 0;
  font-family: system-ui, sans-serif;
  font-size: 10px;
  color: #57534e;
  line-height: 1.4;
}
@media (prefers-reduced-motion: no-preference) {
  .eb-root .eb-btn {
    transition: background 0.15s ease, color 0.15s ease, transform 0.1s ease;
  }
  .eb-root .eb-btn:active {
    transform: scale(0.95);
  }
  .eb-root .eb-card {
    transition: transform 0.2s ease, box-shadow 0.2s ease;
  }
  .eb-root .eb-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  }
}
.eb-root{max-height:none;--demo-accent:#c2410c;border-color:var(--demo-accent)}.eb-root button:focus-visible{outline-color:var(--demo-accent)}
.eb-root .eb-grid{grid-template-columns:1.15fr 1fr}.eb-root .eb-card-lg{grid-row:span 2;position:relative;padding-bottom:70px;overflow:hidden;background:#fb6b38}.eb-root .eb-card-lg::after{content:"";position:absolute;width:90px;height:90px;border:18px solid #1a1917;border-radius:50%;bottom:-20px;right:-10px;transform:rotate(-20deg)}.eb-root .eb-card-lg .eb-tag{color:#29211b}.eb-root .eb-card-lg .eb-card-snippet{color:#312821}.eb-root .eb-card-sm:nth-child(2){background:repeating-linear-gradient(135deg,#ebe5ff 0 8px,#f2edff 8px 16px)}.eb-root .eb-card-sm:nth-child(3){background:#fff4bf}@media(max-width:360px){.eb-root .eb-grid{gap:6px}.eb-root .eb-card{padding:9px}}

仕組みとカスタマイズHow It Works & Customization

仕組みHow it works

Scoped CSS creates the visual design; small vanilla JavaScript handlers update the local demo state.

スコープ化したCSSで描画し、Vanilla JavaScriptでデモ内の状態だけを更新します。

カスタマイズ方法Customization

Accent color for the panel border and keyboard focus ring.

パネルの枠線とキーボードフォーカスの色を変更します。

注意点Caveats

The sample content is fictional. No external assets or libraries are required. Motion follows the operating system preference. Demo labels are English; surrounding documentation supports Japanese and English.

デモ内容は架空です。外部素材・ライブラリは不要。OSの動きを減らす設定に対応します。デモ内のラベルは英語、解説は日英対応です。

よくある質問 Frequently Asked Questions

Does this demo need external libraries? 外部ライブラリは必要ですか?

The sample content is fictional. No external assets or libraries are required. Motion follows the operating system preference. Demo labels are English; surrounding documentation supports Japanese and English.

デモ内容は架空です。外部素材・ライブラリは不要。OSの動きを減らす設定に対応します。デモ内のラベルは英語、解説は日英対応です。

AIへの指示テンプレート AI Prompt Template

以下をAIに貼り付けると実装を依頼できます。 Paste the following into your AI assistant to request implementation.