/* Insights track: /insights, /insights/ai-is-going-to-run-these-jobs, /future-of-the-project-manager (BRIEF §0f).
   Composition on the six columns: the column lines (partials/bays.html) are the backdrop of every section; text sits
   --cell-pad in from the line it starts at; photos, cards, the sheets and panels are opaque objects with their edges on
   the lines. Splits vary (index: masthead 2+4 → Featured 3+3 → list in 2+4 rows or 2+2+2; article: photo beside sheet 1
   (2+4) → full-width Photo strip (3+3) → sheet 2 (on 3-6) → Related as a 2+4 wide row). The cards are layout.css · Cols
   (cards mode) + components.css · Card. Type comes from the .t-* roles and their fluid tokens only; every box is
   flex + gap + padding (BRIEF §5). Motion is off under prefers-reduced-motion. */

/* =============================== /insights =============================== */

/* Masthead (Hero · Page), one row from 1024: band + "Insights" + Hire Roger (32 under the word) on columns 1-2, the
   TagFilter on columns 3-6 on the row's foot, its bar beside Hire Roger (both 48 tall: the two controls share top and
   foot), so the filter heads the feed it acts on, one gutter above the Featured card (Oct 8 round 3: set on the word's
   baseline it floated mid-height, with 868 x 113 px of paper above it and 868 x 152 below). The row is as tall as its
   words and the controls (R2-F10). Below 1024 the stack: word, Hire Roger, then the filter on the full row. */
.ins-mast { padding-bottom: var(--gutter); }
.ins-mast__text { gap: var(--s-32); padding-top: 0; padding-bottom: 0; }
.ins-mast__filter { justify-content: flex-end; }
@media (max-width: 1023px) {
  .ins-mast { padding-bottom: var(--s-32); }
  .ins-mast__text { padding-top: var(--s-48); }
  .ins-mast__filter { padding-top: var(--s-32); }
}
@media (max-width: 767px) {
  .ins-mast { padding-bottom: var(--s-24); }
  .ins-mast__text { gap: var(--s-24); padding-top: var(--s-32); }
  .ins-mast__filter { padding-top: var(--s-24); }
}

/* TagFilter: one segmented bar, an opaque control the lines pass behind. Each tag is one column wide and the 2 px gaps
   (the bar's paper-3 showing through) are centred on the column lines, so the lines run into the bar in register:
   --col is the column pitch in the bar's own width (desktop: the bar starts on line 4 of 12, so a column is
   25% + gutter/8 of it; tablet: the bar is the full row, four columns of (100% + gutter) / 4, the first half a gutter
   narrower); the first tag stops 1 px short of its line, the middle ones 2 px, the last fills to the margin line.
   Phones: 2 x 2, split on the centre line. */
/* with JS the filter shows from the first paint (site.js unhides it once wired): revealed late, it pushed the feed
   down 98 px on phones after load (CLS 0.08); without JS it stays hidden and everything shows */
.js .ins-filter[hidden] { display: flex !important; }
.ins-filter { display: flex; flex-direction: row; flex-wrap: wrap; gap: 2px; width: 100%; background: var(--paper-3); }
.ins-filter > .tag { flex: 1 1 0; min-width: 0; justify-content: center; min-height: var(--control-h); padding: 0 var(--s-8); white-space: nowrap; }
@media (min-width: 1024px) {
  .ins-filter { --col: calc(25% + var(--gutter) / 8); }
  .ins-filter > .tag { flex: 0 0 calc(var(--col) - 2px); }
  .ins-filter > .tag:first-child { flex-basis: calc(var(--col) - 1px); }
  .ins-filter > .tag:last-child { flex: 1 1 0; }
}
@media (min-width: 768px) and (max-width: 1023px) {
  .ins-filter { --col: calc((100% + var(--gutter)) / 4); }
  .ins-filter > .tag { flex: 0 0 calc(var(--col) - 2px); }
  .ins-filter > .tag:first-child { flex-basis: calc(var(--col) - var(--gutter) / 2 - 1px); }
  .ins-filter > .tag:last-child { flex: 1 1 0; }
}
/* phones: the odd tags stop 1 px short of the centre line, the even ones fill (bases sum under 100 %, so a row never
   wraps early). Under 340 a half is too narrow for "Announcement" to keep 16 px from the margin line (C6: 111 px of
   label in a 139 px half at 320), so the tags stack one per row across the full width, still in register: the bar
   covers the centre line and the labels sit far from both margin lines. */
