/* ============================================================
   Editorial routes — Legal Insights, Case Studies, profiles, privacy

   These pages did not exist before: everything on this site linked out to
   `yingke.com.au`, which is being taken down. They are built from the same
   vocabulary the three original routes settled on, so the site reads as one
   thing rather than as a core plus a content annexe:

     - a pigment ground with a progressive frost on the left, from four static
       images (one sharp, three pre-blurred) — never a live blur;
     - hairlines that run from a label out to the margin;
     - tracked small-caps labels in the rust accent;
     - one serif, and no second typeface for emphasis;
     - grained paper below the opening, never a flat fill.
   ============================================================ */

.editorial-page {
  --chrome-rail: 1400px;
  --gutter: max(40px, calc((100vw - 1400px) / 2));
  --wall: #f5f3ec;
  --ink: #1b1c19;
  --body: #35332e;
  --muted: #625d55;
  --accent: #52281b;
  --label: #6f5529;
  --rule: rgba(28, 26, 24, 0.16);
  --grain: url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.45'/%3E%3C/svg%3E");
  background-color: var(--wall);
  background-image: var(--grain);
  background-size: 190px 190px;
  background-attachment: fixed;
  background-blend-mode: soft-light;
}

/* ---- opening ---- */

.ed-opening {
  --field-focus: 100% center;
  position: relative;
  isolation: isolate;
  overflow: hidden;
}

