/* ═══════════════════════════════════════════════════════════════
   FLOWSYNERGY — article.css : the article shell (pillar guides + articles).
   Hero variant `resolve`; single reading column on the LEFT two-thirds with a
   sticky "Guides" spine in the left gutter. Extends site.css; redefines no chrome.
   Smallest font-size on this sheet: 12px.
   ═══════════════════════════════════════════════════════════════ */

/* ── hero: title + "what this resolves" readout, hero frame below ── */
.art-hero{position:relative; isolation:isolate; overflow:hidden; padding-top:clamp(44px,7vh,88px)}
.art-hero__plot{position:absolute; inset:0; width:100%; height:100%; z-index:-2; color:var(--sig); opacity:.22}
.art-hero__vign{position:absolute; inset:0; z-index:-1; background:radial-gradient(110% 80% at 82% 0%, rgba(133,224,255,.08), transparent 55%), linear-gradient(to top, var(--bg) 12%, rgba(8,9,11,.78) 55%, rgba(8,9,11,.40) 100%)}
.art-hero__grid{display:grid; grid-template-columns:minmax(0,1.55fr) minmax(300px,.8fr); gap:clamp(28px,4vw,72px); align-items:end}
/* min-width:0 is load-bearing, not tidying. This is a GRID ITEM, so it defaults to
   min-width:auto and will not shrink below its content's min-content width. The crumb
   inside it carries `white-space:nowrap`, which makes that min-content the whole page
   title -- so at 390 the item measured 492-778px inside a 350px track and pushed its own
   h1 off the screen. body{overflow-x:hidden} hid it from render_gate. */
.art-hero__title{min-width:0}
.art-hero__title h1{font-size:clamp(2.3rem,4.6vw,4.2rem); font-weight:800; letter-spacing:-.04em; text-wrap:balance; max-width:22ch; margin-bottom:clamp(18px,2.6vh,28px)}
.art-hero__title .eyebrow time{font-family:var(--mono); color:var(--txt-2); letter-spacing:.12em}
.art-hero .crumbs span{color:var(--txt-2)}
.art-hero .crumbs a{color:var(--dim)}
.art-hero__readout{gap:16px; animation:fadeUp .9s var(--ease) .18s both}
.kv{margin:0; display:grid; gap:0}
.kv div{display:grid; grid-template-columns:minmax(11ch,.55fr) 1fr; gap:14px; padding:11px 0; border-top:1px solid var(--line-struct)}
.kv div:first-child{border-top:0; padding-top:0}
.kv dt{font-family:var(--mono); font-size:12px; letter-spacing:.16em; text-transform:uppercase; color:var(--dim); padding-top:2px}
.kv dd{margin:0; font-size:13px; line-height:1.5; color:var(--txt-2)}
.art-hero__fig{margin-top:clamp(32px,5vh,64px)}
.art-hero__fig img{aspect-ratio:16/7; object-fit:cover}

/* R1-08: `.art-hero--aside` (valve-selection page build only) — no full-bleed hero band.
   The image sits as a portrait crop in the right column under the resolve readout; the
   title + answer span wider. The plain shell keeps the full-bleed figure. */
/* B4-01: the void here was never the image's height. The title sat `align-self:start` and
   the readout beside it `align-self:end` -- two columns anchored to opposite ends of one
   row, and the hole between them measured 856 x 581px on the flagship guide.
   This is the shape the hvac hero already proves: title over readout down the left, the
   image a tall crop holding the right column for the hero's whole height. Nothing is
   anchored to a far edge, so there is no gap for one to leave. */
.art-hero--aside .art-hero__grid{
  grid-template-columns:minmax(0,1.5fr) minmax(290px,.9fr); align-items:start;
}
.art-hero--aside .art-hero__title{grid-column:1; grid-row:1; align-self:start}
.art-hero--aside .art-hero__title h1{max-width:24ch; font-size:clamp(2.4rem,5vw,4.8rem)}
.art-hero--aside .art-hero__readout{grid-column:1; grid-row:2; align-self:start; margin-top:clamp(20px,2.8vh,34px)}
.art-hero__fig--side{
  grid-column:2; grid-row:1 / span 2; margin-top:0;
  display:flex; flex-direction:column; align-self:stretch;
}
.art-hero__fig--side img{flex:1; min-height:min(540px,56vh); height:100%; aspect-ratio:auto; object-fit:cover}

