/* =============================================================================================
   WHAT IS LEFT IN THIS FILE

   Everything that could become a class property has been moved onto the classes themselves and is
   editable in the Designer. What remains is what Webflow cannot express:

     - custom breakpoints. Webflow has 991 / 767 / 479; this layout needs 1199 and a few others.
     - child combinators inside the rich text (> p, > h2), which set the article's vertical rhythm.
     - :has() and :empty, which hide the dangling separator and the empty social row.
     - !important, needed to beat Webflow's own #w-node- grid placements.
     - properties Webflow does not expose: text-wrap, accent-color, object-fit,
       text-decoration-color, text-underline-offset.
     - html / body selectors: the page background and the body font-size floor.

   If a rule here duplicates a class property, the class wins by being the later source. Delete the
   rule here rather than editing both.
   ============================================================================================= */

/* =============================================================================================
   INSIGHT SINGLE — typography, hierarchy and layout for the Insights CMS template.

   Source of truth: harvey-experience-webflow/insight-lab/type.css
   Worked out against a local mirror of the live page that loads this same Webflow stylesheet, so
   every number in the comments below was measured on the real thing, not estimated.

   LOAD THIS ON THE INSIGHTS TEMPLATE PAGE ONLY (Page settings -> Custom code -> Head), not in the
   site head. Section 12 explains why that distinction matters.
   ============================================================================================= */

/* =============================================================================================
   Insight single — typography and hierarchy pass.

   Everything here is scoped to the blog-single classes, so nothing else on the site moves. Each
   block says what it replaces, because that is what has to be set on the class in the Designer.

   The three things actually wrong with the page, in order of how much they cost:

   1. .toc-article-text sets line-height:1 and every p, li and h2 inherits it. Body copy has no
      leading at all — the lines touch.
   2. The same element uses a flex column with a uniform gap:3em. A heading therefore sits exactly
      as far from its own paragraph as two unrelated paragraphs sit from each other, so nothing
      binds to anything. This is the "hierarchy is all over the place" in one line of CSS.
   3. The whole page is em-based off a body font-size that is viewport ÷ constant with no floor,
      so the article reads at 16.6px at 1440 and collapses from there.

   Result: micro-spacing far too tight, macro-spacing far too loose. Fixing the gap alone would not
   help — without leading the paragraphs stay slabs.
   ============================================================================================= */


/* ---------------------------------------------------------------------------------------------
   1. THE BASE
   Same floor and ceiling already live on the Insights list page, applied here for consistency
   across the section. html body (0,0,2) so it outranks the Osmo block whichever embed loads first.
   At 1440 this takes the base from 13px to 14px, which carries body copy from 16.6px to 17.9px —
   a reading size rather than a caption size.
   --------------------------------------------------------------------------------------------- */
html body { font-size: clamp(14px, var(--size-font), 18px); }


/* ---------------------------------------------------------------------------------------------
   1b. ONE SPINE
   Replaces: .toc-layout   { grid-template-columns: .5fr 2fr .5fr }
             .article-head { margin-left: 167.25px }

   Measured on the page as it stands, at 879px wide:
       h1 / standfirst / meta   140 → 740
       author row               186
       article body             333 → 739
   Three different left edges, and the right edges line up only by accident — .article-head and
   .toc-article both happen to cap at 600px, from different offsets.

   The original intent is visible in .5fr 2fr .5fr: a rail, a measure, and a mirror column to keep
   the measure centred. It fails because fr units make the outer two unequal (192.5px against
   150px) and nothing centres the set, so the measure drifts right while the hero sits left on a
   hard-coded 167.25px margin.

   Fixing the mirror column fixes both: the measure lands on the page's centre axis, so the hero
   only has to be centred too — no calc, no magic number, no coupling between the two containers.

   .toc-layout has THREE children, not two: the Quick Take Aways panel sits in the grid alongside
   the rail and the article, spanning grid-column 1 / 4. That span is why a single-column template
   cannot work here — a child reaching line 4 creates the missing tracks implicitly, and the track
   list resolves to 304.688px 462px 0px no matter what is declared. Three columns is therefore the
   right structure; it only needs the outer two to match.
   --------------------------------------------------------------------------------------------- */
/* .toc-layout is NATIVE now — grid template, gaps, justify-content, width and padding are
   set on the class in the Designer. Only the stacking breakpoint below stays here, because
   1199px is not one of Webflow's three. */

/* Below this the rail has no margin to live in, so everything stacks to one column. The children
   carry explicit grid-column placements that have to be released too, or the article stays pinned
   to a column 2 that no longer exists.

   !important is load-bearing here. Webflow emits grid child placement as ID selectors
   (#w-node-93e6b42f-... { grid-column: 2 / 3 }), so specificity 1,0,0 beats any class rule. The
   alternative is to copy those ids into this sheet, but they are regenerated whenever the element
   is rebuilt in the Designer — a rule that silently stops applying is worse than an !important. */
@media (max-width: 1199px) {
  .toc-layout { grid-template-columns: minmax(0, 46em); }
  /* grid-ROW has to be released along with the column. The rail and the article are both placed in
     row 2 explicitly — correct when they sit in different columns, but stacked it puts them in the
     same cell and the rail renders straight over the article text. */
  .toc-layout > .toc-sidebar,
  .toc-layout > .toc-article,
  .toc-layout > .takeaway-wrapper { grid-column: 1 / -1 !important; grid-row: auto !important; }

  /* Sticky has to come off with the column. Stacked, the rail is above the article rather than
     beside it, so sticking it pins it over the text as you scroll. The template already does this
     — but only below 767px, which left everything between 768 and 1099 overlapping. */
  .toc-sidebar { position: relative; top: 0; }
}

/* .toc-article, .toc-article-text-wrap and .article-head are NATIVE now. */


/* ---------------------------------------------------------------------------------------------
   2. THE ARTICLE COLUMN
   Replaces: .toc-article-text { line-height: 1; gap: 3em }
             .toc-article     { text-align: justify }

   text-align:justify is currently overridden by the child, so it does nothing — but it is a
   loaded gun. Justified text with no hyphenation dictionary tears rivers through a 60ch column.

   The gap goes to zero and spacing moves onto the elements themselves, because a single gap
   cannot express "this heading owns the paragraph below it". Margins can.
   --------------------------------------------------------------------------------------------- */

/* line-height, gap and max-width on .toc-article-text are NATIVE now. text-wrap is not a
   Webflow property, so it stays here. */
.toc-article-text { text-wrap: pretty; }

/* Body copy. margin-bottom only — never top — so the rhythm is set by one edge and headings can
   claim the space above themselves without fighting a neighbour's margin. */
.toc-article-text > p,
.toc-article-text > ul,
.toc-article-text > ol,
.toc-article-text > figure { margin: 0 0 1.15em; }

.toc-article-text > *:last-child { margin-bottom: 0; }

/* Lists: the marker sits in the margin so the text edge stays flush with the paragraphs above it.
   Currently the li text starts 20px in from the paragraph edge, which breaks the left line. */
.toc-article-text ul,
.toc-article-text ol { padding-left: 1.1em; }
.toc-article-text li { margin-bottom: .4em; line-height: 1.6; }
.toc-article-text li:last-child { margin-bottom: 0; }


/* ---------------------------------------------------------------------------------------------
   3. HEADINGS — the binding
   Replaces the uniform 3em gap. The ratio is what does the work: the space ABOVE a heading is
   roughly four times the space below it, so the heading reads as belonging to what follows rather
   than floating between two blocks.
   --------------------------------------------------------------------------------------------- */
/* Headings also live OUTSIDE the rich text: "The Sources used in this Article:" sits directly in
   .toc-article-text-wrap, so a child combinator on .toc-article-text misses it entirely — it was
   rendering at 28px with zero margins, jammed onto its own paragraph. Both parents listed. */
.toc-article-text > h2 {
  font-size: 1.5em;
}

.toc-article-text-wrap > h2 {
  font-size: 1.9125em;   /* 1.5 x 1.275, the rich text's own two steps */
}