@media (max-width: 767px) {
  .ins-filter > .tag { flex: 1 1 calc(50% - 2px); padding: 0 var(--s-12); }
  .ins-filter > .tag:nth-child(odd) { flex: 0 0 calc(50% - 1px); }
}
@media (max-width: 339px) { .ins-filter > .tag, .ins-filter > .tag:nth-child(odd) { flex: 0 0 100%; } }

/* Feed: Featured, the list and the empty slot, one gutter apart, so the cards read as one grid */
.ins-feed { display: flex; flex-direction: column; align-items: stretch; gap: var(--gutter); width: 100%; }

/* Card meta row (R2-F12: one row): labels side by side, a 4 px square between them (drawn, not a character), so each
   label stays its own string */
.card__meta { display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; gap: var(--s-12); }
.card__sep { display: block; flex: none; width: 4px; height: 4px; background: var(--ink-3); }

/* InsightCard · Featured: one Sky card from margin line to margin line. Desktop: the square photo fills columns 1-3
   (its right edge on the centre line: 50 % of the card's inner box), the text columns 4-6: head and Read more grouped
   32 apart and centred on the square's height, so the air above and below splits evenly (no hole in the middle).
   Below 1024 the square runs full width over the text. */
.ins-feature { --card-bg: var(--sky); }
.ins-feature__head { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s-16); }
.ins-feature__head > h2 { font-size: clamp(26px, 2.25vw, 32px); line-height: 1.18; letter-spacing: -0.012em; }
.ins-feature__x { max-width: 560px; }
.ins-feature__body { gap: var(--s-32); }
@media (min-width: 1024px) {
  .ins-feature { flex-direction: row; }
  .ins-feature__media { flex: 0 0 50%; }
  .ins-feature__body { flex: 1 1 0; min-width: 0; justify-content: center; padding: var(--s-48) var(--cell-pad); }
  .ins-feature__body > .card__foot { flex: none; }
  .ins-feature__head { gap: var(--s-24); }
}
/* the narrow desktop (1024-1279): a 32 inset and tighter gaps keep the text within the square's height, so the photo
   always closes the card top to bottom (a Sky strip under the photo would read as an error) */
@media (min-width: 1024px) and (max-width: 1279px) {
  .ins-feature__body { gap: var(--s-24); padding-top: var(--s-32); padding-bottom: var(--s-32); }
  .ins-feature__head { gap: var(--s-16); }
}
@media (min-width: 768px) and (max-width: 1023px) { .ins-feature__body { padding-top: var(--s-32); padding-bottom: var(--s-32); } }

/* InsightCard · Row (the list's Card): meta, title, excerpt in one head block, Read more under it */
.ins-card__head { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s-12); }
.ins-card__x { max-width: 560px; }

/* List: any number of cards, newest first. Three or more showing = 2+2+2 on desktop (layout.css · Cols, cards mode),
   2-up on tablet, 1-up on phones. With fewer cards than a row holds, a card never sits beside empty columns: it turns
   into a wide row (desktop: one or two cards, tablet: one): the square on columns 1-2 (tablet 1 of 2), the text on the
   rest, the title at H2 and the excerpt at Lead, head + Read more grouped 32 apart and centred on the square's height.
   Counts are of VISIBLE cards, so a tag filter switches the mode too. */
