/* Visual system (BRIEF §0f.3): product media frames, service motifs, icons, logo strip, team portraits.
   One file so the visual vocabulary has one home; components.css keeps layout components. Masters on /styleguide
   (@visuals-masters). Everything here is flex + gap + padding, square corners, 1 px rules, no shadows or gradients. */

/* ================================ Icon (partials/icons/<name>.svg) ================================
   One line set: Lucide (ISC, partials/icons/README.md) redrawn at 24 px, 1.5 stroke, square caps, mitred joins,
   square rects (no radius), currentColor. One icon per feature, step or fact, never filler. The span is the Figma
   component (Icon/<name>); the svg inside is its vector. Colour comes from the parent (ink, or .c-blue). */
.icon { display: inline-flex; flex: none; width: 24px; height: 24px; color: inherit; }
.icon > svg { display: block; width: 100%; height: 100%; }
/* IconBadge: the icon on a 48 px Sky square, for a feature card or a list item that leads with its icon; Roger Blue
   line on Sky = 5.0:1 (tokens.css), so the mark reads at a glance without becoming the card's focal element */
.icon-badge { display: flex; flex: none; align-items: center; justify-content: center; width: 48px; height: 48px;
  background: var(--sky); color: var(--blue); }
.section--sky .icon-badge, .panel--sky .icon-badge { background: var(--paper); }
.section--blue .icon-badge { background: var(--paper); }

/* ================================ Motif (partials/motif-*.html, BRIEF §0f.3, R2-F4) ================================
   Each service has its own geometric, non-letterform symbol, scaled to crop or full fits from the same artwork.
   Square tile, Roger Blue on paper or paper on Roger Blue (or on Sky-2: tone=sky). Decorative: aria-hidden, the
   service name always stays in text beside it. Sizes: fill · xl 128 · l 96 · m 64 · s 48 · xs 32. */
.motif { display: block; flex: none; width: 100%; aspect-ratio: 1 / 1; overflow: hidden; background: var(--paper); color: var(--blue); }
.motif[data-tone="blue"] { background: var(--blue); color: var(--paper); }
/* sky: a visible tile on paper without spending the page's one Roger Blue field (a card thumbnail, a list lead) */
.motif[data-tone="sky"] { background: var(--sky-2); color: var(--blue); }
.motif__svg { display: block; width: 100%; height: 100%; fill: currentColor; }
.motif--xl { width: 128px; } .motif--l { width: 96px; } .motif--m { width: 64px; } .motif--s { width: 48px; } .motif--xs { width: 32px; }

/* ================================ Media: the product media stage + MediaFrame ================================
   .media (partials/media-*.html) = a Sky-2 stage (an opaque object: it covers the page's column lines) holding a
   MediaFrame: a paper window with a 1 px Sky-line border, a 40 px title bar (the Roger mark + the document title,
   doc.* strings) and a content area. The frame starts --mt under the stage top, --mi in from its sides, and runs off
   the stage's bottom edge (Harvey-style crop): it has no bottom border and the stage clips it, always between two
   rows of the drawn UI (site.js · Media crop hides any row the edge would slice, [data-cut] below).
   Attributes on the figure: data-ratio = wide (16:10; 1:1 when the stage is narrower than 600 px, so the product
   still reads on a phone) | square (1:1); data-span = full (the figure spans the whole row between the margin lines:
   from 1024 the frame's edges sit on the 2nd and 6th column lines and the stage draws the column lines in Sky-line,
   the page's grid continuing through it) | part (any narrower span: 48 / 24 / 16 px insets by the stage's width);
   data-variant = detail (a zoomed crop: a document sheet running off the right and bottom edges with the stamp drawn
   up to 2x). The content slots: a product UI (.pui, abstract: skeleton bars + doc.* / stamp.* labels only), a
   screenshot <img class="mframe__media">, or a <video class="mframe__media"> (media-video.html, assets/js/media.js). */
.media { container: media / inline-size; display: flex; flex-direction: column; width: 100%; flex: none; }
/* side by side in a split: each stage keeps half a gutter from the column line between them, so the line runs in the
   gutter instead of two Sky-2 stages fusing into one field */