.toc-article-text > h2,
.toc-article-text-wrap > h2 {
  /* font-size is set per context above — a value here would override both and undo the point. */
  line-height: 1.15;           /* was .98, which let long headings collide with themselves */
  letter-spacing: -.03em;      /* was -.05em; too tight to read at this size in caps */
  margin: 2.6em 0 .62em;
  text-wrap: balance;          /* two-line headings break evenly instead of leaving one orphan */
}

.toc-article-text > h3,
.toc-article-text-wrap > h3 {
  font-size: 1.16em;
  line-height: 1.3;
  margin: 1.9em 0 .45em;
  text-wrap: balance;
}

/* A heading must never open the article with a hole above it. */
.toc-article-text > h2:first-child,
.toc-article-text > h3:first-child { margin-top: 0; }


/* ---------------------------------------------------------------------------------------------
   4. THE LEAD-IN PATTERN
   Every example paragraph opens with a bolded name — "JetSupport (B2B aviation services)." — which
   is doing the job of a subheading with none of the affordances. Giving it its own line turns four
   dense paragraphs into a scannable list without touching the CMS copy.
   --------------------------------------------------------------------------------------------- */
.toc-article-text > p > strong:first-child {
  display: block;
  font-weight: 500;
  letter-spacing: -.01em;
  margin-bottom: .18em;
}