@media (min-width: 1024px) {
  .ins-list.ins-list:not(:has(> :nth-child(3 of :not([hidden])))) > * { flex: 0 0 100%; padding: 0; }
  .ins-list:not(:has(> :nth-child(3 of :not([hidden])))) .card { flex-direction: row; }
  /* 2 of 6 columns of the card's outer width (its 1 px edge on either side): the square's right edge on line 4 of 12 */
  .ins-list:not(:has(> :nth-child(3 of :not([hidden])))) .card__media { flex: 0 0 calc((100% + 2px + var(--gutter)) / 3 - var(--gutter) / 2 - 1px); }
  .ins-list:not(:has(> :nth-child(3 of :not([hidden])))) .card__body { flex: 1 1 0; min-width: 0; justify-content: center; gap: var(--s-32); padding: var(--s-48) var(--cell-pad); }
  .ins-list:not(:has(> :nth-child(3 of :not([hidden])))) .card__foot { flex: none; }
  .ins-list:not(:has(> :nth-child(3 of :not([hidden])))) .ins-card__head { gap: var(--s-16); }
  .ins-list:not(:has(> :nth-child(3 of :not([hidden])))) .ins-card__t {
    font-size: clamp(28px, 2.2vw, 32px); line-height: 1.16; letter-spacing: -0.012em;
  }
  .ins-list:not(:has(> :nth-child(3 of :not([hidden])))) .ins-card__x { font-size: var(--lead-fs); line-height: var(--lead-lh); letter-spacing: -0.005em; }
}
/* as the Featured card: on the narrow desktop the wide row's text keeps within its square (32 inset, 24 apart) */
@media (min-width: 1024px) and (max-width: 1279px) {
  .ins-list:not(:has(> :nth-child(3 of :not([hidden])))) .card__body { gap: var(--s-24); padding-top: var(--s-32); padding-bottom: var(--s-32); }
}
@media (min-width: 768px) and (max-width: 1023px) {
  .ins-list.ins-list:not(:has(> :nth-child(2 of :not([hidden])))) > * { flex: 0 0 100%; padding: 0; }
  .ins-list:not(:has(> :nth-child(2 of :not([hidden])))) .card { flex-direction: row; }
  .ins-list:not(:has(> :nth-child(2 of :not([hidden])))) .card__media { flex: 0 0 calc((100% + 2px + var(--gutter)) / 2 - var(--gutter) / 2 - 1px); }
  .ins-list:not(:has(> :nth-child(2 of :not([hidden])))) .card__body { flex: 1 1 0; min-width: 0; justify-content: center; gap: var(--s-32); }
  .ins-list:not(:has(> :nth-child(2 of :not([hidden])))) .card__foot { flex: none; }
}
/* a list with no card showing (Announcement: the Featured card is the announcement) takes no room */
.ins-list:not(:has(> :not([hidden]))) { display: none; }

/* Empty result (Case study): the list's own slot in the wide-row shape, so it reads as a designed state, not a void:
   a decorative 1:1 library photo (an empty floor before fit-out; aria-hidden, its manifest alt is never announced, so
   no words are added) on columns 1-2 (tablet 1 of 2) and a Sky-2 field on the rest holding the band and the line on
   its inset, centred on the square's height. Phones: the square over the line. Its height matches the old 3:1 / 2:1
   / 1:1 slab, so the closing band's Hire Roger stays out of the first screen beside the masthead's (F9). */
.ins-empty { display: flex; flex-direction: column; align-items: stretch; width: 100%; }
.ins-empty__media { width: 100%; overflow: hidden; background: var(--paper-3); }
.ins-empty__panel { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: var(--s-24);
  flex: 1 1 auto; min-width: 0; padding: var(--s-32) var(--cell-pad); background: var(--sky-2); }
@media (min-width: 768px) { .ins-empty { flex-direction: row; } }
@media (min-width: 768px) and (max-width: 1023px) { .ins-empty__media { flex: 0 0 calc((100% + var(--gutter)) / 2 - var(--gutter) / 2); } }
@media (min-width: 1024px) { .ins-empty__media { flex: 0 0 calc((100% + var(--gutter)) / 3 - var(--gutter) / 2); } }
@media (max-width: 767px) { .ins-empty__panel { padding-top: var(--s-24); padding-bottom: var(--s-24); } }