.media--gut { padding-left: calc(var(--gutter) / 2); padding-right: calc(var(--gutter) / 2); }
.media__stage { --mi: var(--s-48); --mt: var(--s-48);
  position: relative; z-index: 0; display: flex; flex-direction: column; align-items: stretch; width: 100%;
  aspect-ratio: 16 / 10; overflow: hidden; padding: var(--mt) var(--mi) 0; background: var(--sky-2); }
.media[data-ratio="square"] .media__stage { aspect-ratio: 1 / 1; }
.media__lines { display: none; }
.media[data-span="full"] .media__lines { display: block; }
.media__lines .gl { background: var(--sky-line); }
@container media (max-width: 599px) {
  .media__stage { --mi: var(--s-24); --mt: var(--s-24); }
  .media[data-ratio="wide"] .media__stage { aspect-ratio: 1 / 1; }
}
@container media (max-width: 399px) { .media__stage { --mi: var(--s-16); } }
/* full span from 1024: one column (220 px at 1440) of Sky-2 each side, the frame on lines 2 and 6. The right inset is
   1 px short so the frame's right border covers the column line (the line takes the first pixel of the next column,
   layout.css), as its left border covers the other */
@media (min-width: 1024px) {
  .media[data-span="full"] .media__stage { --mi: calc((100cqw + var(--gutter)) / 6 - var(--gutter) / 2); --mt: var(--s-64);
    padding-right: calc(var(--mi) - 1px); }
}

/* the frame takes the stage's height exactly (its content runs on past the foot, clipped by the stage as before): a box
   Figma's FILL sets the same way, where a content-sized frame overran its stage in Chrome only */
.mframe { container: mframe / inline-size; display: flex; flex-direction: column; flex: 1 1 0; min-width: 0; min-height: 0;
  background: var(--paper); color: var(--ink); border: 1px solid var(--sky-line); border-bottom: 0; }
.mframe__bar { display: flex; flex-direction: row; align-items: center; justify-content: space-between; gap: var(--s-16);
  flex: none; height: 40px; padding: 0 var(--s-16); border-bottom: 1px solid var(--rule); }
.mframe__id { display: flex; flex-direction: row; align-items: center; gap: var(--s-12); min-width: 0; }
.mframe__mark { display: block; flex: none; width: 22px; height: 16px; fill: var(--ink); }
.mframe__title { font-family: var(--sans); font-weight: 500; font-size: 14px; line-height: 20px; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; min-width: 0; }
/* the window's own controls, drawn: the revision field and the primary action (a Roger Blue key with a paper bar) */
.mframe__tools { display: flex; flex-direction: row; align-items: center; gap: var(--s-16); flex: none; }
.mframe__rev { display: flex; flex-direction: row; align-items: center; gap: var(--s-8); }
.mframe__act { display: flex; align-items: center; justify-content: center; flex: none; width: 64px; height: 24px; background: var(--blue); }
.mframe__act > span { display: block; width: 32px; height: 4px; background: var(--paper); }
/* a phone-width frame keeps the mark and the whole title: the drawn controls step aside */
@container mframe (max-width: 439px) { .mframe__tools { display: none; } }
.mframe__body { display: flex; flex-direction: column; flex: 1 1 0; min-height: 0; }
/* a screenshot or a video: the frame's full width, top-aligned, cropped by the stage's foot like the drawn UI */
.mframe__media { display: block; width: 100%; height: auto; flex: none; }

/* ---------- product UI (.pui): the abstract Buyout / Submittals screens inside the frame. Real px, so text keeps
   >= 13 px at every size (BRIEF §0e.4); three compositions on the frame's own width: wide >= 720 (Buyout adds its
   section sidebar), mid 440-719, compact < 440 (no head stamp, two cover-sheet fields, the log's key columns). */
.pui { display: flex; flex-direction: row; align-items: stretch; flex: 1 1 0; min-height: 0; width: 100%; }   /* the body's height (see .mframe) */
.pui__side { display: none; flex-direction: column; gap: var(--s-16); flex: 0 0 200px; padding: var(--s-24) var(--s-16);
  background: var(--paper-2); border-right: 1px solid var(--rule); }