/* ── body: spine (left gutter) + prose on the left two-thirds; right gutter empty by design ── */
.art-body{
  max-width:var(--wide); margin-inline:auto; padding:clamp(40px,6vh,72px) var(--gut) 0;
  display:grid; grid-template-columns:clamp(200px,16vw,240px) minmax(0,1fr); gap:clamp(28px,4.5vw,80px);
  align-items:start;
}
.art-spine{padding-top:4px}
.art-spine ol{counter-reset:none}
.art-spine li a{padding-right:10px}
.art-spine li a .n{display:inline-block; min-width:2.4ch}
.art-spine__all{display:inline-block; margin-top:18px; padding:12px 0; font-family:var(--mono); font-size:12px; letter-spacing:.12em; text-transform:uppercase; color:var(--txt-2); border-bottom:1px solid var(--line-struct)}
.art-spine__all::after{content:" →"}

/* The body is INJECTED: the renderer emits plain <h2>, <p>, <table>, <figure>, <blockquote>, <ul>.
   Reading text sits at --measure; exhibits break the column to --exhibit. */
.art-body .prose{max-width:none; counter-reset:sec}
.prose > p,.prose > ul,.prose > ol:not(.steps),.prose > h3,.prose > h2,.prose > .caveat,.prose > dl{max-width:var(--measure)}
/* --exhibit is right for an object that NEEDS the extra width -- a wide table, a figure. A
   numbered ledger of prose does not: at --exhibit it framed 1,017px around 705px of text,
   three rows running, on nine pages. It sits between the measure and the exhibit. */
.prose > table,.prose > figure,.prose > .panel,.prose > blockquote,.prose > .tblwrap,.prose > .cells{max-width:var(--exhibit)}
/* B6-01: now declared on the component in site.css */
.prose > h2:first-child{margin-top:0; padding-top:0; border-top:0}
.prose h2::before{counter-increment:sec; content:"§" counter(sec,decimal-leading-zero); font-family:var(--mono); font-size:12px; letter-spacing:.12em; color:var(--sig); flex:none; font-weight:400; position:relative; top:-.25em}
.prose h2{text-wrap:balance}
.prose > .steps,.prose > figure,.prose > .panel,.prose > blockquote,.prose > table,.prose > .tblwrap{margin:clamp(26px,3.4vh,40px) 0}
.prose > .steps + p,.prose > figure + p,.prose > .panel + p,.prose > blockquote + p{margin-top:0}
.prose > .caveat + h2{margin-top:2.2em}

/* pull-quote → panel (the renderer emits <blockquote>) */
.prose blockquote{
  background:var(--bg-3); border:1px solid var(--line-struct); border-left:2px solid var(--sig); border-radius:var(--radius-frame);
  padding:clamp(18px,2vw,26px); font-size:15px; line-height:1.6; color:var(--txt);
}
.prose blockquote p{font-size:inherit; color:inherit}
.prose blockquote cite{display:block; margin-top:12px; font-style:normal; font-family:var(--mono); font-size:12px; letter-spacing:.12em; text-transform:uppercase; color:var(--sig)}
.prose .panel p{color:var(--txt)}

/* figures: photographs and table exhibits share the frame */
.prose figure{margin-left:0; margin-right:0; background:var(--bg-2); border:1px solid var(--line-struct); border-radius:var(--radius-frame); overflow:hidden}
/* The `filter:saturate(.82) contrast(1.06)` that used to be here is gone for the reason
   site.css records at length: grading happens ONCE, in design-system/images.py grade(),
   where it can be seen in the file on disk. This rule was a second grade stacked on the
   first and was missed when the site.css pair was retired. */
.prose figure img{width:100%; height:auto; display:block}
.prose figcaption{padding:12px 16px; border-top:1px solid var(--line-struct); font-family:var(--mono); font-size:12px; letter-spacing:.04em; color:var(--dim); line-height:1.6}
.prose figure.exhibit .tblwrap,.prose figure.exhibit > table{padding:clamp(14px,1.6vw,22px) clamp(16px,1.8vw,24px) 4px}
.prose figure.exhibit caption{text-align:left}