/* Filter motion (BRIEF §0f.4): when a tag is pressed site.js sets the feed's data-filter; each value names its own
   (identical) animation, so every press replays the entrance on whatever shows: the cards rise 16 px and unroll from
   the top (clip-path from the foot) on the enter curve, 60 ms apart in reading order, while the hidden ones leave at
   once (no exit animation on a high-frequency control). Opaque cards never go semi-transparent, so the column lines
   never show through them mid-entrance. Fill is backwards only: once played, no clip-path is left on the card (it
   would cut the title link's 2 px focus ring). Nothing animates at load (no data-filter yet) or under reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  .ins-feed[data-filter] :is([data-tags], .ins-empty):not([hidden]) {
    animation-duration: var(--dur-enter); animation-timing-function: var(--ease-out); animation-fill-mode: backwards; }
  .ins-feed[data-filter="all"] :is([data-tags], .ins-empty):not([hidden]) { animation-name: ins-in-all; }
  .ins-feed[data-filter="announcement"] :is([data-tags], .ins-empty):not([hidden]) { animation-name: ins-in-announcement; }
  .ins-feed[data-filter="case-study"] :is([data-tags], .ins-empty):not([hidden]) { animation-name: ins-in-case-study; }
  .ins-feed[data-filter="vision"] :is([data-tags], .ins-empty):not([hidden]) { animation-name: ins-in-vision; }
  .ins-feed[data-filter] .ins-list > :nth-child(1 of :not([hidden])) { animation-delay: var(--stagger); }
  .ins-feed[data-filter] .ins-list > :nth-child(2 of :not([hidden])) { animation-delay: calc(2 * var(--stagger)); }
  .ins-feed[data-filter] .ins-list > :nth-child(3 of :not([hidden])) { animation-delay: calc(3 * var(--stagger)); }
  .ins-feed[data-filter] .ins-list > :nth-child(n+4 of :not([hidden])) { animation-delay: calc(4 * var(--stagger)); }
}
@keyframes ins-in-all { from { clip-path: inset(0 0 100% 0); translate: 0 var(--reveal-rise); } to { clip-path: inset(0); translate: none; } }
@keyframes ins-in-announcement { from { clip-path: inset(0 0 100% 0); translate: 0 var(--reveal-rise); } to { clip-path: inset(0); translate: none; } }
@keyframes ins-in-case-study { from { clip-path: inset(0 0 100% 0); translate: 0 var(--reveal-rise); } to { clip-path: inset(0); translate: none; } }
@keyframes ins-in-vision { from { clip-path: inset(0 0 100% 0); translate: 0 var(--reveal-rise); } to { clip-path: inset(0); translate: none; } }

/* =============================== articles =============================== */

/* Desktop (Oct 8 visual pass: columns 1-2 stood empty beside 1,800 px of read): the read is a run of PASSAGES, each a
   2+4 row: a rail figure on columns 1-2 and its part of the sheet on columns 3-6. The sheets abut, so the paper-2
   document reads as one; each figure sits beside the words it shows (the opening photo, the belief bars beside the
   80 % / 68 % sentence, a photo beside the construction-project analogy, the product's signed deliverable beside
   "Roger signs", its review stamp beside "a closed submittal", a photo beside the history), then the Photo strip
   (3+3, full width) as the pause, sheet 2 with its own rail figure, Related (2+4 wide row). From 1024 the first
   passage sits 48 under the header rule (.row--plate). Below 1024 one column: the rail figures that carry content
   (the bars, the product crops) move into the sheet's flow (hide-d copies), the rail photos rest, so a phone read
   keeps its pace: title block, square photo, body with its figures, strip, sheet 2, Related. */
.ins-art > .container { padding-bottom: 0; }
@media (max-width: 1023px) { .ins-art > .container { padding-top: var(--s-32); } }
@media (max-width: 767px) { .ins-art > .container { padding-top: var(--s-24); } }
.ins-flow { display: flex; flex-direction: column; align-items: stretch; width: 100%; }

/* Side (columns 1-2, desktop only): the passage's figure, edges on the margin line and line 4 of 12, then the progress
   rail. It lives in its passage's row, so it releases at the passage's foot and the next figure takes over: figure +
   rail are pinned 48 under the header and travel with the words they show wherever the window holds them. The tallest
   pinned stack is about 590 px (80 header + 48 + a 428 square + the 30 px rail at 1440), so the pin works from a 620 px
   window (Oct 8 round 3: at 760 the 1280 x 800 and 1366 x 768 laptops, 650-700 px of viewport, lost their figures
   beside the words). Only in a shorter window the figure stays put and the rail alone travels (the pin fills the cell
   so the rail has room to stick), so columns 1-2 always carry a figure or the reading cue. */