@container mframe (min-width: 720px) { .pui__side { display: flex; } }
.pui__nav { display: flex; flex-direction: column; gap: var(--s-4); }
.pui__nav-i { flex-direction: row; align-items: center; gap: var(--s-12); height: 32px; padding: 0 var(--s-8); }
.pui__nav-i--on { background: var(--sky); }
.pui__sq { display: block; flex: none; width: 8px; height: 8px; border: 1px solid var(--rule-2); }
.pui__sq--done { background: var(--blue); border-color: var(--blue); }
.pui__doc { display: flex; flex-direction: column; gap: var(--s-24); flex: 1 1 0; min-width: 0; padding: var(--s-32); }
.pui__head { display: flex; flex-direction: row; align-items: flex-start; justify-content: space-between; gap: var(--s-24); }
.pui__tb { display: flex; flex-direction: column; gap: var(--s-8); min-width: 0; }
.pui__kind { font-family: var(--narrow); font-weight: 600; font-size: 13px; line-height: 16px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--ink-3); }
.pui__nw { white-space: nowrap; }
.pui__title { font-family: var(--serif); font-weight: 600; font-size: 28px; line-height: 32px; letter-spacing: -0.01em; }
.pui__lab { font-family: var(--narrow); font-weight: 600; font-size: 13px; line-height: 16px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink-3); white-space: nowrap; }
/* the head's left column: the title block, then the cover-sheet fields two a row, so the column stands as tall as
   the stamp beside it (no empty slab under a short title) */
.pui__lead { display: flex; flex-direction: column; gap: var(--s-24); flex: 1 1 0; min-width: 0; }
.pui__fields { display: flex; flex-direction: row; flex-wrap: wrap; gap: var(--s-16) var(--s-24); padding-top: var(--s-16);
  border-top: 1px solid var(--rule); }
.pui__f { display: flex; flex-direction: column; gap: var(--s-8); flex: 1 1 calc(50% - var(--s-24)); min-width: 0; }
/* skeleton text: paper-3 bars stand for words; a Sky-line bar is a heading */
.pui__bar { display: block; flex: none; height: 8px; background: var(--paper-3); }
.pui__bar--h { height: 12px; background: var(--sky-line); }
.pui__bar--fill { flex: 1 1 0; min-width: 0; }
.pui__bar--20 { width: 20%; } .pui__bar--35 { width: 35%; } .pui__bar--50 { width: 50%; } .pui__bar--65 { width: 65%; }
.pui__bar--80 { width: 80%; } .pui__bar--100 { width: 100%; }
.pui__bar--ref { width: 40px; }
.pui__group { display: flex; flex-direction: column; gap: var(--s-8); }
.pui__gh { display: flex; flex-direction: row; align-items: center; gap: var(--s-12); height: 24px; }
.pui__rows { display: flex; flex-direction: column; }
/* a scope line: its tick (included: Roger Blue check; excluded: ink-3 cross), the line, its spec reference */
.pui__row { flex-direction: row; align-items: center; gap: var(--s-12); height: 36px; padding: 0 var(--s-8); }
.pui__row > .pui__span { display: flex; flex: 1 1 0; min-width: 0; }
.pui__row--on { background: var(--sky); border-left: 2px solid var(--blue); padding-left: 6px; }
/* the line being edited (the Supercharged Document Editor): its words in Sky-line on the Sky row, the caret after them */
:is(.pui__row--on, .pui__lr--on, .pui__nav-i--on) .pui__bar { background: var(--sky-line); }
.pui__row > .pui__span { align-items: center; gap: var(--s-4); }
.pui__caret { display: block; flex: none; width: 2px; height: 16px; background: var(--blue); }
.pui .icon { width: 16px; height: 16px; }
.pui .icon > svg { stroke-width: 2; }
.pui__in, .pui__out { display: flex; flex: none; }
.pui__in { color: var(--blue); }
.pui__out { color: var(--ink-3); }
/* compact (a phone's square): the head stamp steps out. Under the title it was a 206 px block that pushed the cover
   sheet and every line out of the crop, so the phone showed a stamp, not the product; the page's hero and warranty
   carry the stamps. The square shows the title, the first two cover-sheet fields and the document's lines instead. */
@container mframe (max-width: 439px) {
  .pui__doc { gap: var(--s-16); padding: var(--s-16); }
  .pui__head { flex-direction: column; align-items: stretch; gap: var(--s-16); }
  .pui__stamp { display: none; }
  .pui__lead { gap: var(--s-16); }
  .pui__f:nth-child(n+3) { display: none; }
  .pui__title { font-size: 24px; line-height: 28px; }
  .pui__row { height: 32px; }
}
/* the crop's foot falls between rows: a drawn unit whose ink crosses the stage's edge is hidden (site.js · Media
   crop), never sliced. visibility keeps every other row where it was */