/* tables: a bare <table> from the renderer gets the standards-table treatment */
.prose table{width:100%; border-collapse:collapse; font-size:15px}
.prose th{text-align:left; font-family:var(--mono); font-size:12px; letter-spacing:.16em; text-transform:uppercase; color:var(--txt-2); font-weight:400; padding:0 16px 12px 0; border-bottom:1px solid var(--line-struct); vertical-align:bottom}
.prose td{padding:13px 16px 13px 0; border-bottom:1px solid var(--line-struct); vertical-align:top; color:var(--txt-2); line-height:1.5}
.prose td:first-child{font-family:var(--mono); font-size:13px; color:var(--txt); min-width:9ch}
.prose td:last-child,.prose th:last-child{padding-right:0}
.prose tr:last-child td{border-bottom:0}
.prose table.tbl{font-size:15px}
.prose .tbl td:first-child{white-space:normal; width:auto}

/* step list titles (no <h3> inside the list — heading rhythm is measured on real headings) */
/* .steps heading spellings are consolidated in site.css (A4-03) */

/* lists, definitions, keyboard focus */
.prose li::marker{color:var(--dim); font-family:var(--mono); font-size:.85em}
.prose dl{display:grid; grid-template-columns:minmax(12ch,.4fr) 1fr; gap:10px 18px}
.prose dt{font-family:var(--mono); font-size:13px; color:var(--txt)}
.prose dd{margin:0}

/* ── related strip (the renderer emits a.related-card > .rc-cat + .rc-title, up to 4) ── */
.related__grid{display:grid; gap:1px; background:var(--line-struct); border:1px solid var(--line-struct); border-radius:var(--radius-frame); overflow:hidden; grid-template-columns:repeat(4,1fr)}
.related__grid:has(> :nth-child(3):last-child){grid-template-columns:repeat(3,1fr)}
.related__grid:has(> :nth-child(2):last-child){grid-template-columns:repeat(2,1fr)}
.related__grid:has(> :only-child){grid-template-columns:1fr}
.related-card{background:var(--bg-2); padding:clamp(18px,2vw,26px); display:flex; flex-direction:column; gap:12px; min-width:0; position:relative}
.related-card::after{content:''; position:absolute; left:0; top:0; width:100%; height:2px; background:var(--sig); transform:scaleX(0); transform-origin:left; transition:transform .45s var(--ease)}
.related-card:hover{background:var(--bg-3)}
.related-card:hover::after{transform:none}
.rc-cat{font-family:var(--mono); font-size:12px; letter-spacing:.18em; text-transform:uppercase; color:var(--txt-2)}
.rc-title{font-family:var(--disp); font-size:clamp(1rem,1.25vw,1.2rem); font-weight:600; letter-spacing:-.02em; line-height:1.2; color:var(--txt); text-wrap:balance}

/* ── responsive ── */
@media (max-width:1180px){
  .art-hero__grid,.art-hero--aside .art-hero__grid{grid-template-columns:1fr; align-items:start}
  .art-hero--aside .art-hero__title{grid-row:auto}
  .art-hero__fig--side{grid-column:auto; grid-row:auto; max-width:var(--exhibit); margin-top:clamp(24px,3.4vh,40px)}
  .art-hero__fig--side img{aspect-ratio:16/9; min-height:0; flex:none; height:auto}
  .art-hero--aside .art-hero__title,.art-hero--aside .art-hero__readout{grid-column:auto; grid-row:auto}
  .art-hero__readout{max-width:var(--exhibit)}
  .art-body{grid-template-columns:minmax(0,1fr); gap:28px}
  .art-spine{border-bottom:1px solid var(--line-struct); padding-bottom:22px}
  .art-spine ol{display:grid; grid-template-columns:repeat(3,1fr); border-left:0; gap:0 18px}
  .art-spine li a{border-left:1px solid var(--line-struct)}
  .related__grid,.related__grid:has(> :nth-child(3):last-child){grid-template-columns:repeat(2,1fr)}
}
@media (max-width:720px){
  .art-hero{padding-top:32px}
  .art-hero__title h1{font-size:clamp(2rem,9vw,2.6rem)}
  .art-hero__fig img{aspect-ratio:4/3}
  .kv div{grid-template-columns:1fr; gap:4px}
  .art-spine ol{grid-template-columns:1fr}
  .related__grid,.related__grid:has(> :nth-child(3):last-child),.related__grid:has(> :nth-child(2):last-child){grid-template-columns:1fr}
  .prose h2{font-size:1.45rem}
  .prose table{font-size:13px}
  .prose figure.exhibit table{min-width:620px}
  .prose figure.exhibit table.tbl--narrow{min-width:0}
  .prose figure.exhibit .tblwrap{overflow-x:auto}
  .prose td{padding:11px 12px 11px 0}
}
@media (max-width:480px){
  /* R1-02: the wide service-condition matrix restacks as cards — first cell is the card
     head, every other cell is labelled by its column head via data-c. No sideways scroll. */
  .prose figure.exhibit table.tbl--wrap{min-width:0}
  .prose figure.exhibit:has(.tbl--wrap) .tblwrap{overflow-x:visible}
  .prose .tbl--wrap thead{display:none}
  .prose .tbl--wrap tr{display:block; padding:16px 0; border-bottom:1px solid var(--line-struct)}
  .prose .tbl--wrap td{display:block; border-bottom:0; padding:5px 0; min-width:0}
  .prose .tbl--wrap td:first-child{font-family:var(--mono); font-size:13px; color:var(--txt); padding:0 0 8px}
  .prose .tbl--wrap td[data-c]::before{content:attr(data-c); display:block; font-family:var(--mono); font-size:12px; letter-spacing:.14em; text-transform:uppercase; color:var(--dim); margin-bottom:2px}
}

