/* ======================================================================
   Bento: the shared master for an illustrated cell grid (first built as the Municipalities "Data driven" section,
   round 9, 2026-10-10; extracted 2026-10-15). One cell = a figure area with a dotted ground and an inline SVG that can
   loop, then a title and a caption. How to adopt it on a page: docs/BENTO.md. To change the look everywhere, edit
   THIS file only; the drawings and their loops are page-owned (page-prefixed group classes and keyframes).

   Link order: tokens.css, site.css, bento.css, then the page's own stylesheet.
   Script: js/bento.js (runs the loops only while the grid is in view; reduced motion = the settled frame).

   Hairline grid, no gaps: each cell draws its own right and bottom hairline; the grid's ::before draws the top and
   left ones, so no line is ever doubled, whatever the column count.
   Dot ground: the figure's ::before is a 24px radial-gradient dot grid (border/decorative at 60%), masked so it fades
   out towards every edge of the figure (64 left / right / bottom, 48 top).
   Base styles = the most complete frame (reduced motion and .is-static show exactly that); the loops are CSS keyframes
   on SVG groups, authored paused, running only while the root has .is-running. transform / opacity /
   stroke-dashoffset only.
   ====================================================================== */

/* ---------- the grid ----------
   Dials (set on the .bento or any ancestor): --bento-cell-h (cell height, 520) and --bento-fig-h (figure area, 300).
   Columns: 3 by default, .bento--2 for two, .bento--4 for four. */