.media [data-cut] { visibility: hidden; }

/* the stamps inside the product: the document-stamp family (components.css .dstamp) in its compact form, drawn in
   --px so the Detail variant can zoom the same drawing. Both are 192 wide and 144 tall inside their rule (header 32 +
   signed 80 + band 32 = header 32 + four dispositions 4 x 24 + 2 x 8), so the two products' heads line up */
.pui .dstamp { --px: 1px; }
.pui__stamp .dstamp__in { width: calc(192 * var(--px)); }
/* Give the recommendation checkbox and label more room to the left, keeping the right edge fixed. */
.pui--submittals .pui__stamp .dstamp__in,
.msheet .pui__stamp .dstamp__in { width: calc(256 * var(--px)); }
.pui__stamp .dstamp__lab, .pui__stamp .dstamp__opt-l { letter-spacing: 0.08em; }
.pui__stamp .dstamp__opt-l--on { letter-spacing: 0.04em; }
.pui__sign { display: flex; flex-direction: column; justify-content: flex-end; gap: calc(8 * var(--px)); height: calc(80 * var(--px));
  padding: 0 calc(12 * var(--px)) calc(16 * var(--px)); }
.pui__ink { display: block; flex: none; width: 56%; height: calc(4 * var(--px)); background: var(--blue); }
.pui__stamp .dstamp__list { gap: 0; padding: calc(8 * var(--px)) 0; border-bottom: 0; }
.pui__stamp .dstamp__opt { gap: calc(8 * var(--px)); min-height: calc(24 * var(--px)); padding: calc(4 * var(--px)) calc(12 * var(--px)); }
.pui__opt-on { background: var(--sky); }

/* the submittal log: a table drawn in rows (rules carry meaning in a table, BRIEF §0e.5) */
.pui__log { display: flex; flex-direction: column; }
.pui__lr { display: flex; flex-direction: row; align-items: center; gap: var(--s-16); height: 40px; padding: 0 var(--s-8);
  border-bottom: 1px solid var(--rule); }
.pui__lr--head { height: 32px; border-bottom-color: var(--rule-2); }
.pui__lr--on { background: var(--sky); border-left: 2px solid var(--blue); padding-left: 6px; }
.pui__c { display: flex; flex-direction: row; align-items: center; min-width: 0; }
.pui__c--no { flex: 0 0 40px; } .pui__c--spec { flex: 0 0 112px; } .pui__c--title { flex: 1 1 0; } .pui__c--act { flex: 0 0 248px; }
.pui__st { display: flex; flex-direction: row; align-items: center; gap: var(--s-8); min-width: 0; max-width: 100%; }
.pui__box { display: block; flex: none; width: 12px; height: 12px; background: var(--blue); }
.pui__box--return { background: var(--ink-3); }
.pui__st-l { font-family: var(--narrow); font-weight: 600; font-size: 13px; line-height: 16px; letter-spacing: 0.06em;
  text-transform: uppercase; white-space: nowrap; }
/* narrower logs keep their key columns: the spec section steps out below 640, the action's words below 440 (its
   square stays: there is no room for the words beside the title bars on a phone, and the figure's label names it) */
@container mframe (max-width: 639px) { .pui__c--spec { display: none; } }
@container mframe (max-width: 439px) { .pui__st-l { display: none; } .pui__c--act { flex: 0 0 auto; } }
/* the phone log: 8 px between its columns, and the cover sheet's field row steps out, so the crop shows the log's
   head and its first rows (finding 11: the phone crop showed the head alone); in the narrowest frame (248 px at 320)
   the No. column steps out too, so the "Submittal title" header keeps its own column instead of running into "Action" */
@container mframe (max-width: 439px) { .pui__lr { gap: var(--s-8); } .pui--submittals .pui__fields { display: none; } }
@container mframe (max-width: 279px) { .pui__c--no { display: none; } }