.ins-side { align-self: stretch; align-items: stretch; }
.ins-side__pin { display: flex; flex-direction: column; align-items: stretch; width: 100%; }
@media (min-width: 1024px) and (min-height: 620px) {
  .ins-side__pin { position: sticky; top: calc(var(--header-h) + var(--s-48)); }
}
@media (min-width: 1024px) and (max-height: 619px) {
  .ins-side__pin { flex: 1 1 auto; }
  .ins-rail { position: sticky; top: calc(var(--header-h) + var(--s-24)); }
}
.ins-hero__photo, .ins-title__photo, .ins-side__photo { width: 100%; background: var(--paper-3); overflow: hidden; }
/* a figure: the product crop (Media/Detail, its own Sky-2 stage) or the belief bars on a Sky tile (facts sit on Sky,
   §0e.5), full rail width; in the sheet's flow below 1024 it takes the reading measure */
.ins-fig { display: flex; flex-direction: column; align-items: stretch; width: 100%; }
.ins-fig--stat { padding: var(--s-48) var(--cell-pad); }
/* the product figures are closed documents on their stage (Oct 8 round 3: the Harvey crop, built for a wide stage,
   ran the paper sheet off the stage's right and bottom edges into the page's own paper, so in the rail it read as a
   broken bracket around a blown-up stamp). Here the Sky-2 shows on all four sides and the sheet or frame is whole,
   ruled in Sky-line on every side and as tall as its content: Media/Detail draws its heading, the stamp and four
   lines at up to 1.15x (the stamp keeps its words above 13 px, the sheet fits a 289 px rail at 1024), the mini mock
   its frame with every line. */
.ins-fig .media[data-variant="detail"] .media__stage { aspect-ratio: auto; padding: var(--mi); }
.ins-fig .msheet { --z: clamp(1px, calc((100cqw - 50px) / 237.6), 1.15px); flex: none; gap: calc(16 * var(--z)); padding: calc(16 * var(--z));
  border: 1px solid var(--sky-line); }
.ins-fig .msheet__lines { width: 100%; }
.ins-fig .mini__stage { height: auto; padding-bottom: var(--mi); }
.ins-fig .mini__frame { flex: none; border-bottom: 1px solid var(--sky-line); }
.ins-fig .mini__body { flex: none; }
@media (max-width: 767px) { .ins-fig--stat { padding: var(--s-32) var(--cell-pad); } }
.ins-sheet > .article > .ins-fig { max-width: 640px; }

/* Rail: the reading-progress band, --cell-pad in from the margin line, 24 under the figure. It is the brand band
   (48 x 6); with scroll timelines it grows to the rail's width as the whole read is scrolled (one timeline on the
   flow, so the cue carries on from figure to figure; a cue tied to scrolling, no autonomous motion; off under reduced
   motion), and only the passage being read shows it (below). */
.ins-rail { display: flex; flex-direction: column; align-items: flex-start; padding: var(--s-24) var(--cell-pad) 0; }
.ins-progress { display: block; flex: none; width: 48px; height: 6px; background: var(--blue); }
@supports (animation-timeline: view()) {
  @media (min-width: 1024px) and (prefers-reduced-motion: no-preference) {
    .ins-flow { view-timeline: --ins-read block; }
    .ins-progress { align-self: stretch; width: auto; background: var(--paper-3); }
    .ins-progress::before { content: ""; display: block; width: 100%; height: 100%; background: var(--blue);
      animation: ins-read linear both; animation-timeline: --ins-read; animation-range: contain 0% contain 100%; }
  }
}
@keyframes ins-read { from { clip-path: inset(0 calc(100% - 48px) 0 0); } to { clip-path: inset(0 0 0 0); } }
/* one band on screen (Oct 8 round 3: every figure's band showed the same fill at once, two or three on screen and six
   in a static capture, a repeated control that read as a glitch): each passage is its own view timeline and its rail
   shows only while that passage holds the middle of the window (its top above 50vh, its foot below), so exactly one
   passage, the one being read, carries the cue; the others keep their box (opacity, no layout shift). A state, not a
   motion: it switches with the scroll position and applies under reduced motion too, where the band is the static
   brand band. Without scroll timelines every band shows, as before. */