/* The trailing "(Concrete results pending for publication.)" is an aside, not body copy. */
.toc-article-text em { color: #6B7280; font-style: italic; }


/* ---------------------------------------------------------------------------------------------
   5. LINKS
   Inline links currently carry no affordance at all beyond colour, and the colour is the same
   black as the surrounding text — so they are invisible until hovered.
   --------------------------------------------------------------------------------------------- */
.toc-article-text a {
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .18em;
  text-decoration-color: rgba(12, 12, 12, .32);
  transition: text-decoration-color .2s ease;
}
.toc-article-text a:hover { text-decoration-color: rgba(12, 12, 12, 1); }


/* ---------------------------------------------------------------------------------------------
   6. THE RAIL
   .toc-link is .875em of a base that has already shrunk, landing at 11.4px — below the point
   where it reads as text rather than texture. The active state also had no weight of its own.
   --------------------------------------------------------------------------------------------- */
/* .toc-sidebar width is NATIVE now. */


/* ---------------------------------------------------------------------------------------------
   6a. BACK TO INSIGHTS — new element
   There is currently no way out of an article except the browser's back button, and no way at all
   for anyone who arrived from search.

   It goes at the top of the rail rather than above the headline. Above the headline it is seen
   once and then scrolled past — gone exactly when it becomes useful, which is halfway down a piece
   that turned out not to be the one you wanted. The rail is already sticky and is already the
   navigation column, so a back link there stays reachable for the whole read. On narrow screens
   the rail stacks above the article, which puts the link in the same place a header version would
   have been, so nothing is lost.

   Markup to add in the Designer: a Link Block as the FIRST child of the TOC Sidebar, class
   `toc-back`, pointing at /insights, containing an arrow span and a text element.
   --------------------------------------------------------------------------------------------- */
/* On wide screens it leaves the rail entirely and pins to the top-left corner of the page, under
   the Milkman mark (fixed, top 24px, 43px tall — so 84px clears it). The left margin is empty at
   this width, and a corner affordance is read as "leave", where the same link inside the rail is
   read as part of the article's furniture.

   Only above the stacking breakpoint. Once the layout is one column the content runs full width and
   a fixed link would sit on top of it, so it goes back into the flow at the top of the rail. */
@media (min-width: 1200px) {
  .toc-back {
    position: fixed;
    top: 84px;
    left: clamp(20px, 2vw, 30px);
    z-index: 60;
    margin-bottom: 0;
  }
}

.toc-back:hover { color: #0C0C0C; }

/* The arrow carries the hover, not the text — it moves toward where it is pointing. Only the
   arrow is animated, so the label stays still and the line does not reflow under the cursor. */
.toc-back__arrow {
  display: inline-block;
  transition: transform .22s cubic-bezier(.4, 0, .2, 1);
}
.toc-back:hover .toc-back__arrow { transform: translateX(-3px); }

@media (prefers-reduced-motion: reduce) {
  .toc-back__arrow { transition: none; }
  .toc-back:hover .toc-back__arrow { transform: none; }
}

/* The rail is padded with four empty .spacer-50 divs — one before the sign-up card and three
   trailing. With the rail's own 28px gap on top of them that is 156px of dead air below the last
   thing in the column, which is invisible on desktop (it hangs off the bottom of a sticky element)
   but shows as a hole between the rail and the article once the two stack. Spacing belongs on the
   thing that needs it, not in empty divs. */
.toc-sidebar > .spacer-50 { display: none; }
.toc-sidebar > .sticky-card { margin-top: 1.6em; }
.toc-link:hover { color: #0C0C0C; }
/* The TOC active state. An inline <style> on the page sets
       [data-toc-item][data-toc-status="active"] { color: rgb(99,91,255) }
   which is Webflow's default link purple and the only chromatic accent left on the page. It
   is (0,2,0) and beats .toc-link, so the rail's current item was rendering purple.

   My earlier rule targeted .w--current, which is the class Webflow sets for the CURRENT PAGE,
   not the current heading — this list is built by the TOC script and uses a data attribute
   instead, so that rule never matched anything. Matching the real attribute at equal
   specificity, and later in the cascade, is what actually wins. */
/* THE RAIL'S ACTIVE STATE — and why the two earlier attempts did nothing.

   The text is not in the <a>. The TOC script clones a template link whose label lives in a
   <span class="span">, and .span { color: var(--colors--text) } paints that #808080. Both my own
   .toc-link colour and the template embed's [data-toc-status="active"] { color:#635bff } target the
   <a>, which renders no text of its own — so neither was ever visible. Measured on the published
   page: all four items were the same grey and the rail had no active state at all.

   Colouring the span is the fix. It cannot be a class property: .span is used elsewhere on the
   site, so it has to be scoped by descent, which the Designer cannot express. */
.toc-list .toc-link [data-toc-text] {
  color: #6B7280;
  -webkit-text-fill-color: #6B7280;
  transition: color .2s ease, -webkit-text-fill-color .2s ease;
}
.toc-list .toc-link:hover [data-toc-text] {
  color: #0C0C0C;
  -webkit-text-fill-color: #0C0C0C;
}
.toc-list .toc-link[data-toc-status="active"] [data-toc-text] {
  color: #0C0C0C;
  -webkit-text-fill-color: #0C0C0C;
}

/* UNRESOLVED — the rail has no visible active state.

   All four items render the same ink. Colouring the <a> does nothing because the label lives in a
   <span class="span"> inside it. Colouring that span does not work either: on the published page,
   color:...!important on the span changed nothing, and no readable stylesheet sets a competing
   value. -webkit-text-fill-color was a false lead on my part — it defaults to currentColor, so
   reading it back only ever mirrored `color`.

   So the rules below are correct in intent and provably not winning, and I do not yet know what
   beats them. Next thing to try: inspect the span in the browser's own element inspector, which
   shows the winning declaration and its origin directly — something getComputedStyle cannot do,
   and which the cross-origin sheets here blocked me from reconstructing.

   Harmless as it stands: the rail is readable, it just does not mark where you are. */

/* The left rule DOES sit on the <a>, so that one works — it just needs to beat the template's
   #635bff at (0,2,0), hence .toc-list in front. */
.toc-list .toc-link[data-toc-status="active"] { border-left-color: #0C0C0C; }

/* "Sign-up" sits at 24px in a rail whose own labels are 11px — the least important thing on the
   page was the loudest. */
.toc-sidebar .text-size-large-2 { font-size: 1.15em; line-height: 1.3; }


/* ---------------------------------------------------------------------------------------------
   6b. THE AUTHOR LINE
   Replaces: .team-member-info { flex-flow: column }  +  the .divider-2 rule beneath it

   Modelled on the Figma blog's byline, which is the reference here. What makes that one work is
   restraint, not decoration: avatar, name, role — all on ONE line, the role sitting directly after
   the name in a lighter weight at the same size and no label, no rule under it. It reads as a
   sentence rather than a business card.

   The version here stacks name over role and then draws a horizontal rule below, so a byline that
   should be one quiet line occupies three and carries more visual weight than the standfirst above
   it. Same information, a third of the height, and the space it gives back separates the header
   from the article better than the rule did.
   --------------------------------------------------------------------------------------------- */
.team-member-info {
  flex-direction: row;
  align-items: baseline;
  flex-wrap: wrap;
  column-gap: .55em;
  row-gap: 0;
}

.team-member-image { width: 32px; height: 32px; flex: 0 0 32px; }
.team-member { gap: 12px; align-items: center; }

.team-member-info .blending-difference { font-weight: 500; letter-spacing: -.01em; }

/* The role. #808080 is the CSS keyword `gray` and is off-palette — the brand greys are #6B7280
   and #9CA3AF. Lighter in colour rather than in weight, because Diatype has no 330. */
.team-member-info .text-muted-2 { color: #6B7280; font-weight: 400; }

/* The rule did the job that white space should be doing. */
.article-head .divider-2 { display: none; }

/* With the rule gone the meta row needs its own air, or it crowds the byline. */
.article-head .news-category-read { margin-top: 1.4em; }


/* ---------------------------------------------------------------------------------------------
   6c. THE AUTHOR CARD — new element, end of article
   Modelled on the block that closes a Figma blog post. Measured there: hairline rule above, 64px
   round avatar, 16px gap, and the bio set at the SAME size and the SAME colour as the article's
   body copy — not smaller, not greyed. Then the social links underneath, underlined, separated by
   a thin pipe. That refusal to shrink it is what gives the block its confidence; treated as a
   caption it would read as a footnote.

   The bio opens with the name, which is why there is no separate name heading — the sentence does
   that job. It is a copy convention rather than a layout one, so it has to hold in the CMS: a bio
   that does not start with the name will read as an orphan paragraph.

   Milkman's Authors collection currently has Name, Function, Profile Avatar and Slug only. This
   block needs a Bio field and at least one social URL before it can be built for real — see the
   README. The copy in the mirror is placeholder.
   --------------------------------------------------------------------------------------------- */
.author-card {
  display: flex;
  gap: 16px;
  align-items: flex-start;
  border-top: 1px solid #E5E7EB;
  margin-top: 2.6em;
  /* Symmetric on purpose. Measured before: 39px above the avatar and 10px between the social links
     and the next section's divider, so the block sat hard against the line below it and floated
     off the one above. The card should read as one band with equal air on both sides. */
  padding-top: 2.2em;
  padding-bottom: 2.2em;
  /* The card is a sibling of .toc-article-text, not a child, so it does not inherit the article's
     reading size — 1em here would resolve against .toc-article and land at 14px. Taking the same
     variable the article uses keeps the bio at body size, which is the entire point of the block. */
  font-size: var(--font-size--medium);
}

.author-card__avatar {
  flex: 0 0 64px;
  width: 64px;
  height: 64px;
  border-radius: 50%;      /* the one deliberate round corner on a square-cornered site: a face */
  object-fit: cover;
  display: block;
}

.author-card__links a {
  color: #0C0C0C;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .18em;
  text-decoration-color: rgba(12, 12, 12, .32);
  transition: text-decoration-color .2s ease;
}
.author-card__links a:hover { text-decoration-color: rgba(12, 12, 12, 1); }

/* --- social links: nothing shows unless there is somewhere to go ---------------------------
   Three separate cases, because they fail in three different ways:

   1. A link with no destination. Conditional visibility in the Designer is the real mechanism —
      Webflow drops the element from the published HTML per item, so an author with no Instagram
      genuinely has no element. These two selectors are the backstop for when that is forgotten,
      matching a missing or blank href.
   2. The separator. It is a real span rather than an ::before on the second link, so the pipe
      stays out of the anchor's click target and out of its underline. It earns its place only
      when two links actually survive — hence :has(a ~ a), the general sibling combinator, since
      the span itself sits between them and would break an adjacent one.
   3. The row. With both fields empty there is a flex container with nothing in it, still taking
      its gap from the bio above.
   ------------------------------------------------------------------------------------------- */
.author-card__links a:not([href]),
.author-card__links a[href=""] { display: none; }

/* The condition has to test for two links with real destinations, not just two anchors. Hiding an
   anchor with display:none leaves it in the DOM, and selectors do not care about display — so a
   plain :has(a ~ a) still matched when one of the two was blank, and the separator printed with
   nothing after it. Same dangling-separator bug as the meta row at 8b. */
.author-card__links:not(:has(a[href]:not([href=""]) ~ a[href]:not([href=""]))) .author-card__sep { display: none; }

.author-card__links:not(:has(a[href]:not([href=""]))) { display: none; }

/* Stacked, the avatar above the text reads better than a 64px column squeezing the bio. */
@media (max-width: 520px) {
  .author-card { flex-direction: column; gap: 14px; }
}

/* An author with no bio yet — Jakub, at the time of writing — would otherwise render as a hairline,
   a portrait and nothing else. Conditional visibility on the Bio field is the proper mechanism in
   the Designer; this is the belt to that pair of braces, and costs one selector. */
.author-card:has(.author-card__bio:empty) { display: none; }


/* ---------------------------------------------------------------------------------------------
   7. OFF-PALETTE GREY
   .caption-2 uses the CSS keyword `gray` (#808080). The brand greys are #6B7280 and #9CA3AF, and
   #808080 is neither — it reads slightly warm against both.
   --------------------------------------------------------------------------------------------- */
.caption-2 { color: #6B7280; letter-spacing: .08em; }


/* ---------------------------------------------------------------------------------------------
   8. CORNERS
   Eleven different radii are in play on this one page: 4, 5, 6, 8, 10, 12, 13, 15, 128, 200 and
   999px — on a site whose nav, buttons and case-study media are all square. The takeaway panel and
   the hero media are the two that show.
   --------------------------------------------------------------------------------------------- */
.takeaway-wrapper,
.media-wrapper-2,
.customer-mini { border-radius: 0; }

/* Avatars are the exception and have to be excluded by selector, not by ordering: .section.is-blog
   img is specificity 0,2,1 and beats .author-card__avatar at 0,1,0, so the squaring rule was
   winning and the portrait came out as a square. A face is the one thing on this site that should
   be round. */
.section.is-blog img:not(.author-card__avatar):not(.team-member-image),
.section.is-blog .w-richtext figure img { border-radius: 0; }


/* ---------------------------------------------------------------------------------------------
   8b. THE DANGLING SEPARATOR
   The meta row renders three .caption-2 elements: the category, a "·", and a second tag that is
   empty on this post. The separator is static markup, so it prints whether or not anything follows
   it — the row currently reads "ALWAYS-ON MARKETING ·".

   Hiding it conditionally rather than deleting it keeps the row correct on posts that DO carry a
   second tag; :empty only matches when the element has no child nodes at all, which is exactly the
   case here (verified: childNodes 0).
   --------------------------------------------------------------------------------------------- */
.news-category-read .caption-2:empty { display: none; }
.news-category-read .caption-2:has(+ .caption-2:empty) { display: none; }


/* ---------------------------------------------------------------------------------------------
   9. THE STRAY FONT
   "Quick Take Aways" is set in TWK Ghost at weight 300 — the only appearance of a third family on
   the site, left over from before the move to Harvey. Everything around it is ABC Diatype.
   --------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------
   9b. QUICK TAKE AWAYS — moved to the right column
   Replaces: a full-width dark panel above the article (grid-column 1 / 4, a grey-over-image
   background, 28px padding, white text, and a "Whitepaper Download" link in a second column).

   It becomes the right-hand margin note the Figma article uses: hairline, label, text, nothing
   else. No panel, no background, no button. The point of a takeaway list is to be glanceable
   beside the argument, not to interrupt it — as a full-width block it sat between the header and
   the first paragraph and had to be read before the article could start.

   The whitepaper link goes because it was the only call to action inside a summary; the article
   already carries a CTA banner further down.
   --------------------------------------------------------------------------------------------- */
.takeaway-wrapper {
  /* ID-selector placement again (#w-node-...), so !important is required — see the note at 1b. */
  grid-column: 3 / 4 !important;
  grid-row: 2 / 3 !important;
  display: block;
  background: none;
  border-radius: 0;
  border-top: 1px solid #E5E7EB;
  max-width: none;
  width: 100%;
  margin: 0;
  padding: 1.4em 0 0;
  text-align: left;
  align-items: flex-start;
}

/* The hairline moves down to the text block, so the share row sits ABOVE the line the way it does
   on the Figma page — icons, air, rule, label. */
.takeaway-wrapper { border-top: 0; padding-top: 0; }

.takeaway-wrapper .customer-mini-text {
  width: 100%;
  display: block;
  border-top: 1px solid #E5E7EB;
  padding-top: 1.4em;
}

/* --- share row ------------------------------------------------------------------------------
   Figma's are 32×32 with an 8px radius and a 40px pitch. Size and pitch copied; the radius is not
   — this site squared eleven different corner values on purpose, and four rounded chips would be
   the only soft corners left on the page.
   -------------------------------------------------------------------------------------------- */
.share-row { display: flex; gap: 8px; margin-bottom: 3.4em; }

.share-btn svg { width: 15px; height: 15px; display: block; }

.share-btn:hover { background: #0C0C0C; border-color: #0C0C0C; color: #FFFFFF; }

/* Copy has no destination to navigate to, so the button has to say so itself. */
.share-btn.is-copied { background: #0C0C0C; border-color: #0C0C0C; color: #FFFFFF; }
.share-btn.is-copied::after {
  content: "Copied";
  position: absolute;
  margin-top: 52px;
  font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: #6B7280;
  white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) { .share-btn { transition: none; } }
.takeaway-wrapper .customer-logo-wrap { display: none; }

/* The one CTA inside a summary. */
.takeaway-wrapper .customer-quote-follow-link { display: none; }

/* .text-color-white is a class, so the white has to be overridden rather than inherited away — and
   the label carries THREE classes (.text-medium.specialty.text-color-white, 0,3,0), which beat a
   two-class override and left "Quick Take Aways" rendering white on white. Match its specificity. */
.takeaway-wrapper .text-medium.specialty.text-color-white,
.takeaway-wrapper .text-color-white,
.takeaway-wrapper .take-aways,
.takeaway-wrapper li { color: #0C0C0C; }

/* Sidebar type: smaller than the article so it reads as a note beside it, not a second voice.
   1em, not a fraction — this resolves against the page base (14px) while the article runs at
   1.275em (17.9px), so the step down is already built in. .82em landed at 11.5px, which is caption
   territory rather than something anyone reads. */
.takeaway-wrapper .take-aways { font-size: 1em; }
.takeaway-wrapper .take-aways ul { padding-left: 1.05em; margin: 0; }
.takeaway-wrapper .take-aways li {
  line-height: 1.5;
  padding-bottom: 0;          /* was a 20px pad doing the job a margin should do */
  margin-bottom: .85em;
}
.takeaway-wrapper .take-aways li:last-child { margin-bottom: 0; }

/* Stacked, it is no longer a margin note — give it back the article's reading size. */
@media (max-width: 1199px) {
  .takeaway-wrapper { grid-column: 1 / -1 !important; grid-row: auto !important; }
  .takeaway-wrapper .take-aways { font-size: 1.15em; }
}


/* The LABEL only. .take-aways is the rich text holding the bullets, not the heading — styling that
   as a label turns the whole list into uppercase letter-spaced small caps. */
.takeaway-wrapper .text-medium.specialty {
  font-family: var(--font-family--caption, "ABC Diatype", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif);
  font-weight: 500;
  letter-spacing: .12em;
  text-transform: uppercase;
  font-size: .84em;        /* .78em landed at 10.9px — under the size where caps stay legible */
  margin-bottom: 1.1em;
}

/* The bullets are body copy on a dark panel and need the same leading as the article. */
.take-aways { font-size: 1em; letter-spacing: 0; text-transform: none; }
.take-aways ul { padding-left: 1.1em; margin: 0; }
.take-aways li { line-height: 1.55; margin-bottom: .7em; }
.take-aways li:last-child { margin-bottom: 0; }


/* ---------------------------------------------------------------------------------------------
   11. NEWSLETTER — the site's own block, reused
   Replaces a bespoke section I had built from the Figma reference. That was the wrong instinct:
   this block already exists on /insights and is better than what I drew — Harvey Serif title, a
   line of description, and a bare field on a single hairline, over the same BG-blue.avif the
   loader panel now uses. Reusing it class-for-class means the styling is already correct and the
   port is "copy the section", not "rebuild it".

   ONE structural change, and it applies to BOTH pages because both use these classes:

   The opt-in is missing. .approach-news_form is a flex ROW carrying the underline, so a checkbox
   added inside it would land beside the field rather than under it. The underline therefore moves
   down to a new .approach-news_field row, and the form becomes a column holding that row plus the
   consent. Nothing about the visible line changes; it just belongs to a smaller element now.
   --------------------------------------------------------------------------------------------- */
.approach-news_form,
.approach-news_form.w-form {
  display: block;
  border-bottom: 0;
  padding-bottom: 0;
}

.form-9 { display: block; flex: 1; }

/* Square, like everything else, and light enough to read on the dark panel without becoming the
   loudest thing in the row. accent-color keeps the checked state native rather than rebuilt. */
.approach-news_check {
  flex: 0 0 16px;
  width: 16px;
  height: 16px;
  margin: 2px 0 0;
  border-radius: 0;
  accent-color: #F7F7F7;
}
.approach-news_consent:hover { color: #efeee1d1; }

/* --- the light variant, for the article page -------------------------------------------------
   Same block, same classes, no background. The media / grad / scrim layers are deleted rather than
   hidden — in the Designer those are children you remove, and hiding them in CSS would leave three
   absolutely-positioned divs on every page for nothing.

   data-theme flips to light on the section itself. The site's adaptive nav reads that attribute to
   decide its own colour, so leaving it "dark" over a white band would turn the nav dark for the
   height of this section.

   Everything below is a colour inversion of the dark version, nothing structural.
   -------------------------------------------------------------------------------------------- */
.section_approach-news.is-light {
  color: #0C0C0C;
  background-image: none;
  background-color: transparent;
  /* No rules top or bottom. On the dark version the background does the separating; here the
     section's own padding is enough, and two more hairlines on a page that already has one under
     the author card and one under the takeaways just adds ruling. */
}

.is-light .approach-news_title { color: #0C0C0C; }
.is-light .approach-news_desc  { color: #6B7280; }

.is-light .approach-news_field { border-bottom-color: #0C0C0C; }

.is-light .approach-news_input,
.is-light .approach-news_input.w-input { color: #0C0C0C; }
.is-light .approach-news_input::placeholder { color: #9CA3AF; }

.is-light .approach-news_submit,
.is-light .approach-news_submit.w-button { color: #0C0C0C; }
.is-light .approach-news_submit:hover { opacity: .6; }

.is-light .approach-news_consent { color: #6B7280; }
.is-light .approach-news_consent:hover { color: #0C0C0C; }
.is-light .approach-news_check { accent-color: #0C0C0C; }

/* --- "By" before the name ---------------------------------------------------------------------
   Taken from the Figma article header, where the byline reads "By Georgia Rust, Rodrigo Davies" at
   the same weight and colour as the name itself — the prefix is part of the sentence, not a label
   attached to it. Ours already runs name + role on one line, so this only adds the word.

   A real span rather than a ::before on the name: this is copy, and copy in a pseudo-element cannot
   be selected, searched or read out.
   ---------------------------------------------------------------------------------------------- */
.team-member-by {
  font-weight: 500;
  letter-spacing: -.01em;
  /* inherit, not the ink token: the name beside it renders at #000, and a hard-coded #0C0C0C would
     leave "By" a shade off the word it belongs to. Same mismatch as the author bio. */
  color: inherit;
}

/* ---------------------------------------------------------------------------------------------
   12. PAGE CONTAINER WIDTH — reverted, on purpose
   I widened this template to 24px margins to match Figma's 1392px container. That was measured
   correctly and was still the wrong call, because it made the article WIDER THAN THE INSIGHTS LIST
   IT SITS UNDER — 1392 against 1328 — so moving from the index to a post shifted the page.

   Counted across the site, .padding-global is not a universal container at all:
       home, careers                       0 uses  (their own geometry)
       work, talk, growth, legal           1 use
       insights list                       5 uses
       insights single                     2 uses
   Changing it would move five pages and leave home and careers where they are, so it cannot
   deliver "the same everywhere" on its own.

   The template therefore keeps the site's 56px inset. Widening the whole site is a real option —
   /insights, /work, /talk, /growth and /legal would all go to 1392 — but that is a deliberate
   site-wide change to the class in the Designer, not something a typography pass should smuggle in.
   --------------------------------------------------------------------------------------------- */


/* ---------------------------------------------------------------------------------------------
   13. ONE TYPE SCALE
   Counted on the rendered page: 16 distinct sizes and 3 families against Figma's 9 and 2.

   Ours:  45.5 · 34 · 29 · 26.8 · 23.8 · 17.9 · 16.1 · 16 · 15.7 · 14 · 13 · 12 · 11.8 · 11 · 10.5
   Figma: 90 · 64 · 46 · 32 · 24 · 18 · 16 · 14 · 12

   The problem is not the number of steps, it is that five of ours sit between 14 and 18 and five
   more between 10.5 and 13. Nobody can tell 15.7 from 16 from 16.1 — they are not decisions, they
   are the residue of em chains resolving against different parents. That reads as "lots of
   different sizes" precisely because none of the differences mean anything.

   In-scope scale, seven steps:
       12  micro labels, uppercase      (category, QUICK TAKE AWAYS, Read More)
       13  rail navigation              (TOC links, back link)
       14  meta and UI                  (byline, author links, consent, fine print)
       18  body                         (17.9)
       27  article h2                   (26.8)
       34  section headings             (newsletter title)
       45  h1

   The small band is set in PIXELS on purpose. Every stray value above came from an em resolving
   against a parent that had itself been scaled; fixing the sizes without fixing the mechanism just
   moves the drift somewhere else. Labels are UI, not prose — they do not need to ride the article's
   fluid scale.

   OUT OF SCOPE, deliberately: 29px (nav), 23.8 / 16 / 11 / 0px (footer). Those are site-wide
   components — changing them from a template stylesheet would move every page on the site.
   --------------------------------------------------------------------------------------------- */

/* 14 — meta and UI */
.author-card__links      { font-size: 14px; }
.toc-sidebar .text-size-large-2 { font-size: 14px; line-height: 1.4; }   /* was 16.1 */

/* 12 — micro labels */
.takeaway-wrapper .text-medium.specialty { font-size: 12px; }            /* was 11.8 */
.section.is-blog .button-text-small,
.section.is-next .button-text-small      { font-size: 12px; }            /* was 10.5 */

/* The third family. TWK Ghost survives on the CTA banner because the earlier rule was scoped to
   the takeaway wrapper; this catches every .specialty in the article. Harvey Serif stays — that is
   the display face and the newsletter title is meant to use it. */
.section.is-blog .text-medium.specialty {
  font-family: var(--font-family--caption, "ABC Diatype", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif);
}

/* ---------------------------------------------------------------------------------------------
   14. THE WHITEPAPER BLOCK — the inline note pattern
   Replaces a floating card mid-article with the shape the Figma piece uses for its own mid-read
   sign-up: hairline, a coloured tile on the left, one sentence and an underlined link on the
   right, hairline. It interrupts the column without breaking out of it.

   It also fixes a real bug. All three text elements carry .text-color-white while the block itself
   has no background — transparent over a white page. The image sits at 410→592 and the text at
   616→826, so nothing is behind the words: they were white on white. Only the tile was visible.
   --------------------------------------------------------------------------------------------- */
.cta-banner {
  border-top: 1px solid #E5E7EB;
  border-bottom: 1px solid #E5E7EB;
  padding: 1.6em 0;
  margin: .6em 0;
}

/* Grid, not flex. The block has three children — tile, text, link — and as a flex row the link
   lands in a third column beside the sentence instead of under it. The reference puts the link on
   the next line, still in the text column, so the tile spans both rows. */
.cta-banner .customer-mini {
  display: grid;
  grid-template-columns: clamp(140px, 22%, 200px) minmax(0, 1fr);
  grid-template-rows: auto auto;
  column-gap: clamp(20px, 3vw, 34px);
  row-gap: .45em;
  align-items: start;
  align-content: center;
  background: none;
  border-radius: 0;
  padding: 0;
  height: auto;
}
.cta-banner .zoom-image-link          { grid-column: 1; grid-row: 1 / 3; align-self: center; }
.cta-banner .customer-mini-text       { grid-column: 2; grid-row: 1; }
.cta-banner .customer-quote-follow-link { grid-column: 2; grid-row: 2; }

/* The tile. Fixed width so the sentence beside it keeps a sane measure; the image fills it. */
.cta-banner .zoom-image-link {
  border-radius: 0;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  display: block;
}
.cta-banner .zoom-image-link img {
  width: 100%; height: 100%;
  object-fit: cover;
  border-radius: 0;
  display: block;
}

.cta-banner .customer-mini-text {
  flex: 1 1 auto;
  display: block;
  min-width: 0;
}

/* White text on a white page — the class says .text-color-white and nothing sits behind it.
   The title carries three classes (.text-medium.specialty.text-color-white, 0,3,0), so a two-class
   override loses to it and it stays invisible. Third time this exact trap has bitten on this page:
   .text-color-white is always applied alongside other classes, never alone. */
.cta-banner .text-medium.specialty.text-color-white,
.cta-banner .arrow-link-text.text-color-white,
.cta-banner .text-color-white { color: #0C0C0C; }

.cta-banner .text-medium.specialty {
  font-size: var(--font-size--medium);
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: -.01em;
  margin-bottom: .15em;
}

.cta-banner .paragraph {
  font-size: var(--font-size--medium);
  line-height: 1.5;
  color: #6B7280;
}

/* The call to action becomes an underlined link in the flow, not a button parked in a third
   column — same move as the "Sign up here." in the reference. */
.cta-banner .customer-quote-follow-link {
  display: block;
  height: auto;
  padding: 0;
  margin-top: .5em;
}
.cta-banner .arrow-link { display: inline-flex; }
.cta-banner .arrow-link-text {
  font-size: var(--font-size--medium);
  color: #0C0C0C;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .18em;
  text-decoration-color: rgba(12, 12, 12, .35);
  transition: text-decoration-color .2s ease;
}
.cta-banner .arrow-link:hover .arrow-link-text { text-decoration-color: rgba(12, 12, 12, 1); }

@media (max-width: 560px) {
  .cta-banner .customer-mini { flex-direction: column; align-items: flex-start; }
  .cta-banner .zoom-image-link { flex: 0 0 auto; width: 60%; }
}

/* ---------------------------------------------------------------------------------------------
   15. THE H1 IN TWK GHOST
   Replaces: .heading-h1 { font-family: var(--font-family--primary) }  — ABC Diatype

   The face is already on the site as --_typography---specialty (Twkghost, falling back to Times
   New Roman, so it is a serif). Using the variable rather than naming the family keeps this
   pointing at whatever the token means later.

   The tracking has to change with the face. -.05em is a grotesk setting: on a serif at 45px in
   caps it closes the counters and the words start to knit together. -.015em keeps the tightness
   without that. Line-height goes from 1 to 1.05 for the same reason — a serif carries more weight
   below the baseline, so two lines at 1.0 nearly touch.
   --------------------------------------------------------------------------------------------- */
.section.is-blog .heading-h1 {
  font-family: var(--_typography---specialty);
  font-weight: 400;
  text-transform: none;   /* the global .heading-h1 rule uppercases; this is a headline, not a label */
  letter-spacing: -.02em; /* lowercase gives back the space caps were eating, so it can close up a touch */
  line-height: 1.06;
}

/* ---------------------------------------------------------------------------------------------
   16. GHOST AS THE SPECIALTY FACE, AND THE PAGE COLOUR
   Ghost replaces Harvey Serif as the specialty font — the token already points at it, but the
   newsletter title names "Harvey Serif 400 100" directly, so it does not follow the token. Using
   var() rather than a family name means the next swap needs no code change here.
   --------------------------------------------------------------------------------------------- */
.approach-news_title { font-family: var(--_typography---specialty); }

/* The page colour, taken from the Always-On page: --vx-bg is #F5F5F3, a warm off-white rather than
   pure white. It sits on html AND body because the site head pins both to #FFFFFF — html is what
   paints the canvas (so overscroll matches), and body carries a .body class whose own background
   would otherwise win on specificity. */
html,
body.body,
body { background-color: #FFFFFF; }

/* Anything that was white ON white is now white on off-white, which shows. The frosted careers
   card and the hairlines were picked against #FFFFFF. */
.section.is-blog,
.section.is-next,
.section_approach-news.is-light { background-color: transparent; }


/* ---------------------------------------------------------------------------------------------
   17. EMPTY IMAGE SLOTS
   Webflow already marks an image bound to an empty CMS field with .w-dyn-bind-empty and renders it
   at 0x0, so the <img> itself is invisible. The hole is the FRAME around it: .media-wrapper-2 keeps
   its box and paints rgba(127,127,127,.2) — measured 644x361 of flat grey mid-article.

   Hiding the wrapper rather than the image is therefore the fix. :has() is why this cannot be a
   class property: the wrapper has to react to the state of its own child.

   THUMBNAILS ARE THE EXCEPTION, and .media-rounded used to be in this list — which was wrong. A
   card with no image is not a card, and on the related-publications row it left two of three
   entries as a title floating over nothing. A thumbnail must always be there, so instead of
   hiding it, .media-rounded now carries the blue panel gradient as a permanent backdrop. That is
   set natively on the class in the Designer, not here, for two reasons: it needs no :has(), and
   this stylesheet only loads on the article template while the same thumbnails appear on
   /insights. A bound image is position:absolute, inset:0, object-fit:cover, so it covers the
   gradient completely — the fallback is only ever visible when there is nothing to cover it.

   Deliberately NOT hiding .w-dyn-bind-empty globally — some empty bindings are text that other
   rules already collapse, and a blanket rule would also catch elements where the empty state is
   meant to leave a gap.
   --------------------------------------------------------------------------------------------- */
.media-wrapper-2:has(img.w-dyn-bind-empty),
.zoom-image-link:has(img.w-dyn-bind-empty) {
  display: none;
}


/* ---------------------------------------------------------------------------------------------
   18. TAKEAWAYS THAT ARE NOT THERE
   Four of the eight live posts have no Quick Take Aways. The panel still rendered: a hairline, the
   label "Quick Take Aways", and nothing under it — a heading announcing an empty list.

   Webflow marks the empty rich text itself (.take-aways.w-dyn-bind-empty), so the whole text block
   can go and the share row above it stays. Scoped to .takeaway-wrapper because .customer-mini-text
   is also used by the whitepaper banner further down the article.

   Checked against every live post rather than the one I had open: content-in-establishing-your-brand,
   effective-digital-prospecting, the-secret-sauce-... and next-phase all hit this.
   --------------------------------------------------------------------------------------------- */
.takeaway-wrapper .customer-mini-text:has(.take-aways.w-dyn-bind-empty) {
  display: none;
}


/* ---------------------------------------------------------------------------------------------
   19. SOURCES THAT ARE NOT THERE
   Same shape as 18, one section further down. Every one of the twelve live posts carries the
   heading "The Sources used in this Article:" — it is static markup in the template, not a bound
   field — but four have nothing under it, so you get a 1.9em heading announcing an empty list:
   content-in-establishing-your-brand, effective-digital-prospecting, next-phase and
   nice-to-meet-you-again.

   The article template also has a SECOND body rich text between the first one and the CTA banner
   (it carries the FAQ on always-on-marketing-examples). That one is empty on five posts — the same
   four plus the-secret-sauce-to-effective-advertising, whose sources are filled. It has no heading
   of its own, so it was already collapsing to zero height; the rule below just makes that explicit
   rather than relying on an empty box happening to take no space.

   The heading and the rich text are siblings inside .toc-article-text-wrap, so the WRAPPER is what
   has to go — hiding the rich text alone leaves the heading behind, which is the whole problem.
   Scoped with the child combinator, and it is deliberately not limited to the sources block: the
   article template has a second body rich text further up that is empty on those same posts, and
   an empty .toc-article-text-wrap has no reason to hold space anywhere. The wrap around the real
   article body has a filled rich text, so it never matches.

   Checked: the sources heading is NOT inside [data-toc-content], so hiding it cannot leave an
   orphaned entry in the contents rail pointing at something that is no longer rendered.
   --------------------------------------------------------------------------------------------- */
.toc-article-text-wrap:has(> .toc-article-text.w-dyn-bind-empty) {
  display: none;
}


/* =============================================================================================
   20. RUNWAY PASS
   The single, restyled after runway.com/news/* — ported from the validated lab build at
   insight-lab/runway.html. Appended as one section rather than woven through the sheet: every
   rule here overrides an earlier register by cascade order (same selector, later wins), so the
   old design is still readable above and this pass can be lifted out in one cut.

   Structure is untouched. The head is a flex column, so the reorder is pure `order`; the rails
   and panels already exist. What changes is the registers:

     head      centered; category · date on top as the quiet meta line, then the 50px/1.0/-0.04em
               sentence-case headline in the ONE grotesk (not Ghost - that is half of what makes
               the Runway read), then the byline. Standfirst and divider go - Runway's head is
               headline + meta, nothing else.
     read      18/1.25/-0.02em in #404040, h2 28/1.0/-0.04em ink - size hierarchy at constant
               weight 400.
     rails     the customer-template voice: 11px BOLD uppercase #7c7c7c labels, 14px items at
               75% ink, active = full ink.
     related   the black band: #0C0C0C, 36px sentence-case heading, card titles flip to light.

   Values are px on purpose: the article body base is clamp(14px, --size-font, 18px) and the
   Osmo scale is capped at 1440, so the effective base is a constant 14px - px and em are the
   same thing here, and px is what was measured on the reference.
   ============================================================================================= */

/* ---- head ---- */
.section.is-blog .article-head {
  align-items: center;
  text-align: center;
}
.section.is-blog .article-head > .news-category-read { order: -2; margin-bottom: 26px; }
.section.is-blog .article-head > .heading-h1 { order: -1; }
.section.is-blog .article-head > .team-member { order: 0; margin-top: 16px; }
.section.is-blog .article-head > .spacer-50,
.section.is-blog .article-head > .text-medium,
.section.is-blog .article-head > .divider-2 { display: none; }
.section.is-blog .article-head > .spacer-305 { height: 56px; }

/* Overrides the specialty-font rule in section 16 by cascade order. The one-grotesk headline is
   half of the Runway read; Ghost stays available for wherever the brand wants it next. */
.section.is-blog .heading-h1 {
  font-family: var(--font-family--primary, 'ABC Diatype', 'Helvetica Neue', Arial, sans-serif);
  font-weight: 400;
  font-size: 50px;
  line-height: 1;
  letter-spacing: -0.04em;
  text-transform: none;
  color: #0C0C0C;
  max-width: 790px;
  text-wrap: balance;
}

/* category · date becomes the lone quiet line above the headline - Runway's 13px date register */
.news-category-read .caption-2 {
  font-size: 13px;
  letter-spacing: -0.02em;
  text-transform: none;
  color: rgba(12, 12, 12, 0.5);
}

/* byline keeps name + role, loses the avatar: Runway's head carries no photograph */
.section.is-blog .article-head .team-member-image { display: none; }

/* ---- the read ---- */
.toc-article-text {
  font-size: 18px;
  line-height: 1.25;
  letter-spacing: -0.02em;
  color: #404040;
}
.toc-article-text > p,
.toc-article-text > ul,
.toc-article-text > ol,
.toc-article-text > figure { margin: 0 0 20px; }
.toc-article-text > h2 {
  font-size: 28px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.04em;
  color: #0C0C0C;
  margin: 52px 0 16px;
}
.toc-article-text-wrap > h2 {
  font-size: 28px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.04em;
  color: #0C0C0C;
}
.toc-article-text a { color: #0C0C0C; }

/* ---- rails: the customer-template voice ---- */
.toc-sidebar .label,
.toc-sidebar .title-label-wrap {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: normal;
  text-transform: uppercase;
  color: #7c7c7c;
}
[data-toc-item] {
  font-size: 14px;
  line-height: 1.3;
  letter-spacing: -0.03em;
  color: #0C0C0C;
  opacity: 0.75;
  transition: opacity 0.2s;
}
[data-toc-item]:hover,
[data-toc-item][data-toc-status="active"] { opacity: 1; }

/* takeaways panel joins the same register: the old white-on-dark text classes flip to ink */
.takeaway-wrapper .customer-mini-text {
  font-size: 14px;
  line-height: 1.3;
  letter-spacing: -0.03em;
}
.takeaway-wrapper .text-color-white,
.takeaway-wrapper .take-aways { color: rgba(12, 12, 12, 0.75); }
.takeaway-wrapper .take-aways li { margin-bottom: 12px; }

/* ---- related: the black band ----
   Overrides the transparent background from section 16 by cascade order. Card titles and meta
   were restyled site-side to the rw-* registers, which are ink - on the band they flip light. */
.section.is-next {
  background-color: #0C0C0C;
  padding-top: 96px;
  padding-bottom: 96px;
}
.section.is-next .heading-h1,
.section.is-next .heading-section {
  font-family: var(--font-family--primary, 'ABC Diatype', 'Helvetica Neue', Arial, sans-serif);
  font-weight: 400;
  font-size: 36px;
  line-height: 1;
  letter-spacing: -0.04em;
  text-transform: none;
  color: #F7F7F7;
}
.section.is-next .rw-card-title { color: #F7F7F7; }
.section.is-next .rw-meta { color: rgba(247, 247, 247, 0.55); }
.section.is-next .caption-2 { color: rgba(247, 247, 247, 0.55); }

/* ---- 20b. the diff pass ----
   Measured lab against staging element by element after the first port; these are the deltas
   that survived. Each rule names what it kills. */

/* The read h2s came through in uppercase - the heading class carries a transform the first pass
   never addressed. Sentence-case is the register. */
.toc-article-text > h2,
.toc-article-text-wrap > h2 { text-transform: none; }

/* The contents items rendered in the template's purple link colour - the same purple that cost
   three wrong diagnoses earlier in this project. A heavier selector outranks whatever link class
   carries it. */
.toc-sidebar a[data-toc-item] {
  color: #0C0C0C;
  opacity: 0.75;
}
.toc-sidebar a[data-toc-item]:hover,
.toc-sidebar a[data-toc-item][data-toc-status="active"] { opacity: 1; }

/* The hero ran full width with square corners. The lab hero: 690px, centred, r3, 3:2. Scoped to
   the 4:3 variant, which is what the template uses above the article - mid-article figures keep
   their own sizing. */
.section.is-blog .media-wrapper-2.is-4-3 {
  max-width: 690px;
  margin: 0 auto 56px;
  border-radius: 3px;
  overflow: hidden;
  aspect-ratio: 3 / 2;
}
.section.is-blog .media-wrapper-2.is-4-3 img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The takeaways label still spoke Ghost at 12px. It joins the panel-label register - and the
   font-family override matters as much as the size, because .specialty IS the Ghost binding. */
.takeaway-wrapper .text-medium.specialty {
  font-family: var(--font-family--caption, 'ABC Diatype', 'Helvetica Neue', Arial, sans-serif);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: normal;
  text-transform: uppercase;
  color: #7c7c7c;
}
.takeaway-wrapper .take-aways li {
  color: rgba(12, 12, 12, 0.75);
  letter-spacing: -0.03em;
  font-size: 14px;
  line-height: 1.3;
}

/* The back link: the lab crumb register - ink at 40%, full at hover. */
.toc-back {
  font-size: 14px;
  color: #0C0C0C;
  opacity: 0.4;
  transition: opacity 0.2s;
}
.toc-back:hover { opacity: 0.7; }

/* The author card never joined the furniture family: bio was riding the article base at 17.85px
   black. Lab register: 13px muted on 1.5. */
.author-card__bio {
  font-size: 13px;
  line-height: 1.5;
  letter-spacing: normal;
  color: #6B7280;
}
.author-card__links a { font-size: 13px; color: #6B7280; }
.author-card__links a:hover { color: #0C0C0C; }

/* The sources block drops from a 28px section heading to the small cap register - it is
   furniture, not a chapter. :last-of-type is safe because the sources wrap is the final
   .toc-article-text-wrap in the article; the FAQ wrap precedes it. */
.toc-article-text-wrap:last-of-type > h2 {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: normal;
  text-transform: uppercase;
  color: #7c7c7c;
  margin: 44px 0 8px;
  padding-top: 22px;
  border-top: 1px solid #DCDBD6;
}
.toc-article-text-wrap:last-of-type > .toc-article-text {
  font-size: 13px;
  line-height: 1.5;
  letter-spacing: normal;
  color: #6B7280;
}

/* Band cards follow the discover-more spec (24 / leading-none / no tracking / r3), not the index
   grid spec the shared rw classes carry. Scoped, so /insights keeps its own register. */
.section.is-next .rw-card-title {
  font-size: 24px;
  line-height: 1;
  letter-spacing: normal;
}
.section.is-next .rw-meta { font-size: 13px; letter-spacing: -0.26px; }
.section.is-next .media-rounded { border-radius: 3px; }

/* ---- 20c. two stragglers from the diff pass ----
   The takeaways label needed one more level of specificity to clear an earlier pass, and the
   sources selector was simply wrong: :last-of-type matches the last element of its TAG among
   siblings, and the author card - also a div - follows the sources wrap. :has(+ .author-card)
   names the relationship directly: the wrap immediately before the author card IS sources. */
.takeaway-wrapper .customer-mini-text .text-medium.specialty { color: #7c7c7c; }

.toc-article-text-wrap:has(+ .author-card) > h2 {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: normal;
  text-transform: uppercase;
  color: #7c7c7c;
  margin: 44px 0 8px;
  padding-top: 22px;
  border-top: 1px solid #DCDBD6;
}
.toc-article-text-wrap:has(+ .author-card) > .toc-article-text {
  font-size: 13px;
  line-height: 1.5;
  letter-spacing: normal;
  color: #6B7280;
}

/* ---- 20d. responsive step-downs ----
   The Runway pass was written in fixed px against the 1440 reference and shipped without a
   mobile trap: a 50px headline on a 375px screen. Two steps, matching the lab's own breakpoint
   and Webflow's 767. Body copy and card titles stay - 18 and 24 read fine small - it is the
   display registers and the band paddings that scale. */
@media (max-width: 991px) {
  .section.is-blog .heading-h1 { font-size: 42px; }
  .rw-cta-heading { font-size: 40px; }
}
@media (max-width: 767px) {
  .section.is-blog .heading-h1 { font-size: 34px; }
  .toc-article-text > h2,
  .toc-article-text-wrap > h2 { font-size: 24px; }
  .section.is-blog .media-wrapper-2.is-4-3 { margin-bottom: 36px; }
  .rw-cta-band { padding: 72px 20px; }
  .rw-cta-heading { font-size: 32px; }
  .rw-cta-sub { font-size: 15px; }
  .section.is-next { padding-top: 64px; padding-bottom: 64px; }
}

/* ---- 20e. three faults from the nice-to-meet-you-again walkthrough ----
   Found by eye on the one live post with no category and a portrait hero - the content states
   the always-on-examples post never exercises. */

/* A post without a category rendered ". July 21, 2026" - the separator survived its own
   category. Section 17's rule hides a separator BEFORE an empty caption; this is the mirror:
   the separator that directly FOLLOWS one. */
.news-category-read .caption-2:empty + .caption-2 { display: none; }

/* The byline hung left of the axis: .team-member is a flex row at full column width, so
   centering the text-align did nothing for its flex children. */
.section.is-blog .article-head .team-member { justify-content: center; }

/* The hero ignored its 3:2 - the wrapper still carries Webflow's padding-top ratio hack
   (a computed 743px of padding), and padding beats aspect-ratio. Kill the padding; the image
   inside is absolutely positioned and simply fills whatever box remains. */
.section.is-blog .media-wrapper-2.is-4-3 { padding-top: 0; }

/* ---- 20f. the contents rail, actually ----
   The link itself measured clean at 14px Diatype, which is why the numeric sweep passed - but
   every link wraps a span carrying Ghost at 25.9px, and the eye sees the span. The span inherits
   the link's register instead of keeping its own. The template's active bar (border-left plus
   14px of padding) goes with it: this rail signals the active section with opacity, not
   furniture. */
.toc-sidebar a[data-toc-item] span {
  font-family: inherit;
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
  letter-spacing: inherit;
}
.toc-sidebar a[data-toc-item],
.toc-sidebar a[data-toc-item][data-toc-status="active"] {
  border-left: 0;
  padding-left: 0;
}

/* ---- 20g. the CTA band on a wide screen ----
   The sub-line block inherits a global ~46em paragraph max-width and sat flush left inside the
   centered band - text-align centers text, not blocks. And the related section's tag was
   .text-dark on a black band: black on black. */
.rw-cta-sub { margin-left: auto; margin-right: auto; }
.section.is-next .section-tag { color: rgba(247, 247, 247, 0.55); }

/* ---- 20h. the breadcrumb ----
   The lab head opens with a centred "Insights / Category" crumb; the port had kept the sidebar's
   back button instead. The crumb now leads the head (order -3, above the date line), the category
   moves out of the meta line and into the crumb, and the back button retires - one way home, not
   two. */
.section.is-blog .article-head > .rw-crumb { order: -3; }
.rw-crumb a,
.rw-crumb span,
.rw-crumb div {
  color: #0C0C0C;
  opacity: 0.4;
  text-decoration: none;
  transition: opacity 0.2s;
}
.rw-crumb a:hover { opacity: 0.7; }
/* a post without a tag would read "Insights /" - the bound block gets w-dyn-bind-empty, so the
   separator before it goes too */
.rw-crumb .w-dyn-bind-empty { display: none; }
.rw-crumb span:has(+ .w-dyn-bind-empty) { display: none; }

/* the category now lives in the crumb; the meta line keeps only the date */
.section.is-blog .news-category-read .caption-2:nth-child(-n+2) { display: none; }

/* the back button and its spacer retire from the rail */
.toc-sidebar .toc-back { display: none; }
.toc-sidebar .toc-back + .spacer-50 { display: none; }

/* ---- 20i. the head reads like the lab ----
   The lab head is crumb, headline, then ONE meta line: author and date together. The port had
   the date floating alone between crumb and headline. The author link and the date line moved
   into .rw-byline (a real move in the Designer, not CSS trickery), which slots under the h1.
   The old order rules for .team-member and .news-category-read as direct head children no longer
   match anything - kept above for the record, inert. */
.section.is-blog .article-head > .rw-byline { order: 0; }
.rw-byline .news-category-read { margin: 0; }
.rw-byline .team-member { justify-content: center; }
/* separate name-block and date with a middot, the lab's own separator */
.rw-byline .news-category-read::before {
  content: "\00B7";
  color: rgba(12, 12, 12, 0.5);
  font-size: 13px;
  margin-right: 8px;
}

/* ---- 20j. byline row, seated properly ----
   Three leftovers from the move: the 56px spacer-305 kept its DOM slot between the h1 and the
   byline row (order beats position only when set - it was not), the date wrapped because the
   moved block kept a width constraint, and the author link still claimed its old full column. */
.section.is-blog .article-head > .spacer-305 { order: 1; }
.rw-byline .news-category-read,
.rw-byline .caption-2 { white-space: nowrap; }
.rw-byline .team-member { width: auto; }

/* ---- 20k. the compact pass ----
   Measured on runway.com/news/introducing-runway-dev (desktop rules read from their stylesheet,
   not the pane - the pane's viewport collapses to 0 and serves mobile values). Their head rhythm:
   crumb, 24 down to a 50px title, 14 down to the 13px grey meta, 32 down to the hero - and the
   hero sits INSIDE the 730px text column at 16:9, not on its own wider stage. Then the read opens
   with a lede: the first paragraph at 24/1.15 before body copy drops to 18. Ours ran crumb 26,
   byline 16, a 56px spacer, and a 690px 3:2 hero - looser at every joint. */
.section.is-blog .article-head > .rw-crumb { margin: 0 0 24px; }
.section.is-blog .article-head > .heading-h1 { margin: 0; }
.section.is-blog .article-head > .rw-byline { margin: 14px 0 32px; }
.section.is-blog .article-head > .spacer-305 { display: none; }
.section.is-blog .media-wrapper-2.is-4-3 {
  max-width: 730px;
  aspect-ratio: 16 / 9;
  margin: 0 auto 48px;
}

/* the lede: only when the read actually opens with a paragraph - a post that starts with an h2
   gets no false promotion */
.toc-article-text > p:first-child {
  font-size: 24px;
  line-height: 1.15;
  letter-spacing: -0.18px;
}
@media (max-width: 991px) {
  .toc-article-text > p:first-child { font-size: 22px; letter-spacing: -0.54px; }
}
@media (max-width: 767px) {
  /* restate the mobile hero margin: 20d set it, but this pass sits later in the cascade */
  .section.is-blog .media-wrapper-2.is-4-3 { margin-bottom: 36px; }
}

/* ---- 20l. the token pass ----
   Every face this stylesheet names is now a style-guide variable, with the old literal stack as
   the var() fallback - the fallback is what the local lab renders with, since the Webflow
   variables only exist on the site. Headings ride --font-family--primary, the 11px cap labels
   ride --font-family--caption; the newsletter band classes were rewired natively in the Designer.
   Change a face on the style-guide page and all of it follows. */

/* ---- 20m. the autofill patch ----
   Chrome paints its own background over an autofilled input - a dark slab on this band. There is
   no clean way to restyle it: the box-shadow inset trick needs a solid colour and this band is a
   gradient. The endless background-color transition postpones Chrome's paint indefinitely, and
   the text-fill keeps the typed value readable while it does. */
.approach-news_input:-webkit-autofill,
.approach-news_input:-webkit-autofill:hover,
.approach-news_input:-webkit-autofill:focus {
  /* clip Chrome's forced background to the glyphs themselves - newer Chrome ignores the
     transition delay, but a background clipped to text has nothing left to show */
  -webkit-background-clip: text;
  background-clip: text;
  transition: background-color 9999999s ease-in-out 0s;
  -webkit-text-fill-color: #F7F7F7;
  caret-color: #F7F7F7;
}