/* ---------- Detail: a zoomed crop. The sheet starts --mt / --mi in from the stage's top-left and runs off its right
   and bottom edges; inside, the document's heading bar, its stamp drawn at --z (up to 2x, keeping air before the
   edge), then the document's lines, which run off the crop ---------- */
.media[data-variant="detail"] .media__stage { padding: var(--mt) 0 0 var(--mi); }
.msheet { --z: clamp(1px, calc((100cqw - 56px) / 226), 2px);
  display: flex; flex-direction: column; align-items: flex-start; gap: calc(24 * var(--z)); flex: 1 1 0; min-width: 0; min-height: 0;
  padding: calc(24 * var(--z)); background: var(--paper); color: var(--ink); border: 1px solid var(--sky-line); border-right: 0; border-bottom: 0; }
.msheet .dstamp { --px: var(--z); }
.msheet__lines { display: flex; flex-direction: column; gap: calc(12 * var(--z)); width: 140%; }
.msheet__lines > .pui__bar { height: calc(8 * var(--z)); }
.msheet__head { width: 45%; height: calc(12 * var(--z)); }

/* ---------- video slot: the poster until site motion is allowed; then it plays while on screen, and the toggle (44 x
   44, on the stage's foot corner) pauses it. No autoplay attribute, so a visitor who asks for reduced motion (or has
   no JS) only ever sees the poster (assets/js/media.js) ---------- */
.media__toggle { position: absolute; right: var(--s-16); bottom: var(--s-16); z-index: 1; display: flex; align-items: center;
  justify-content: center; width: var(--tap); height: var(--tap); background: var(--paper); color: var(--ink);
  border: 1px solid var(--sky-line); transition: background-color var(--dur-hover) var(--ease-out); }
@media (hover: hover) { .media__toggle:hover { background: var(--sky); } }
.media__toggle .icon:last-child, .media__toggle[aria-pressed="true"] .icon:first-child { display: none; }
.media__toggle[aria-pressed="true"] .icon:last-child { display: inline-flex; }

/* ---------- hover inside a card (BRIEF §0f.4: "media image scale 1.02 inside its frame"): a drawn product UI grows
   2 % from its top edge, clipped by the stage, so the window itself never moves. A screenshot or video (an img /
   video in the frame) takes the card's own media zoom (components.css .card), so it is never scaled twice ---------- */
.mframe__body:has(> .pui) { transform-origin: 50% 0; transition: scale var(--dur-exit) var(--ease-in); }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  :is(.card, .insight-hit):hover .mframe__body:has(> .pui) { scale: 1.02; transition: scale var(--dur-enter) var(--ease-out); }
}
@media (prefers-reduced-motion: reduce) { .mframe__body, .media__toggle { transition: none; } .mframe__body { scale: none !important; } }

/* ================================ Mini mock (partials/mini-*.html, Oct 8) ================================
   The ServiceTile's visual block: the MediaFrame above at card scale, much simpler (Tidjane: "as in the top one but
   much simpler and smaller"). A Sky-2 stage, the frame inset --mi on three sides and running off the stage's foot
   (no bottom border, the stage clips it: the Harvey crop of the full stage), its title bar (R> mark + document
   title, .mframe__bar) and one small composition that is NOT the stage's: Buyout the signed cover sheet (three
   fields beside the Deliverable stamp), Submittals a three-line log with disposition chips, the middle one ticked.
   Real px only (1 px rules, 8 px bars, whole-pixel insets), so it stays crisp at any width, and no text under 13 px
   (BRIEF §0e.4). The stage's height is fixed (inset + bar + body) so two tiles' text always starts on one line,
   whatever each mock draws: the body is 176 (the cover sheet's 128 stamp or three 48 px log lines under a 24 inset)
   and 136 for a compact frame (a phone's tile, a tablet 2-up, the 1024-1279 3+3, the menu's cards), so a stacked
   tile is a card, not a screen of mock UI (Oct 8 critique: 1,056 px for two tiles at 375).
   Two compositions on the frame's own width (the mframe container): compact below 440 px (the cover-sheet fields
   step out below 400 and the stamp stands alone; the log drops its numbers and keeps all three chip words) and the
   full one above. Hover (BRIEF §0f.4): inside a hovered card the body grows 1.02 from its top edge, clipped by the
   stage, as the full stage's product UI does. */