.bento {
  position: relative; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  margin: var(--pn-space-64) 0 0; padding: 0; list-style: none;
}
.bento--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.bento--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.bento::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  border-top: 1px solid var(--pn-color-border-decorative); border-left: 1px solid var(--pn-color-border-decorative);
}
.bento__cell {
  display: flex; flex-direction: column; height: var(--bento-cell-h, 520px);
  border-right: 1px solid var(--pn-color-border-decorative); border-bottom: 1px solid var(--pn-color-border-decorative);
}
/* 36 top padding drops the 200-tall drawing a little below the figure's centre, clear of the label plate */
.bento__fig { position: relative; flex: none; height: var(--bento-fig-h, 300px); padding-top: 36px; display: grid; place-items: center; }
.bento__fig::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image: radial-gradient(circle, color-mix(in srgb, var(--pn-color-border-decorative) 60%, transparent) 1px, transparent 1.5px);
  background-size: 24px 24px; background-position: 12px 12px;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 64px, #000 calc(100% - 64px), transparent),
                      linear-gradient(to bottom, transparent, #000 48px, #000 calc(100% - 64px), transparent);
  -webkit-mask-composite: source-in;
  mask-image: linear-gradient(to right, transparent, #000 64px, #000 calc(100% - 64px), transparent),
              linear-gradient(to bottom, transparent, #000 48px, #000 calc(100% - 64px), transparent);
  mask-composite: intersect;
}
/* the FIG_0N label on its surface plate (a page may hide it: Municipalities does, in site.css) */
.bento__label {
  position: absolute; top: 20px; left: 20px; z-index: 1;
  padding: 4px 8px; border-radius: var(--pn-radius-control);
  background: var(--pn-color-background-surface); color: var(--pn-color-text-muted);
}
.bento__svg { --bd: 0s; position: relative; display: block; overflow: visible; }
.bento__text { flex: 1; padding: var(--pn-space-32); }
/* --bento-title-lines (default 1): reserve this many title lines so captions in one row start level when some titles
   wrap. 1lh = the title's own line-height, so it follows whatever type class the page puts on the title. */
.bento__t { color: var(--pn-color-text-primary); min-height: calc(var(--bento-title-lines, 1) * 1lh); }
.bento__c { margin-top: var(--pn-space-12); font: 400 16px/1.6 var(--pn-font-sans); color: var(--pn-color-text-secondary); text-wrap: pretty; } /* owner 2026-10-10: sans, not mono */

/* ---------- drawing vocabulary ----------
   Faces in surface tones, edges border/control, lit rims text/secondary, accent = the one highlight per drawing.
   The accent uses the fixed brand-green tokens, so the drawings do not follow the page's accent exploration. */
.bento__svg :is(path, ellipse, circle) { fill: none; stroke: var(--pn-color-border-control); stroke-width: 1.25; stroke-linejoin: round; stroke-linecap: round; }
.bento .b-t { fill: var(--pn-color-background-raised); }
.bento .b-l { fill: var(--pn-color-background-surface); }
.bento .b-r { fill: var(--pn-color-background-canvas); }
.bento .b-lit, .bento .b-ln--lit { stroke: var(--pn-color-text-secondary); }
.bento .b-ln { stroke-opacity: 0.7; }
.bento .b-shadow { fill: var(--pn-color-background-canvas); fill-opacity: 0.6; stroke: none; }
.bento [fill^="url"] { stroke: none; }
.bento .b-glow-in { stop-color: var(--pn-color-brand-green); stop-opacity: 0.16; }
.bento .b-glow-out { stop-color: var(--pn-color-brand-green); stop-opacity: 0; }
.bento .b-acc { stroke: var(--pn-color-brand-green); }
.bento .b-acc--w { stroke-width: 1.75; }
.bento .b-acc--fill { fill: var(--pn-color-brand-greenTint); }
.bento .b-acc--top { fill: var(--pn-color-brand-green); }
.bento .b-acc-inset { stroke: var(--pn-color-brand-greenFill); }
.bento .b-scan-glow { stroke: var(--pn-color-brand-greenTint); stroke-width: 6; }
.bento .b-lot { fill: var(--pn-color-background-surface); }
.bento .b-lot-on { fill: var(--pn-color-brand-greenTint); stroke: var(--pn-color-brand-green); stroke-opacity: 0.6; }
.bento .b-fold { fill: var(--pn-color-background-raisedHover); }
.bento .b-paper { fill: var(--pn-color-background-raisedHover); }
.bento .b-box { fill: var(--pn-color-background-surface); }
.bento .b-tick { stroke: var(--pn-color-brand-green); stroke-width: 2.5; stroke-dasharray: 1; stroke-dashoffset: 0; }
.bento .b-road { fill: var(--pn-color-background-surface); stroke: var(--pn-color-border-decorative); }
.bento .b-socket { fill: var(--pn-color-background-canvas); }
.bento .b-dot { fill: var(--pn-color-border-control); stroke: none; }
.bento .b-cable { stroke-width: 5; }
.bento .b-cable-core { stroke: var(--pn-color-background-surface); stroke-width: 2.5; }
.bento .b-pulse { stroke: var(--pn-color-brand-green); stroke-width: 2.5; stroke-dasharray: 0.14 1.3; stroke-dashoffset: -0.45; }

/* ---------- loops: run state ----------
   Page loops are authored `paused` (in the animation shorthand) and start their timing from --bd, a per-cell offset
   so neighbouring drawings never beat together (cells 1..6 below; a seventh cell and on default to 0s).
   js/bento.js adds .is-running while the grid is in view and .is-static under reduced motion. */
.bento__svg--1 { --bd: 0s; }
.bento__svg--2 { --bd: 0.7s; }
.bento__svg--3 { --bd: 1.4s; }
.bento__svg--4 { --bd: 0.35s; }
.bento__svg--5 { --bd: 1.05s; }
.bento__svg--6 { --bd: 1.75s; }
.bento.is-running .bento__svg * { animation-play-state: running; }
.bento.is-static .bento__svg * { animation: none; }
/* !important on purpose: a page stylesheet loads after this file and its loop rules (.bento .xx-b1-lift { animation: ... })
   tie this selector's specificity, so without it reduced motion would lose the cascade whenever JS is off. */
@media (prefers-reduced-motion: reduce) { .bento .bento__svg * { animation: none !important; } }

/* ---- responsive: laptop (2026-11-04) ---- */
/* four columns stay; the 280 x 200 drawings scale down with their cell instead of running past it (1024: 236 cells) */
@media (max-width: 1279px) {
  .bento__svg { max-width: calc(100% - var(--pn-space-32)); height: auto; }
}

/* ---- responsive: tablet (2026-11-04) ---- */
/* two columns (a 280 drawing does not fit a third of a tablet row); the hairline grid holds at any column count */
@media (max-width: 1023px) {
  .bento, .bento--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bento__cell { height: auto; min-height: var(--bento-cell-h, 520px); } /* grows when a caption wraps more; the row stays level */
}

/* ---- responsive: phone (2026-11-04) ---- */
@media (max-width: 767px) {
  .bento, .bento--2, .bento--4 { grid-template-columns: minmax(0, 1fr); }
  .bento__cell { min-height: 0; }
  .bento__text { padding: var(--pn-space-24); }
}