@supports (animation-timeline: view()) {
  @media (min-width: 1024px) {
    .ins-read { view-timeline: --ins-pass block; view-timeline-inset: 50% 50%; }   /* the window's middle line */
    .ins-rail { opacity: 0; animation: ins-pass linear; animation-timeline: --ins-pass; }
  }
}
@keyframes ins-pass { from, to { opacity: 1; } }

/* Column (columns 3-6; below 1024 the full row): the sheet */
.ins-col { display: flex; flex-direction: column; align-items: stretch; }
/* the sheet fills its passage's height, so where a rail figure runs a few px past the words the paper-2 carries on
   to the next passage instead of leaving a paper seam across the document */
.ins-col > .ins-sheet { flex: 1 1 auto; }

/* Sheet: the article as a document on paper-2, edge to edge on its columns, so the column lines stop at its edges and
   never cross a line of the title or the text. Its text sits --cell-pad in (the page's text edge); reading text keeps
   a 640 px measure (about 70 characters); the wide parts (pull quote, Sky card) take the full inner width. Sheet 1
   opens on the title block, 64 over the body; sheet 2 opens straight on its H2. A passage's sheet that runs on into
   the next (--open) keeps no foot, and the next (--cont) opens one paragraph gap (24) down, so the seam between
   two passages is exactly the read's own paragraph spacing. */
.ins-sheet { display: flex; flex-direction: column; align-items: stretch; gap: var(--s-64); width: 100%;
  padding: var(--s-48) var(--cell-pad) var(--s-64); background: var(--paper-2); }
@media (max-width: 1023px) { .ins-sheet { gap: var(--s-48); padding-top: var(--s-32); padding-bottom: var(--s-48); } }
@media (max-width: 767px) { .ins-sheet { gap: var(--s-32); padding-top: var(--s-24); padding-bottom: var(--s-32); } }
.ins-sheet.ins-sheet--open { padding-bottom: 0; }
.ins-sheet.ins-sheet--cont { padding-top: var(--s-24); }
.ins-sheet--2 > .article > :first-child { padding-top: 0; }

/* Title block: back link, then the headline group (band + H1, the byline 16 under the H1, the dateline under it: who
   speaks and when, read with the headline), then Hire Roger 32 under it (P027, Q-31: the first screen's one dark-blue
   solid) */
.ins-title { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s-32); }
.ins-title > .ins-title__lede { padding-top: var(--s-16); }
.ins-title .hero__h1 { max-width: 16em; }
.ins-title__lede { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s-16); }
.ins-dateline { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s-8); }
.ins-updated { display: flex; flex-direction: row; flex-wrap: wrap; align-items: baseline; gap: var(--s-8); }
@media (max-width: 767px) { .ins-title { gap: var(--s-24); } .ins-title > .ins-title__lede { padding-top: 0; } }
.ins-sheet > .article { max-width: none; align-items: stretch; }
.ins-sheet > .article > :is(.article__p, .article__h2, .article__list, .article-signoff, .article-pq) { max-width: 640px; }
/* the pull quote's lead-in wraps on its own terms: an inline-block as wide as the measure (so it stays part of the
   paragraph's one string and the <br> still starts the quote), with pretty wrapping: one line from 1100, and no
   one-word orphan where it must break at 1024 (the paragraph's balance had broken it after "Stanford's") */
.ins-sheet .article-pq__by { display: inline-block; width: 100%; text-wrap: pretty; }
/* the quote wraps on its own too, balanced (inside a paragraph with a full-measure line, balance would aim at that) */
.ins-sheet .article-pq__q { display: inline-block; width: 100%; text-wrap: balance; }
/* the Sky card: the list that carries the argument (Sky = Roger's side), its own text --cell-pad in */
.ins-sheet .article-panel { padding: var(--s-48) var(--cell-pad); }
.ins-sheet .article-panel > * { max-width: 640px; }
@media (max-width: 767px) { .ins-sheet .article-panel { padding: var(--s-32) var(--cell-pad); } }

/* Photo strip: the article's two library squares as their own full-width row on the paper ground between the sheets:
   3+3 (layout.css · Cols, cards mode: outer edges on the margin lines, the centre line down the gutter between them),
   tablet 2-up, phones 1-up at full width (no 143 px thumbnails). 64 above and below (48 / 32), so the column lines show
   around it and it reads as the pause between two movements of the argument. */