.mini { --px: 1px; container: mini / inline-size; display: flex; flex-direction: column; width: 100%; flex: none; }
.mini__stage { --mi: var(--s-48); --mb: 176px; display: flex; flex-direction: column; align-items: stretch; width: 100%;
  height: calc(var(--mi) + 40px + var(--mb)); overflow: hidden; padding: var(--mi) var(--mi) 0; background: var(--sky-2); }
@container mini (max-width: 559px) { .mini__stage { --mi: var(--s-32); } }
/* the compact frame (below 440, i.e. a mini under 504 with its 32 insets) draws the compact composition, so its body
   is the short one: no empty sheet under three log lines or a lone stamp */
@container mini (max-width: 503px) { .mini__stage { --mb: 136px; } }
@container mini (max-width: 399px) { .mini__stage { --mi: var(--s-24); } }
@container mini (max-width: 319px) { .mini__stage { --mi: var(--s-16); } }   /* a 320 phone: the whole title still fits */
.mini__body { align-items: flex-start; gap: var(--s-16); padding: var(--s-24); }
.mini__rows, .mini__log { display: flex; flex-direction: column; align-self: stretch; }
.mini__span { display: flex; flex: 1 1 0; min-width: 0; }
/* Buyout: the cover sheet, its fields (label over a value bar, as the stage's .pui__f) beside the signed Deliverable
   stamp; the three fields stand exactly as tall as the stamp (3 x 32 + 2 x 16 = 128 = 2 + 5 + 1 + 32 + 80 + 1 + 5 + 2).
   Compact, the stamp alone signs on a 56 px field: 16 + 104 leaves a 16 px sheet under it in the short 136 body */
.mini__sheet { display: flex; flex-direction: row; align-items: flex-start; gap: var(--s-24); align-self: stretch; }
.mini__fields { display: flex; flex-direction: column; gap: var(--s-16); flex: 1 1 0; min-width: 0; }
.mini__fields > .pui__f { flex: none; }
.mini__stamp .dstamp__in { width: calc(192 * var(--px)); max-width: 100%; }
/* the stamp may shrink with its sheet (never past the frame's edge: a 320 phone's or a 1024-1100 /hire-roger sent
   card's frame is narrower than the 192 px stamp plus the body's inset) */
.mini__sheet > .mini__stamp { flex: 0 1 auto; min-width: 0; }
.mini__stamp .dstamp__lab { letter-spacing: 0.08em; }
/* Submittals: a log line = its number, its title, its disposition chip (the review stamp's box + word, stamp blue).
   The chips share one column, so the three boxes line up under each other */
.mini__lr { flex-direction: row; align-items: center; gap: var(--s-12); height: 48px; padding: 0 var(--s-8);
  border-bottom: 1px solid var(--rule); }
.mini__lr--on { background: var(--sky); border-left: 2px solid var(--blue); padding-left: 6px; }
.mini__lr--on .pui__bar { background: var(--sky-line); }
.mini__no { width: 24px; }
.mini__st { display: flex; flex-direction: row; align-items: center; gap: var(--s-8); flex: 0 0 248px; color: var(--blue); }
.mini__st-l { font-family: var(--narrow); font-weight: 600; font-size: 13px; line-height: 16px; letter-spacing: 0.06em;
  text-transform: uppercase; white-space: nowrap; }
.mini__st-l--on { font-weight: 700; letter-spacing: 0.04em; }
/* compact (a phone's card, a tablet 2-up, the 1024-1279 3+3, the menu's cards): 16 px body, 40 px log lines (16 + 3 x
   40 = the short 136 body exactly), the number steps out and the chip column keeps the recommendation on one line, so every
   chip keeps its word and the title bar gives way; the stamp signs on a shorter field (its line 56 under the head) */