.ed-opening__field,
.ed-opening__frost,
.ed-opening__settle,
.ed-opening__masthead {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.ed-opening__field {
  z-index: -3;
  background: var(--field) var(--field-focus) / cover no-repeat;
}

.ed-opening__field::after {
  content: "";
  position: absolute;
  inset: 0;
  opacity: 0.15;
  mix-blend-mode: soft-light;
  background-image: var(--grain);
  background-size: 180px 180px;
}

.ed-opening__frost { z-index: -2; }

.ed-opening__frost span {
  position: absolute;
  inset: 0;
  display: block;
  background-position: var(--field-focus);
  background-repeat: no-repeat;
  background-size: cover;
}

.ed-opening__frost span:nth-child(1) {
  background-image: var(--field-soft);
  mask-image: linear-gradient(90deg, #000 0%, #000 44%, transparent 70%);
  -webkit-mask-image: linear-gradient(90deg, #000 0%, #000 44%, transparent 70%);
}
.ed-opening__frost span:nth-child(2) {
  background-image: var(--field-softer);
  mask-image: linear-gradient(90deg, #000 0%, #000 30%, transparent 56%);
  -webkit-mask-image: linear-gradient(90deg, #000 0%, #000 30%, transparent 56%);
}
.ed-opening__frost span:nth-child(3) {
  background-image: var(--field-softest);
  mask-image: linear-gradient(90deg, #000 0%, #000 16%, transparent 42%);
  -webkit-mask-image: linear-gradient(90deg, #000 0%, #000 16%, transparent 42%);
}

.ed-opening__frost::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg,
    rgba(248, 246, 239, 0.42) 0%,
    rgba(248, 246, 239, 0.28) 26%,
    rgba(248, 246, 239, 0.1) 54%,
    rgba(248, 246, 239, 0) 76%);
}

/* Nav legibility must not depend on which artwork sits behind it. */
.ed-opening__masthead {
  z-index: -1;
  height: calc(var(--header-height) + 34px);
  inset: 0 0 auto;
  background:
    linear-gradient(90deg, rgba(247, 245, 239, 0) 34%, rgba(247, 245, 239, 0.5) 78%, rgba(247, 245, 239, 0.62) 100%),
    linear-gradient(180deg, rgba(247, 245, 239, 0.84) 0%, rgba(247, 245, 239, 0.62) 46%, rgba(247, 245, 239, 0) 100%);
  /* The horizontal component has no vertical falloff of its own, so on its own it
     paints a uniformly opaque band the full height of this element and then stops
     dead — a white stripe straight across the artwork. Masking the whole layer
     vertically makes both components fade out together. */
  mask-image: linear-gradient(180deg, #000 0%, rgba(0, 0, 0, 0.62) 48%, transparent 100%);
  -webkit-mask-image: linear-gradient(180deg, #000 0%, rgba(0, 0, 0, 0.62) 48%, transparent 100%);
}

.ed-opening__settle {
  z-index: -1;
  background: linear-gradient(180deg, rgba(245, 243, 236, 0) 64%, rgba(245, 243, 236, 0.7) 86%, var(--wall) 100%);
}

@supports not ((mask-image: linear-gradient(#000, transparent)) or (-webkit-mask-image: linear-gradient(#000, transparent))) {
  .ed-opening__frost span { display: none; }
  .ed-opening__frost::after {
    background: linear-gradient(90deg,
      rgba(248, 246, 239, 0.93) 0%, rgba(248, 246, 239, 0.8) 26%,
      rgba(248, 246, 239, 0.48) 48%, rgba(248, 246, 239, 0.1) 70%);
  }
}

.ed-hero {
  min-height: clamp(360px, 30vw, 470px);
  position: relative;
  display: grid;
  align-content: center;
  padding: calc(var(--header-height) + clamp(44px, 4.2vw, 66px)) 0 clamp(40px, 3.8vw, 58px);
}

.ed-hero__inner { margin: 0 var(--gutter); }

/* the site's label-plus-rule device */
.ed-eyebrow {
  margin: 0 0 clamp(20px, 2.2vw, 30px);
  display: flex;
  align-items: center;
  gap: clamp(14px, 1.6vw, 24px);
  color: var(--accent);
  font-family: var(--sans);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.24em;
  line-height: 1.2;
  text-transform: uppercase;
}

.ed-eyebrow::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, rgba(82, 40, 27, 0.4), rgba(82, 40, 27, 0.08) 62%, rgba(82, 40, 27, 0));
}

.ed-hero h1 {
  max-width: 19ch;
  margin: 0;
  color: var(--ink);
  font-family: var(--serif);
  font-size: clamp(44px, 5.2vw, 82px);
  font-weight: 400;
  letter-spacing: -0.03em;
  line-height: 0.96;
}

.ed-hero__lede {
  max-width: 54ch;
  margin: clamp(20px, 2vw, 28px) 0 0;
  color: var(--body);
  font-family: var(--serif);
  font-size: clamp(17px, 1.35vw, 21px);
  line-height: 1.5;
}

/* ---- index listing ---- */

.ed-list {
  padding: clamp(52px, 5vw, 76px) var(--gutter) clamp(96px, 9vw, 140px);
  position: relative;
  isolation: isolate;
}

.ed-list::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(1400px 700px at 88% -6%, rgba(118, 92, 110, 0.12), transparent 70%),
    radial-gradient(1100px 560px at 6% 22%, rgba(150, 118, 80, 0.08), transparent 68%);
  /* The first ellipse is centred *above* this box, so without a mask it paints
     at near-peak from row 0 and butts the opening's finished paper — the same
     hard-line defect the header scrim had, measured at 6–7/255 right where the
     artwork is supposed to settle into the page. The wash has to arrive, not
     start. Fixed lengths, not percentages: this section is 21 rows tall, so a
     percentage ramp would be hundreds of pixels on the index and a few dozen on
     a short one. */
  mask-image: linear-gradient(180deg, transparent 0, #000 210px, #000 calc(100% - 140px), transparent 100%);
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 210px, #000 calc(100% - 140px), transparent 100%);
}

.ed-count {
  margin: 0 0 clamp(26px, 2.6vw, 36px);
  padding-bottom: 15px;
  border-bottom: 1px solid rgba(28, 26, 24, 0.5);
  color: var(--label);
  font-family: var(--sans);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

.ed-items { display: grid; }

/* An entry is a row, not a card. Rows keep one left edge down the whole page,
   which is the discipline the rest of the site is built on; a card grid would
   introduce a second rhythm for no reason. */
.ed-item {
  padding: clamp(26px, 2.6vw, 36px) 0;
  display: grid;
  grid-template-columns: 128px minmax(0, 1fr) 190px;
  gap: clamp(20px, 2.6vw, 46px);
  align-items: baseline;
  border-bottom: 1px solid var(--rule);
  color: inherit;
  text-decoration: none;
  transition: background-color 320ms ease;
}

.ed-item { position: relative; z-index: 0; }

/* The hover wash used to be painted on the row's own content box, so its edge
   fell exactly on the "1" of the date and exactly on the arrow — a lit panel with
   its contents pressed against both ends.
   A first fix widened the plate past the row with a negative inset. That worked
   visually and cost 18px of row `scrollWidth`, which the layout audit correctly
   flagged at all 11 viewports; an audit that has to be taught to ignore things
   stops being worth running.
   So the plate stays inside the row and loses its edges instead: the tint fades
   out over the last 30px at each end, so it is at full strength under the type
   and there is no line for anything to sit flush against. Same principle as the
   header scrim and the section washes — nothing on this page ends on a hard
   boundary. */
.ed-item::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 0;
  background-color: transparent;
  transition: background-color 320ms ease;
  mask-image: linear-gradient(90deg, transparent 0, #000 30px, #000 calc(100% - 30px), transparent 100%);
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 30px, #000 calc(100% - 30px), transparent 100%);
}

.ed-item:hover::before,
.ed-item:focus-visible::before { background-color: rgba(255, 253, 247, 0.66); }

.ed-item__date {
  color: var(--muted);
  font-family: var(--sans);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.ed-item h2 {
  /* Uncapped, the title ran to 1171px at 1440 while the blurb beneath it stopped
     at ~720 — a 450px notch down the right of every row. Capped to land on the
     blurb's own right edge instead.
     32ch, measured: this serif's `0` is narrow, so `ch` under-reports it badly —
     24ch resolved to ~530px, not the ~720 the unit implies. */
  max-width: 32ch;
  margin: 0;
  color: var(--ink);
  font-family: var(--serif);
  font-size: clamp(21px, 1.9vw, 30px);
  font-weight: 400;
  letter-spacing: -0.022em;
  line-height: 1.15;
  text-wrap: pretty;
}

/* 62ch is ~521px. The notch in the right of every row was never this measure's
   fault — 521px is correct for 16.5px prose — it was the title's, which ran the
   full 967px middle column at 1440 and so ended 450px past the blurb beneath it.
   The title is capped instead (below), and the two now share a right edge to
   within a line's rag. Capped in `ch` at both sizes so they track together as the
   type scales. */
.ed-item p {
  max-width: 62ch;
  margin: 10px 0 0;
  color: var(--body);
  font-family: var(--serif);
  font-size: clamp(14.5px, 1.05vw, 16.5px);
  line-height: 1.5;
}

.ed-item__go {
  justify-self: end;
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--accent);
  font-family: var(--sans);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  white-space: nowrap;
}

.ed-item__go svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  transition: transform 340ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* The arrow rests 4px inside the rail so its hover travel lands *on* the rail
   every hairline on the page shares, instead of overshooting it. */
.ed-item__go { padding-right: 4px; }

.ed-item:hover .ed-item__go svg,
.ed-item:focus-visible .ed-item__go svg { transform: translate(4px, -4px); }

/* ---- article ---- */

.ed-article {
  padding: clamp(56px, 5.4vw, 84px) var(--gutter) clamp(90px, 8.6vw, 132px);
  position: relative;
  isolation: isolate;
}

/* An article is prose plus a margin, not prose alone.
 *
 * It was one 620px measure pinned to the left gutter, which left ~850px of blank
 * paper down the whole right side of every one of the 27 article pages — for the
 * entire scroll, because the images were capped to the text measure too and could
 * not relieve it. The reviewer called it "a column that reads as having slipped
 * off the left edge"; the client put it less kindly.
 *
 * The prose does not move: it keeps the left rail the h1 above it stands on, which
 * is the page's spine and also the part of the artwork where the frost is
 * strongest. What changes is that the space beside it now carries the section, the
 * date and the article's own contents — and that figures and the takeaways summary
 * are released from the reading measure, so the wide column gets used by the two
 * things that want width.
 *
 * `:has()` so the privacy page, which shares this class and has no margin element,
 * stays a single column instead of reserving an empty track. Same guard as
 * `.pf-main`. */
.ed-article:has(> .ed-margin) {
  display: grid;
  grid-template-columns: clamp(196px, 18vw, 264px) minmax(0, 1fr);
  /* 10vw is 145px at 1440, and that number is derived rather than chosen. A 552px
     reading measure plus a 259px margin column cannot fill a 1,360px rail — 549px
     is left over, and the only real question is where it goes. Splitting it 145/404
     puts the text block's centre exactly on the page's centre (720) and makes the
     space to the left of the text (259 + 145) equal the space to its right (404).
     So the leftover reads as two matched margins instead of a void on one side. */
  gap: 0 clamp(36px, 10vw, 150px);
  align-items: start;
}

.ed-article:has(> .ed-margin) > .ed-article__body { grid-column: 2; grid-row: 1; }
.ed-article:has(> .ed-margin) > .ed-foot { grid-column: 2; grid-row: 2; }

/* The margin is on the *left*, and the prose to its right.
 *
 * The first version of this had them the other way round, and the client asked
 * whether the text would not be more comfortable on the right. It is, for three
 * reasons that all point the same way:
 *
 *   1. With the margin on the right, the two content blocks hugged opposite edges
 *      and left a ~550px hole between them. Adjacent, they read as one composition.
 *   2. The prose sits at x=363 instead of x=40, so its centre is 639 against a page
 *      centre of 720 — reading happens near the middle of a wide screen rather than
 *      hard against its left edge.
 *   3. It is what the rest of the site already does. `.pf-main` on the profiles is
 *      rail-then-body, and `.ed-item` on the listings is date-then-content. The
 *      article was the only editorial layout putting its labels on the right.
 *
 * The page's left rail stays occupied at x=40 — by the margin now instead of the
 * prose — so the article still shares the spine the nav, the hero eyebrow and the
 * footer stand on. And figures and the takeaways run out to x=1400, so the right
 * side carries content rather than being the new empty half.
 *
 * A side benefit: visual order now matches document order, which it did not before.
 *
 * Spans both rows and sticks, so it stays with the reader on a 1,800-word piece
 * instead of scrolling away in the first screen. */
.ed-margin {
  grid-column: 1;
  grid-row: 1 / span 2;
  position: sticky;
  top: calc(var(--header-height) + clamp(24px, 2.4vw, 38px));
}

.ed-margin__rows { margin: 0; }

.ed-margin__row {
  padding: 10px 0;
  display: grid;
  gap: 4px;
  border-bottom: 1px solid var(--rule);
}

.ed-margin__row:first-child { border-top: 1px solid rgba(28, 26, 24, 0.4); }

.ed-margin__row dt,
.ed-margin__label {
  margin: 0;
  color: var(--label);
  font-family: var(--sans);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

.ed-margin__row dd {
  margin: 0;
  color: var(--body);
  font-family: var(--serif);
  font-size: 14.5px;
  line-height: 1.4;
}

.ed-margin__contents { margin-top: clamp(26px, 2.6vw, 36px); }
.ed-margin__label { margin-bottom: 11px; }

/* Numbered, because the sections are read in order, but the numerals are set as
   quiet tracked figures rather than a browser list marker. */
.ed-margin__contents ol {
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: ed-contents;
  display: grid;
  gap: 9px;
}

.ed-margin__contents li {
  counter-increment: ed-contents;
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr);
  gap: 8px;
}

.ed-margin__contents li::before {
  content: counter(ed-contents, decimal-leading-zero);
  color: var(--label);
  font-family: var(--sans);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.08em;
  line-height: 1.9;
}

.ed-margin__contents a,
.ed-margin__row dd a {
  color: var(--body);
  font-family: var(--serif);
  font-size: 14px;
  line-height: 1.35;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color 200ms ease, border-color 200ms ease;
}

.ed-margin__contents a:hover,
.ed-margin__row dd a:hover {
  color: var(--accent);
  border-bottom-color: rgba(82, 40, 27, 0.34);
}

/* The reading measure lives on the text, not on the container.
   68ch of this serif measured 78-86 characters a line — its `0` is narrow, so the
   `ch` unit under-reports; 58ch lands at 66-72, the range long-form prose is
   actually set to. But capping the *container* at that measure also capped the
   figures and the takeaways summary, which is why the note below about images
   being "pulled to the measure's edge" was untrue: `width: min(100%, 100%)` is a
   no-op, and every photograph sat inside the text column. Those two now take the
   full width of the column they are in. */
.ed-article__body {
  color: var(--body);
  font-family: var(--serif);
  font-size: clamp(16.5px, 1.18vw, 19px);
  line-height: 1.66;
}

/* One measure, on the container, so nothing inside it can disagree with anything
   else — prose, headings, figures and the takeaways summary all share both edges.
 *
 * Two earlier attempts were wrong in opposite directions and both are worth
 * recording. First the measure was `58ch` on the container, which also capped the
 * figures. Then it moved onto the text elements so figures could break out to the
 * full column — 1,037px against 552px of prose. That looked like it was using the
 * width and was really just filling space I had left over: it gave one generic
 * stock photograph per article twice the presence of the writing, and it made the
 * figure share the text's left edge and the page's right edge, which is neither
 * one alignment nor the other.
 *
 * A length rather than `ch`, because `ch` resolves against each element's own
 * font-size: a shared `58ch` gave paragraphs 548px and the 27px headings 813px, so
 * the headings overhung the prose they introduced by 265px. `rem` resolves
 * identically everywhere and still tracks the reader's root font size. */
.ed-article__body {
  --measure: min(100%, 34.5rem);
  max-width: var(--measure);
}

.ed-article__body > * { margin: 0 0 1.05em; }
.ed-article__body > *:last-child { margin-bottom: 0; }

.ed-article__body h2,
.ed-article__body h3 {
  margin: 2.1em 0 0.7em;
  color: var(--ink);
  font-size: clamp(21px, 1.75vw, 27px);
  font-weight: 400;
  letter-spacing: -0.02em;
  line-height: 1.2;
}

.ed-article__body h3 { font-size: clamp(18px, 1.4vw, 22px); }
.ed-article__body h2:first-child,
.ed-article__body h3:first-child { margin-top: 0; }

.ed-article__body ul,
.ed-article__body ol { padding-left: 1.35em; }
.ed-article__body li { margin: 0 0 0.5em; }

.ed-article__body strong { font-weight: 600; }

.ed-article__body figure {
  margin: 2.4em 0;
  width: 100%;
}

.ed-article__body img {
  width: 100%;
  height: auto;
  display: block;
  filter: saturate(0.86) contrast(0.97);
}

/* ---- article footer + neighbours ---- */

/* The same `rem` measure the article body uses, for the same reason. In `ch` this
   hairline never agreed with the text above it: 631px against the body's 642.5px at
   1440, 624px at 1024, then 572 against 552 once the body moved to `rem` — always
   out by 10-20px, always at the one place on the page where a rule and a column of
   type are supposed to end together. */
.ed-foot {
  max-width: min(100%, 34.5rem);
  margin: clamp(54px, 5vw, 76px) 0 0;
  padding-top: clamp(24px, 2.4vw, 32px);
  border-top: 1px solid rgba(28, 26, 24, 0.42);
}

/* `.ed-foot p` below is (0,1,1) and later in the file, so it beat every
   declaration here: the label rendered 15px serif grey with no margin, which put
   the word NOTE hard against the first line of the disclaimer and made it read
   as the sentence's first word. Same specificity class, so it wins on order. */
.ed-foot .ed-foot__label {
  margin: 0 0 10px;
  color: var(--label);
  font-family: var(--sans);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.ed-foot p {
  margin: 0;
  color: var(--muted);
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.55;
}

.ed-near {
  padding: clamp(52px, 5vw, 76px) var(--gutter) clamp(90px, 8.6vw, 128px);
  border-top: 1px solid var(--rule);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(28px, 3.4vw, 64px);
}

.ed-near a {
  display: block;
  color: inherit;
  text-decoration: none;
}

.ed-near__dir {
  margin: 0 0 12px;
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--accent);
  font-family: var(--sans);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.ed-near__dir::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, rgba(82, 40, 27, 0.32), rgba(82, 40, 27, 0));
}

.ed-near h2 {
  margin: 0;
  color: var(--ink);
  font-family: var(--serif);
  font-size: clamp(19px, 1.6vw, 25px);
  font-weight: 400;
  letter-spacing: -0.02em;
  line-height: 1.2;
}

.ed-near a:hover h2 { color: var(--accent); }
/* `margin: 0` because this is a `<p>` sitting beside an `<h2>` in a two-column
   block: the UA's 17px top margin pushed it 5px off its neighbour's first
   baseline, which is the one alignment the block exists to make. */
.ed-near__empty { margin: 0; color: var(--muted); font-family: var(--serif); font-size: 17px; }

/* ---- responsive ---- */

@media (max-width: 1180px) { .editorial-page { --gutter: 28px; } }

/* Below 1080 there is not enough width for a prose measure and a margin side by
   side, so the margin stops being a margin and becomes a header block: the two
   facts on one line, the contents beneath. It is first in the document precisely
   so that it lands *above* the article when stacked — a contents list after the
   text it indexes would be useless, and screen readers get the same sensible
   order either way. */
@media (max-width: 1080px) {
  .ed-article:has(> .ed-margin) {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }

  .ed-article:has(> .ed-margin) > .ed-article__body,
  .ed-article:has(> .ed-margin) > .ed-foot {
    grid-column: 1;
    grid-row: auto;
  }

  /* Reset the desktop placement too, or the single column keeps a span-2 row. */
  .ed-margin { grid-column: 1; }

  .ed-margin {
    grid-column: 1;
    grid-row: auto;
    position: static;
    max-width: 40rem;
    margin-bottom: clamp(34px, 3.6vw, 48px);
  }

  .ed-margin__rows {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 clamp(20px, 3vw, 40px);
  }

  .ed-margin__row:nth-child(2) { border-top: 1px solid rgba(28, 26, 24, 0.4); }

  .ed-margin__contents ol {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 9px clamp(20px, 3vw, 40px);
  }
}

@media (max-width: 560px) {
  .ed-margin__rows,
  .ed-margin__contents ol { grid-template-columns: minmax(0, 1fr); }
  .ed-margin__row:nth-child(2) { border-top: 0; }
}

@media (max-width: 960px) {
  .ed-item { grid-template-columns: 108px minmax(0, 1fr); }
  .ed-item__go { display: none; }
  .ed-hero h1 { max-width: 100%; }

  /* The frost ramp is tuned for a hero whose type occupies the left ~40% and
     whose artwork owns the right. Below 960 the title cap is lifted because a
     44px serif cannot live in a narrow column — but the ramp was left where it
     was, so long titles crossed the 44% mark onto full-strength pigment and
     measured 2.42:1, and the lede reached bare paint at 3.97:1. Both are AA
     failures on the largest type on the page.
     The type is not squeezed to fit the frost; the frost is widened to cover the
     type, which is the only one of the two that preserves the design. */
  .ed-opening__frost span:nth-child(1) {
    mask-image: linear-gradient(90deg, #000 0%, #000 80%, transparent 100%);
    -webkit-mask-image: linear-gradient(90deg, #000 0%, #000 80%, transparent 100%);
  }
  .ed-opening__frost span:nth-child(2) {
    mask-image: linear-gradient(90deg, #000 0%, #000 56%, transparent 86%);
    -webkit-mask-image: linear-gradient(90deg, #000 0%, #000 56%, transparent 86%);
  }
  .ed-opening__frost span:nth-child(3) {
    mask-image: linear-gradient(90deg, #000 0%, #000 32%, transparent 64%);
    -webkit-mask-image: linear-gradient(90deg, #000 0%, #000 32%, transparent 64%);
  }
  .ed-opening__frost::after {
    background: linear-gradient(90deg,
      rgba(248, 246, 239, 0.5) 0%,
      rgba(248, 246, 239, 0.4) 40%,
      rgba(248, 246, 239, 0.24) 72%,
      rgba(248, 246, 239, 0.08) 100%);
  }
}

@media (max-width: 680px) {
  .editorial-page { --gutter: 20px; }
  /* `cover` crops hard horizontally at phone width, so the focal point decides
     whether the hero shows the painting or an empty corner of it. The two
     artworks are mirrored — measured chroma puts the insights field's pigment at
     78-100% of its width and the case-studies field's at 0-60% — so one shared
     value cannot serve both. The old flat `16% center` landed on the insights
     field's empty left third, and every insights page, every profile and the
     privacy page rendered a blank cream panel where the hero art should be.
     Each page names its own narrow focus next to the artwork it belongs to. */
  .ed-opening { --field-focus: var(--field-focus-narrow, 88% center); }
  .ed-opening__frost span:nth-child(1),
  .ed-opening__frost span:nth-child(3) { display: none; }
  .ed-opening__frost span:nth-child(2) { mask-image: none; -webkit-mask-image: none; }
  .ed-opening__frost::after {
    background: linear-gradient(180deg, rgba(248, 246, 239, 0.38), rgba(248, 246, 239, 0.26) 62%, rgba(248, 246, 239, 0.12));
  }
  .ed-item { grid-template-columns: minmax(0, 1fr); gap: 9px; }
  .ed-near { grid-template-columns: minmax(0, 1fr); }
}

/* A summary block, which is what the source's runs of <h6> actually were. On the
   page's own paper with hairlines above and below — not a tinted callout box,
   because a coloured panel would be the only one on the site. */
.ed-takeaways {
  margin: 2.2em 0;
  padding: clamp(20px, 1.8vw, 26px) 0;
  border-top: 1px solid rgba(28, 26, 24, 0.4);
  border-bottom: 1px solid var(--rule);
}

/* One column. The two-column version existed only because this block used to be
   given the full 1,037px column, where a single line was 110 characters; at the
   reading measure it does not need splitting, and the hairlines above and below are
   what give the summary its weight in any case. */

.ed-takeaways__label {
  margin: 0 0 14px;
  color: var(--label);
  font-family: var(--sans);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.17em;
  text-transform: uppercase;
}

.ed-takeaways ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 11px;
}

.ed-takeaways li {
  margin: 0;
  padding-left: 20px;
  position: relative;
  font-size: 0.94em;
  line-height: 1.55;
}

.ed-takeaways li::before {
  content: "";
  width: 5px;
  height: 5px;
  position: absolute;
  top: 0.62em;
  left: 2px;
  border-radius: 50%;
  background: var(--accent);
}

/* ---- profile ---- */

.pf-hero {
  position: relative;
  padding: calc(var(--header-height) + clamp(46px, 4.4vw, 70px)) 0 clamp(44px, 4.2vw, 64px);
}

.pf-hero__inner {
  margin: 0 var(--gutter);
  display: grid;
  grid-template-columns: clamp(200px, 22vw, 292px) minmax(0, 1fr);
  gap: clamp(30px, 4vw, 68px);
  align-items: end;
}

/* The portrait sits in the frosted half, so it reads as part of the ground
   rather than as a photo pasted over it. */
.pf-portrait {
  position: relative;
  aspect-ratio: 0.86;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.5);
  box-shadow: 0 18px 40px rgba(24, 20, 18, 0.14), inset 0 1px 0 rgba(255, 255, 255, 0.7);
}

.pf-portrait img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  object-position: center top;
  filter: saturate(0.86) contrast(0.97);
}

.pf-id h1 {
  /* Capped so a long name cannot run out of the frosted half and into the
     pigment, where it would lose contrast. */
  max-width: 17ch;
  margin: 0;
  color: var(--ink);
  font-family: var(--serif);
  font-size: clamp(38px, 4.4vw, 68px);
  font-weight: 400;
  letter-spacing: -0.032em;
  line-height: 0.98;
}

/* Some of these are genuine four-appointment stacks — the longest is 200
   characters. At 22px on a 30ch measure that is seven lines in the same face as
   the name above it, so the role out-massed the h1 and the page lost its
   hierarchy. A wider measure and a smaller size put the worst case at three
   lines and keep the name the largest thing on the page; the short roles, which
   are most of them, are unaffected. */
.pf-role {
  max-width: 42ch;
  margin: clamp(12px, 1.2vw, 18px) 0 0;
  color: var(--body);
  font-family: var(--serif);
  font-size: clamp(16px, 1.15vw, 19px);
  line-height: 1.4;
}

.pf-main {
  padding: clamp(50px, 5vw, 78px) var(--gutter) clamp(80px, 7.6vw, 116px);
  display: grid;
  grid-template-columns: clamp(200px, 22vw, 292px) minmax(0, 1fr);
  gap: clamp(30px, 4vw, 68px);
  align-items: start;
}

.pf-rail { display: grid; gap: clamp(24px, 2.4vw, 34px); }

.pf-rows { margin: 0; display: grid; }

/* Label above value, not beside it. The 66px label column plus its 14px gutter
   left the value 131px at 961px wide — against a 208px email address, which
   `overflow-wrap: anywhere` then broke mid-domain into `carrie.fan@yingkelaw` /
   `yer.com.au`, each half carrying its own underline so it read as two broken
   links. At 1440 the same arithmetic left 3.6px between the address and the end
   of its own hairline, where the rows below it have 99px.
   Stacked, the value gets the rail's full width at every size: no mid-word
   break, nothing flush to the rule, and the hairlines stop running a third of
   their length past their own content in the 768-960 band. */
.pf-row {
  padding: 11px 0;
  display: grid;
  gap: 5px;
  border-bottom: 1px solid var(--rule);
}

.pf-row:first-child { border-top: 1px solid rgba(28, 26, 24, 0.4); }

.pf-row dt {
  color: var(--label);
  font-family: var(--sans);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

.pf-row dd {
  margin: 0;
  color: var(--body);
  font-family: var(--serif);
  font-size: 14.5px;
  line-height: 1.4;
  /* `anywhere` was breaking addresses mid-domain. `break-word` keeps whole words
     together and only splits one that cannot fit on a line by itself, which for
     a stacked 292px rail is nothing we ship. */
  overflow-wrap: break-word;
}

.pf-row dd a { color: inherit; text-decoration: none; border-bottom: 1px solid rgba(82, 40, 27, 0.32); }
.pf-row dd a:hover { color: var(--accent); border-bottom-color: var(--accent); }

.pf-label {
  margin: 0 0 9px;
  color: var(--label);
  font-family: var(--sans);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

.pf-block ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; }

.pf-block li,
.pf-plain {
  margin: 0;
  color: var(--body);
  font-family: var(--serif);
  font-size: 14.5px;
  line-height: 1.45;
}

.pf-body { max-width: 66ch; }

/* There was no link rule for prose anywhere in either stylesheet, so every
   inline link in every article body and every profile rendered as plain body
   text — same colour, no underline, no weight. On the six profiles whose bio is
   the short fallback, "contact our Sydney office" is the only actionable thing
   on the page and it was invisible. Matches the rail's link treatment, which
   already did this correctly. */
.ed-article__body a,
.pf-body a,
.ed-foot a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid rgba(82, 40, 27, 0.34);
  transition: color 200ms ease, border-color 200ms ease;
}

.ed-article__body a:hover,
.pf-body a:hover,
.ed-foot a:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

/* A profile with no rail is a single column, not a column plus a 292px hole.
   Six of the 37 have no rail data; the grid was reserving the track anyway and
   indenting the bio 390px into open paper. */
.pf-main:not(:has(> .pf-rail)) { grid-template-columns: minmax(0, 1fr); }
.pf-body h2 { font-size: clamp(19px, 1.5vw, 24px); }

@media (max-width: 960px) {
  .pf-hero__inner,
  .pf-main { grid-template-columns: minmax(0, 1fr); }
  .pf-portrait { width: min(100%, 300px); }
  .pf-rail { max-width: 520px; }
}

/* Legislation names run long and contain no break opportunities — "Competition
   and Consumer (Industry Codes–Franchising) Regulation 2014" pushed the document
   past the viewport at narrow widths. Prose is allowed to break inside a word
   only as a last resort, which is what `anywhere` means here. */
.ed-article__body,
.ed-article__body li,
.ed-article__body p,
.ed-takeaways li,
.ed-item h2,
.ed-item p,
.ed-near h2 {
  overflow-wrap: anywhere;
}