.ins-strip { padding: var(--s-64) 0; }
@media (max-width: 1023px) { .ins-strip { padding: var(--s-48) 0; } }
@media (max-width: 767px) { .ins-strip { padding: var(--s-32) 0; } }
.ins-strip__photo { width: 100%; overflow: hidden; background: var(--paper-3); }

/* Related · Single (R2-F5): the label above (on the text inset), then one Card from margin line to margin line in the
   /insights wide-row pattern: the square on columns 1-2 (tablet 1 of 2), then the /insights card's own four levels
   (Oct 8 round 3: a title and Read more alone left some 500 x 428 px of the plate blank): the tag, the title (H2 from
   1024), the excerpt (Lead from 1024) and Read more, one group 32 over its cue on the plate's foot, so the last line
   sits on the square's base line and the plate reads as filled. Phones: the square over the text. 64 under the sheet
   (48 / 32 below 1024). The title link covers the card (one target); the square is decorative (aria-hidden). */
.ins-related { display: flex; flex-direction: column; align-items: stretch; gap: var(--s-24); width: 100%; padding-top: var(--s-64); }
.ins-related__head { display: flex; padding: 0 var(--cell-pad); }
@media (max-width: 1023px) { .ins-related { padding-top: var(--s-48); } }
@media (max-width: 767px) { .ins-related { gap: var(--s-16); padding-top: var(--s-32); } }
@media (min-width: 768px) {
  .ins-related__card { flex-direction: row; }
  .ins-related__card .card__body { flex: 1 1 0; min-width: 0; justify-content: flex-end; gap: var(--s-32); }
  .ins-related__card .card__foot { flex: none; }
}
@media (min-width: 768px) and (max-width: 1023px) {
  .ins-related__card .card__media { flex: 0 0 calc((100% + 2px + var(--gutter)) / 2 - var(--gutter) / 2 - 1px); }
}
/* the four levels fit beside the square from 1280 (a 32 inset to 1439, 48 from 1440, where the square is 428); on the
   narrow desktop and the tablet row (square 288-374 px) the excerpt rests, so the plate is never taller than the
   square beside it (a paper-2 sliver under the photo would read as an error) */
@media (min-width: 768px) and (max-width: 1279px) { .ins-related__card .ins-card__x { display: none; } }
@media (min-width: 1024px) {
  .ins-related__card .card__media { flex: 0 0 calc((100% + 2px + var(--gutter)) / 3 - var(--gutter) / 2 - 1px); }
  .ins-related__card .card__body { padding: var(--s-48) var(--cell-pad); }
  .ins-related__t { font-size: clamp(28px, 2.2vw, 32px); line-height: 1.16; letter-spacing: -0.012em; }
  .ins-related__card .ins-card__head { gap: var(--s-16); }
  .ins-related__card .ins-card__x { font-size: var(--lead-fs); line-height: var(--lead-lh); letter-spacing: -0.005em; }
}
@media (min-width: 1024px) and (max-width: 1439px) { .ins-related__card .card__body { padding-top: var(--s-32); padding-bottom: var(--s-32); } }

/* CTA line on /future-of-the-project-manager (typography only, no word changes): "their week back." holds together
   (.nowrap) and two line breaks show only in the width bands where the free wrap ends a line within the clearance of
   a column line (C6): after "Give your" on phones from 328, after "PMs" at 832-927. Measured clear from 320 to 1920. */
.ins-br { display: none; }
@media (min-width: 328px) and (max-width: 767px) { .ins-br--m { display: inline; } }
@media (min-width: 832px) and (max-width: 927px) { .ins-br--t { display: inline; } }