@container mframe (max-width: 439px) {
  .mini__body { padding: var(--s-16); }
  .mini__lr { gap: var(--s-8); height: 40px; }
  .mini__no { display: none; }
  .mini__st { flex-basis: 228px; }
  .mini__st-l, .mini__st-l--on { letter-spacing: 0.02em; }
  .mini__sign { height: calc(56 * var(--px)); }
}
@container mframe (max-width: 399px) { .mini__fields { display: none; } }
/* In narrow frames, omit the decorative title bars so the checkbox and complete disposition still fit on one line. */
@container mframe (max-width: 319px) {
  .mini__log .mini__span { display: none; }
  .mini__log .mini__lr { padding-left: 0; padding-right: 0; }
  .mini__st { flex: 1 1 0; min-width: 0; }
}
@container mframe (max-width: 259px) {
  .mini__t2 { display: none; }   /* Buyout: "Buyout package"; Submittals: "Submittals", never an ellipsis */
}
.mini__body { transform-origin: 50% 0; transition: scale var(--dur-exit) var(--ease-in); }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .card:hover .mini__body { scale: 1.02; transition: scale var(--dur-enter) var(--ease-out); }
}
@media (prefers-reduced-motion: reduce) { .mini__body { transition: none; scale: none !important; } }

/* ================================ LogoStrip (partials/logo-strip.html, D-25) ================================
   A row of customer marks in one grey ink, from src/site.json "logos" (files in assets/img/logos/). Renders nothing
   while the list is empty: no placeholder ever ships (the [GC logo] tokens live on /styleguide only). Marks are set
   to one height (32 px) and greyed, so no customer's colours outshout another's or the page's one blue. */
.logos { display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; gap: var(--s-24) var(--s-48); width: 100%; }
.logos__item { flex-direction: row; align-items: center; height: 48px; }
.logos__img { display: block; width: auto; height: 32px; max-width: 160px; object-fit: contain; filter: grayscale(1); opacity: 0.72; }
/* the styleguide's token tile: the slot a mark fills, its size drawn as a paper-2 plate */
.logos__token { display: flex; align-items: center; justify-content: center; width: 160px; height: 48px; background: var(--paper-2); color: var(--ink-3); }
@media (max-width: 767px) { .logos { gap: var(--s-16) var(--s-32); } .logos__token { width: 128px; } }

/* /styleguide only: a motif's construction drawing (the 12 x 12 module grid, the letter cut by the tile foot) */
.sg-construct { display: block; width: 100%; height: auto; }

/* ================================ Portrait (team, WSJ-style stipple) ================================
   Owner: portrait pipeline. One unified treatment for every team member: a pen-and-ink stipple drawing on paper (dots
   on the skin and clothing, inked features, hair in strokes), square, head and shoulders, eye line at 40 %, the same
   head size and tone, made from any clear headshot by tools/portrait/batch.sh into
   assets/img/team/<first-last>.webp (392 px master) + .png (two-colour fallback, Figma import) + <first-last>-<px>.webp,
   all 1-bit (every pixel --ink or --paper). Measured on the built /about, the tile is 195.94 CSS px at 1440+, 126.61 at
   1024, 153.94 at 768, 159.44 at 375; each file is drawn at the device width of one of them (196 x DPR 2 = 392, 318 =
   375 x2, ...) with one dot = one CSS px (2 x 2 device px at DPR 2, big enough to see), never resampled, so the
   srcset hands the browser a file it paints 1:1 and every dot stays a crisp point.
   1:1 also needs a whole-pixel box: Chrome snaps the image to whole CSS px before it paints (159.44 becomes 159 or 160
   depending on the column), so the box is rounded here and the file matches the rounded box; the overshoot (under
   0.5 px) is clipped by the square, whose ground is the same paper. Browsers without round() keep 100 % and a smooth
   resample. No image-rendering override: nearest-neighbour would alias the grain where a width falls between files.
   The dots are drawn on a --paper ground, so the slot paints --paper while it loads and the square never flashes Sky.
   The <picture> mirrors the library photos (WebP source, PNG img). No motion: a portrait is not a control. */
.portrait { display: block; flex: none; width: 100%; aspect-ratio: 1 / 1; overflow: hidden; background: var(--paper); }
.portrait__img { display: block; width: 100%; height: 100%; max-width: none; object-fit: cover; }
.portrait__img { width: round(nearest, 100%, 1px); height: round(nearest, 100%, 1px); }
/* TeamGrid/Member: with a portrait the tile grows from the 64 px monogram chip to the card's full inner width. Stipple
   needs well over 100 px to read as a drawing rather than a grey thumbnail; every card keeps one structure (tile, name,
   role) and a member without a photo keeps the monogram chip. Two classes, so it wins over the chip size at any width. */
.team__tile.team__tile--portrait { align-self: stretch; width: auto; height: auto; aspect-ratio: 1 / 1; background: var(--paper); }