/* ══ design review round 1 ═══════════════════════════════════════ */
/* B1-04: mono tabular numerals for a numeric table -- the language the homepage
   instrument already speaks, and the reason decimal points line up down a column. */
.prose .tbl--num td:not(:first-child),.prose .tbl--num th:not(:first-child){text-align:right}
.prose .tbl--num td:not(:first-child){font-family:var(--mono); font-variant-numeric:tabular-nums; font-feature-settings:"tnum" 1; color:var(--txt)}
@media (max-width:720px){
  /* B1-15: the last crumb printed the whole page title in caps above an h1 saying the
     same words -- nine lines of one sentence where vertical space is scarcest. */
  /* B1-15, retargeted: the article hero emits <span>s inside .crumbs, not <li>s, so the
     first version of this rule matched nothing and shipped doing nothing. `> :last-child`
     works whichever element the page uses. */
  .crumbs > :last-child{max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0}
}
@media (max-width:480px){
  /* B1-10: a pressure-temperature grid exists to be read ACROSS a row and DOWN a column.
     Restacked one value per line it is neither -- so this one keeps the <=720 scroll
     treatment, which is already built and already announces itself with a 'scroll' cue. */
  .prose figure.exhibit table.tbl--num{min-width:560px}
  .prose figure.exhibit:has(.tbl--num) .tblwrap{overflow-x:auto}
  .prose .tbl--num thead{display:table-header-group}
  .prose .tbl--num tr{display:table-row}
  .prose .tbl--num td{display:table-cell; padding:11px 12px 11px 0; white-space:nowrap}
  /* the scroll is announced, as it is at <=720: an unlabelled sideways scroll is a hidden one */
  .prose figure.exhibit:has(.tbl--num) .tblwrap{
    -webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 44px),transparent);
    mask-image:linear-gradient(90deg,#000 calc(100% - 44px),transparent);
  }
  .prose figure.exhibit:has(.tbl--num) .tblwrap::before{
    content:"scroll \2192"; display:block; font-family:var(--mono); font-size:12px;
    letter-spacing:.16em; text-transform:uppercase; color:var(--dim); padding-bottom:10px;
  }
  .prose .tbl--num td:first-child{padding:11px 12px 11px 0}
  .prose .tbl--num td[data-c]::before{content:none}
}

@media (max-width:1180px){
  /* C2: the spine becomes the article's only in-page navigation below 1180 and its rows were
     31px. The mono stays at the 12px floor; the box grows. */
  .art-spine li a{padding:14px 10px}
}


/* key-takeaways panel (run3-2026-09-16-a): the visible summary the article rubric and the 14 September
   presentation rule require before the first H2. Same ground and rule as .readout. */
.prose .takeaways{background:var(--bg-3); border:1px solid var(--line-struct); border-left:3px solid var(--sig); border-radius:var(--radius-frame); padding:clamp(16px,2vw,24px); margin:0 0 1.8em}
.prose .takeaways .k{display:block; font-family:var(--mono); font-size:12px; letter-spacing:.2em; text-transform:uppercase; color:var(--sig); margin-bottom:10px}
.prose .takeaways ul{margin:0; color:var(--txt); font-size:16px; line-height:1.55}