/* =============================== Roger announcement =============================== */
/* Restrained long-form reading, with only two deliberate editorial panels. */
.announcement-page .announcement {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  padding: var(--s-32) 0 var(--s-48);
}
.announcement__header {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s-16);
  width: min(100%, 1040px);
  padding: 0 0 var(--s-24);
}
.announcement__breadcrumb { display: flex; min-height: var(--tap); align-items: center; }
.announcement__eyebrow {
  display: flex;
  align-items: center;
  gap: var(--s-12);
  color: var(--blue);
  font-family: var(--narrow);
  font-size: var(--label-fs);
  font-weight: 700;
  letter-spacing: var(--label-ls);
  line-height: var(--label-lh);
}
.announcement__bar { width: 32px; height: 4px; background: var(--blue); }
.announcement__title {
  max-width: 1040px;
  color: var(--ink);
  font-family: var(--serif);
  font-size: clamp(32px, 3vw, 36px);
  font-weight: 400;
  letter-spacing: -.015em;
  line-height: 1.18;
  text-wrap: balance;
}
.announcement__content {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  width: min(100%, 1040px);
  padding: 0;
}
.announcement__section {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--s-8);
  padding: var(--s-16) 0;
}
.announcement__section h2 {
  margin-bottom: var(--s-4);
  color: var(--ink);
  font-family: var(--serif);
  font-size: clamp(22px, 2vw, 24px);
  font-weight: 400;
  letter-spacing: -.005em;
  line-height: 1.3;
}
.announcement__section p {
  color: var(--ink-2);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.55;
}
.announcement__section .announcement__lead {
  color: var(--ink);
  font-size: 16px;
  line-height: 1.55;
}
.announcement__list {
  display: flex;
  flex-direction: column;
  gap: var(--s-8);
  padding: var(--s-4) 0;
  color: var(--ink-2);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.5;
}
.announcement__list li {
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr);
  gap: var(--s-8);
}
.announcement__list li::before {
  content: "›";
  color: var(--blue);
  font-family: var(--serif);
  font-size: 24px;
  line-height: 1.05;
}
.announcement__callout {
  margin: var(--s-8) 0;
  padding: var(--s-16) var(--s-24);
  background: var(--blue);
  color: var(--on-blue) !important;
  font-family: var(--serif) !important;
  font-size: 18px !important;
  line-height: 1.45 !important;
}
.announcement__section--last {
  padding-bottom: 0;
}
.announcement__invitation {
  margin-top: var(--s-8);
  padding: var(--s-16) var(--s-24);
  border-left: 4px solid var(--blue);
  background: var(--sky-2);
  color: var(--ink) !important;
  font-family: var(--serif) !important;
  font-size: 18px !important;
  line-height: 1.45 !important;
}
.announcement__sincerely { margin-top: var(--s-16); color: var(--ink) !important; }
.announcement__signatories {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s-12) var(--s-24);
  padding-top: var(--s-24);
  border-top: 1px solid var(--rule);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 400;
  line-height: 1.45;
}
.announcement__signatories li { display: block; }
.announcement__footer {
  width: 100%;
  background: var(--sky);
  color: var(--ink);
}
.announcement__footer-in {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-24);
  width: min(calc(100% - 2 * var(--margin)), var(--container));
  min-height: 112px;
  margin: 0 auto;
  padding: var(--s-32) 0;
}
.announcement__footer p,
.announcement__footer a {
  font-family: var(--narrow);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .12em;
  line-height: 1.5;
}
.announcement__footer a { color: var(--blue); text-decoration: underline; text-underline-offset: 4px; }
@media (max-width: 1023px) {
  .announcement-page .announcement { padding-top: var(--s-32); }
  .announcement__header { padding-bottom: var(--s-24); }
}
@media (max-width: 767px) {
  .announcement-page .announcement { padding: var(--s-24) 0 var(--s-32); }
  .announcement__header { gap: var(--s-12); padding-bottom: var(--s-16); }
  .announcement__title { font-size: 32px; line-height: 1.16; }
  .announcement__content { padding-top: 0; }
  .announcement__section { gap: var(--s-8); padding: var(--s-12) 0; }
  .announcement__section h2 { font-size: 22px; }
  .announcement__list { gap: var(--s-8); }
  .announcement__callout,
  .announcement__invitation { padding: var(--s-16); }
  .announcement__signatories { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-8) var(--s-16); }
  .announcement__footer-in { align-items: flex-start; flex-direction: column; justify-content: center; gap: var(--s-12); width: calc(100% - 2 * var(--margin)); }
}
@media (max-width: 359px) {
  .announcement__signatories { grid-template-columns: minmax(0, 1fr); }
}
