/* ==================================================================
   EAWATER — POLISH LAYER
   Loaded after eaw.css. Fixes image sizing, typography and alignment.
   Kept separate so the base design system stays readable.
   ================================================================== */

/* ============================================================ IMAGES
   The bug: only placeholders had an aspect ratio. Real uploaded images
   rendered at their natural height, so a portrait photo next to a
   landscape one broke the whole row. Every image now fills a fixed box.
   ================================================================== */
.card img,
.card .ph,
.eco img,
.promo-card img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  object-position: center;
  background: var(--surface);
  display: block;
}

/* The homepage lead runs wider, so it gets a wider crop. */
.lead .lead-img img,
.lead .lead-img .ph { aspect-ratio: 3 / 2; }

/* Magazine and report covers are portrait — never crop those to landscape. */
.magrid img, .magrid .ph,
.card.cover img, .card.cover .ph { aspect-ratio: 3 / 4; object-fit: cover; }

/* Company logos must sit inside their box, not be cropped. */
.card.company img,
.company-logo { aspect-ratio: 3 / 2; object-fit: contain; background: #fff; padding: 10px; }

/* Person photos stay square. */
.card.person img, .card.person .ph { aspect-ratio: 1 / 1; object-fit: cover; }

/* Cards become equal-height columns so text baselines line up. */
.grid > .card { display: flex; flex-direction: column; }
.grid > .card .dek { margin-bottom: 0 }
.grid > .card .tags { margin-top: auto; padding-top: 12px }

/* Consistent gaps. The old grid used different gaps per breakpoint. */
.grid { gap: 30px 26px }
@media (max-width: 720px) { .grid { gap: 26px 20px } }

/* ======================================================== TYPOGRAPHY */
.card h3 {
  font-size: 18.5px;
  line-height: 1.28;
  letter-spacing: -.015em;
  margin: 6px 0 7px;
  /* Three lines then ellipsis, so a long headline cannot shove a card
     out of alignment with its neighbours. */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.card .dek {
  font-size: 14.8px;
  line-height: 1.55;
  color: var(--steel);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.card .kicker, .card .meta {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--steel);
  margin: 0 0 5px;
}
.card .meta { text-transform: none; letter-spacing: .04em; font-size: 11.5px; margin: 0 0 9px }

/* Body copy was inheriting an ambiguous colour. Make it explicit. */
.prose { color: var(--ink); font-size: 18px; line-height: 1.7; max-width: 68ch }
.prose p { margin: 0 0 1.15em }
.prose h2 { font-size: 24px; margin: 1.7em 0 .5em; letter-spacing: -.02em }
.prose h3 { font-size: 19.5px; margin: 1.5em 0 .45em }
.prose ul, .prose ol { margin: 0 0 1.15em; padding-left: 1.3em }
.prose li { margin: 0 0 .4em }
.prose img { margin: 1.8em 0; border-radius: var(--r) }
.prose a { text-decoration: underline; text-underline-offset: 2px }
.prose strong { font-weight: 600 }
.prose table { width: 100%; border-collapse: collapse; margin: 1.6em 0; font-family: var(--sans); font-size: 15.5px }
.prose th, .prose td { border: 1px solid var(--line); padding: 9px 11px; text-align: left }
.prose th { background: var(--surface); font-weight: 600 }

/* ========================================================= ALIGNMENT */
/* The article column was drifting. Lock the measure and the rhythm. */
.entrygrid { gap: 52px; padding: 34px 0 }
@media (min-width: 1000px) { .entrygrid { grid-template-columns: minmax(0, 1fr) 316px } }
.entrygrid > div > .block:first-child { margin-top: 0 }

.hubhead { padding: 34px 0 30px }
.hubhead h1 { margin-bottom: 12px }
.hubhead .lede { max-width: 62ch }

.section { padding: 44px 0 }
.section.tight { padding: 24px 0 }
.shead { display: flex; justify-content: space-between; align-items: baseline; gap: 20px;
  border-bottom: 2px solid var(--ink); padding-bottom: 10px; margin-bottom: 26px }
.shead h2 { margin: 0; font-size: 22px; letter-spacing: -.02em }
.shead a { font-family: var(--mono); font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; white-space: nowrap }

/* Tag rows were wrapping into a wall. Cap the visible height. */
.tags { display: flex; flex-wrap: wrap; gap: 6px; margin: 16px 0 0 }
.tag { font-family: var(--mono); font-size: 11px; letter-spacing: .04em; padding: 5px 10px;
  border: 1px solid var(--line); border-radius: var(--r); color: var(--steel); background: #fff }
.tag:hover { border-color: var(--blue); color: var(--blue); text-decoration: none }

/* Sidebar blocks share one rhythm instead of three. */
aside > * { margin-bottom: 24px }
aside > *:last-child { margin-bottom: 0 }
.cta { border: 1px solid var(--line); border-top: 3px solid var(--blue); padding: 18px; background: var(--surface) }
.cta h4 { margin: 0 0 7px; font-size: 15.5px }
.cta p { margin: 0 0 13px; font-size: 14.5px; color: var(--steel); line-height: 1.55 }

/* ===================================================== ARTICLE IMAGES */
figure.eaw-fig { margin: 2em 0 }
figure.eaw-fig img { width: 100%; border-radius: var(--r) }
figure.eaw-fig figcaption { font-family: var(--mono); font-size: 11.5px; line-height: 1.5;
  color: var(--steel); margin-top: 9px; letter-spacing: .02em }

/* Gallery — 1 to 4 images sit in a tidy grid instead of stacking raggedly. */
.eaw-gallery { display: grid; gap: 12px; margin: 2em 0 }
.eaw-gallery.g1 { grid-template-columns: 1fr }
.eaw-gallery.g2 { grid-template-columns: repeat(2, 1fr) }
.eaw-gallery.g3 { grid-template-columns: repeat(3, 1fr) }
.eaw-gallery.g4 { grid-template-columns: repeat(2, 1fr) }
@media (max-width: 620px) { .eaw-gallery.g3, .eaw-gallery.g4 { grid-template-columns: repeat(2, 1fr) } }
.eaw-gallery figure { margin: 0 }
.eaw-gallery img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: var(--r);
  cursor: zoom-in; transition: opacity .15s }
.eaw-gallery.g1 img { aspect-ratio: 16 / 9; cursor: zoom-in }
.eaw-gallery img:hover { opacity: .92 }
.eaw-gallery figcaption { font-family: var(--mono); font-size: 11px; color: var(--steel); margin-top: 7px }

/* Lightbox */
.eaw-lb { position: fixed; inset: 0; z-index: 200; background: rgba(10,24,38,.94);
  display: grid; place-items: center; padding: 30px; cursor: zoom-out }
.eaw-lb img { max-width: 100%; max-height: 84vh; width: auto; height: auto; border-radius: var(--r) }
.eaw-lb figcaption { color: #9FB6C7; font-family: var(--mono); font-size: 12.5px;
  text-align: center; margin-top: 14px }
.eaw-lb-x { position: absolute; top: 18px; right: 22px; width: 40px; height: 40px; border: 0;
  border-radius: 50%; background: rgba(255,255,255,.14); color: #fff; font-size: 22px; cursor: pointer }
.eaw-lb-nav { position: absolute; top: 50%; transform: translateY(-50%); width: 46px; height: 46px;
  border: 0; border-radius: 50%; background: rgba(255,255,255,.14); color: #fff; font-size: 22px; cursor: pointer }
.eaw-lb-prev { left: 22px } .eaw-lb-next { right: 22px }
.eaw-lb-count { position: absolute; bottom: 22px; left: 50%; transform: translateX(-50%);
  color: #9FB6C7; font-family: var(--mono); font-size: 12px }

/* ============================================================ MOBILE */
@media (max-width: 720px) {
  .card h3 { font-size: 17px }
  .prose { font-size: 17px }
  .shead { flex-direction: column; align-items: flex-start; gap: 6px }
  .hubhead { padding: 24px 0 22px }
  .section { padding: 32px 0 }
  .entrygrid { gap: 34px }
}

/* ============================================================= PRINT */
@media print {
  .util, .mainnav, .masthead form, .ad, .ad-sticky, .ad-popup, .share, aside, .foot { display: none !important }
  .prose { font-size: 11pt; max-width: none }
  a[href]::after { content: " (" attr(href) ")"; font-size: 9pt; color: #555 }
}

/* ==================================================================
   FILTER SIDEBAR
   The bug: .scroll-box had a max-height but no overflow rule, so long
   checkbox lists spilled out and sat on top of the next heading.
   ================================================================== */
.scroll-box {
  max-height: 220px;
  overflow-y: auto;
  overscroll-behavior: contain;
  border: 1px solid var(--line);
  background: #fff;
  padding: 10px 12px;
  margin-bottom: 4px;
  border-radius: var(--r);
}
.scroll-box::-webkit-scrollbar { width: 9px }
.scroll-box::-webkit-scrollbar-thumb { background: #C9D4DC; border-radius: 5px }
.scroll-box::-webkit-scrollbar-track { background: var(--surface) }
.scroll-box label:last-child { margin-bottom: 0 }

.filters { position: sticky; top: 16px; max-height: calc(100vh - 32px); overflow-y: auto }
@media (max-width: 999px) { .filters { position: static; max-height: none } }
.filters select { width: 100%; padding: 8px 10px; border: 1px solid var(--line);
  background: #fff; font-family: var(--sans); font-size: 14.5px; border-radius: var(--r) }
.filters h4 { clear: both }
.filter-actions { display: flex; gap: 8px; margin-top: 20px;
  padding-top: 16px; border-top: 1px solid var(--line) }

/* ============================================================ PAGER */
.pager-a { display: flex; gap: 6px; flex-wrap: wrap; align-items: center;
  margin-top: 30px; padding-top: 22px; border-top: 1px solid var(--line) }
.pager-a a, .pager-a span.on, .pager-a span.gap {
  padding: 8px 13px; border: 1px solid var(--line); background: #fff;
  min-width: 40px; text-align: center; border-radius: var(--r) }
.pager-a a:hover { border-color: var(--blue); color: var(--blue); text-decoration: none }
.pager-a .on { background: var(--ink); color: #fff; border-color: var(--ink); font-weight: 600 }
.pager-a .gap { border: 0; background: none; min-width: 20px; padding: 8px 2px; color: var(--steel) }
.pager-a .pgcount { margin-left: auto; border: 0; background: none; padding: 8px 0;
  color: var(--steel); font-size: 12px; letter-spacing: .02em }
@media (max-width: 620px) { .pager-a .pgcount { margin-left: 0; width: 100%; text-align: left } }

/* Child terms sit indented under their parent in filter lists. */
.filters label.child { padding-left: 20px; font-size: 13.8px; color: var(--steel); position: relative }
.filters label.child::before { content: ""; position: absolute; left: 8px; top: 11px;
  width: 7px; height: 1px; background: var(--line) }

/* ============================ ECOSYSTEM INDEX, TWO LEVELS ============ */
.eco-block { display: flex; flex-direction: column }
.eco-block .eco { flex: 1 }
.eco-kids { display: flex; flex-wrap: wrap; gap: 5px; padding: 12px 2px 0 }
.eco-kids a { font-family: var(--mono); font-size: 11px; letter-spacing: .02em;
  color: var(--steel); padding: 4px 9px; border: 1px solid var(--line);
  border-radius: var(--r); background: #fff; line-height: 1.3 }
.eco-kids a:hover { border-color: var(--blue); color: var(--blue); text-decoration: none }
.eco-kids a.more { border-style: dashed; color: var(--blue) }

/* ================= HOMEPAGE ECOSYSTEM BLOCK ================= */
/* Nine parent cards, not 98. Sub-categories live inside their parent. */
.eco-block { display: flex; flex-direction: column }
.eco-block .eco { flex: 1; min-height: 148px }
.eco-block .eco h3 { font-size: 17.5px; margin: 0 0 7px }
.eco-block .eco p { font-size: 14.2px; line-height: 1.5; color: var(--steel); margin: 0 0 12px }
.eco-block .eco .n { font-family: var(--mono); font-size: 10.5px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--blue) }

.eco-foot { display: grid; grid-template-columns: repeat(3, 1fr); gap: 26px; margin-top: 30px;
  padding-top: 28px; border-top: 1px solid var(--line) }
@media (max-width: 900px) { .eco-foot { grid-template-columns: 1fr } }
.eco.wide { display: block; min-height: 0 }

/* A category with nothing in it yet is still reachable, just quieter — so the
   page reads as a map with gaps rather than a wall of zeroes. */
.eco-kids a.empty { color: #A8B6C1; border-style: dashed }
.eco-kids a.empty:hover { color: var(--blue); border-style: solid }
.eco-kids a span { opacity: .55; margin-left: 3px }

/* ==================== TYPE-AHEAD FACETS ====================
   Nobody scrolls 86 checkboxes looking for "RO Membranes". You type. */
.facet { position: relative; margin-bottom: 18px }
.facet-chips { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 6px }
.facet-chips:empty { margin-bottom: 0 }
.facet-chip { display: inline-flex; align-items: center; gap: 5px; background: var(--ink);
  color: #fff; border-radius: 3px; padding: 4px 5px 4px 9px; font-size: 12.5px; line-height: 1.3 }
.facet-chip button { background: none; border: 0; color: #fff; opacity: .65; cursor: pointer;
  font-size: 15px; line-height: 1; padding: 0 3px }
.facet-chip button:hover { opacity: 1 }
.facet-input { width: 100%; padding: 8px 10px; border: 1px solid var(--line); background: #fff;
  font-family: var(--sans); font-size: 14px; border-radius: var(--r) }
.facet-input:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 2px rgba(18,105,159,.12) }
.facet-drop { position: absolute; z-index: 40; left: 0; right: 0; margin-top: 3px; background: #fff;
  border: 1px solid var(--line); border-radius: var(--r); box-shadow: 0 8px 22px rgba(10,24,38,.13);
  max-height: 250px; overflow-y: auto }
.facet-opt { display: block; width: 100%; text-align: left; background: none; border: 0;
  padding: 8px 11px; font-family: var(--sans); font-size: 14px; color: var(--ink); cursor: pointer;
  border-bottom: 1px solid var(--surface) }
.facet-opt:last-child { border-bottom: 0 }
.facet-opt:hover, .facet-opt.on { background: var(--surface); color: var(--blue) }
.facet-none { padding: 10px 11px; font-size: 13.5px; color: var(--steel) }
.facet-fallback.js-hidden { display: none }

/* Search suggestions now lead with categories, so the count matters. */
.s-meta { margin-left: auto; font-family: var(--mono); font-size: 11px; color: var(--steel);
  white-space: nowrap; padding-left: 12px }

/* =============== PROJECT & TENDER RECORDS =============== */
.rec { border: 1px solid var(--line); background: #fff; padding: 16px 18px; margin-bottom: 12px;
  border-radius: var(--r) }
.rec:hover { border-color: #C9D4DC }
.rec-head { display: flex; justify-content: space-between; gap: 18px; align-items: flex-start }
.rec-head h3 { font-size: 17px; line-height: 1.3 }
@media (max-width: 620px) { .rec-head { flex-direction: column; gap: 8px }
  .rec-head > div:last-child { text-align: left !important } }
.entrygrid.rev > aside { order: -1 }
@media (min-width: 1000px) { .entrygrid.rev { grid-template-columns: 280px minmax(0,1fr) } }

/* ============== TRENDING / SEARCHES / POLL WIDGETS ============== */
.widget { border: 1px solid var(--line); background: #fff; padding: 16px 18px; margin-bottom: 18px;
  border-radius: var(--r) }
.widget h4 { margin: 0 0 12px; font: 600 11px/1 var(--mono); letter-spacing: .13em;
  text-transform: uppercase; color: var(--steel) }
.ranklist { list-style: none; margin: 0; padding: 0; counter-reset: r }
.ranklist li { display: flex; gap: 11px; align-items: flex-start; padding: 9px 0;
  border-bottom: 1px solid var(--surface); font-size: 14.5px; line-height: 1.42 }
.ranklist li:last-child { border-bottom: 0; padding-bottom: 0 }
.ranklist .rank { flex: none; width: 20px; font: 700 15px var(--display); color: var(--line-dark, #C9D4DC) }
.ranklist a { color: var(--ink); text-decoration: none }
.ranklist a:hover { color: var(--blue) }

.poll .pollq { font: 600 16px/1.4 var(--display); margin: 0 0 14px }
.pollopt { display: flex; gap: 9px; align-items: flex-start; padding: 8px 10px; margin-bottom: 6px;
  border: 1px solid var(--line); border-radius: var(--r); cursor: pointer; font-size: 14px }
.pollopt:hover { border-color: var(--blue); background: var(--surface) }
.pollopt input { width: auto; margin-top: 3px; flex: none }
.pollbar { position: relative; padding: 9px 11px; margin-bottom: 6px; border-radius: var(--r);
  background: var(--surface); overflow: hidden; font-size: 14px; display: flex; gap: 10px }
.pollbar-fill { position: absolute; inset: 0 auto 0 0; background: #DCE6ED; z-index: 0 }
.pollbar.mine .pollbar-fill { background: #CFE0EC }
.pollbar.mine { font-weight: 600 }
.pollbar-txt, .pollbar-pc { position: relative; z-index: 1 }
.pollbar-pc { margin-left: auto; font: 600 13px var(--mono); color: var(--steel) }

/* ==================== MOBILE ====================
   Most of this audience is on a phone. Label/value tables stack rather than
   scroll — someone checking a tender's closing date should not have to swipe
   sideways to find it. */
@media (max-width: 640px) {
  .data.spec, .data.spec tbody, .data.spec tr, .data.spec th, .data.spec td { display: block; width: auto }
  .data.spec tr { border-bottom: 1px solid var(--line); padding: 9px 0 }
  .data.spec tr:last-child { border-bottom: 0 }
  .data.spec th { border: 0; padding: 0 0 2px; width: auto !important;
    font: 600 10.5px/1 var(--mono); letter-spacing: .1em; text-transform: uppercase;
    color: var(--steel) }
  .data.spec td { border: 0; padding: 0; font-size: 15px }

  /* Two-column layouts collapse; the sidebar goes under the content. */
  .entrygrid, .entrygrid.rev { grid-template-columns: 1fr }
  .entrygrid.rev > aside { order: 0 }
  .form-grid.two { grid-template-columns: 1fr }
  .form-grid.two > label, .form-grid.two > div { grid-column: 1 / -1 }
  .statgrid { grid-template-columns: repeat(2, 1fr) }
  .grid.g3, .grid.g4 { grid-template-columns: 1fr }
  .grid.g2 { grid-template-columns: 1fr }

  /* A dropdown taller than the viewport is unusable. */
  .facet-drop { max-height: 46vh }
  .facet-input { font-size: 16px }   /* iOS zooms anything under 16px */

  .widget { padding: 14px 15px }
  .ranklist li { font-size: 15px }
  .rec { padding: 14px 15px }
  .hubhead h1 { font-size: 27px }
}

/* The admin is used on phones too — usually to approve something quickly. */
@media (max-width: 700px) {
  .adminbar .wrap { flex-wrap: wrap; gap: 4px 12px }
  .toolbar { flex-wrap: wrap }
  .toolbar > * { flex: 0 1 auto }
}

/* ================= THINGS THAT WERE NEVER STYLED =================
   Four elements existed in the markup with no rules at all: the skip link, the
   menu button, the search suggestion box, and the footer legal line. They were
   rendering as raw browser defaults on every page. */

/* Skip link: for keyboard and screen-reader users. It should be invisible
   until it is focused, not parked in the corner of every page. */
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--ink); color: #fff; padding: 11px 18px;
  font: 600 14px var(--sans); text-decoration: none; border-radius: 0 0 4px 0;
}
.skip:focus { left: 0 }

/* The menu button was a grey browser default. */
.nav-toggle {
  display: none; align-items: center; gap: 7px;
  background: none; border: 1px solid var(--line); border-radius: var(--r);
  padding: 8px 13px; cursor: pointer;
  font: 600 12.5px/1 var(--sans); color: var(--ink);
}
.nav-toggle:hover { border-color: var(--ink) }
.nav-toggle::before {
  content: ''; width: 15px; height: 10px; flex: none;
  border-top: 2px solid currentColor; border-bottom: 2px solid currentColor;
  box-shadow: inset 0 0 0 1px transparent, 0 4px 0 -1px currentColor;
}
.nav-toggle[aria-expanded="true"] { background: var(--ink); color: #fff; border-color: var(--ink) }

/* Suggestions were pushing the page down instead of floating over it. */
.msearch { position: relative }
.msearch .sug, #sugBox, .suggest-box {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 60;
  background: #fff; border: 1px solid var(--line); border-radius: var(--r);
  box-shadow: 0 12px 30px rgba(10,24,38,.14);
  max-height: 60vh; overflow-y: auto;
}
.msearch .sug a, #sugBox a, .suggest-box a {
  display: flex; align-items: baseline; gap: 10px; padding: 9px 13px;
  border-bottom: 1px solid var(--surface); text-decoration: none; color: var(--ink);
}
.msearch .sug a:last-child, #sugBox a:last-child { border-bottom: 0 }
.msearch .sug a:hover, #sugBox a:hover { background: var(--surface) }
.s-type { flex: none; font: 600 9.5px/1.6 var(--mono); letter-spacing: .1em;
  text-transform: uppercase; color: var(--steel); min-width: 74px }
.s-title { font-size: 14.5px; line-height: 1.4 }

/* The legal line in the footer. */
.flegal {
  border-top: 1px solid rgba(255,255,255,.12); margin-top: 22px; padding-top: 18px;
  font-size: 12.5px; line-height: 1.65; color: rgba(255,255,255,.55);
}
.flegal a { color: rgba(255,255,255,.78); text-decoration: underline }
.flegal a:hover { color: #fff }

/* ================= THE PHONE HEADER =================
   Two faults: the tagline forced the page wider than the screen, and the menu
   never folded, so the header filled the first screen before any content. */
@media (max-width: 860px) {
  .nav-toggle { display: inline-flex }

  .mainnav { display: none }
  .mainnav.open { display: block }
  .mainnav.open > ul { flex-direction: column; align-items: stretch; gap: 0 }
  .mainnav.open > ul > li { border-bottom: 1px solid var(--line) }
  .mainnav.open > ul > li > a { display: block; padding: 13px 2px; font-size: 15px }
  .mainnav.open .mega { position: static; display: none; box-shadow: none; border: 0;
    padding: 0 0 12px 14px; background: none }
  .mainnav.open li.open > .mega { display: block }

  .masthead .wrap { flex-wrap: wrap; gap: 12px }
  .brand small {
    display: block; white-space: normal; word-break: break-word;
    font-size: 9px; letter-spacing: .1em; line-height: 1.5; max-width: 100%;
  }
  .msearch { order: 3; flex-basis: 100%; min-width: 0 }
  .msearch input { min-width: 0; width: 100% }
}

/* Nothing may ever make the page wider than the screen. A single overflowing
   element gives the whole site a sideways scroll on a phone. */
html, body { overflow-x: hidden; max-width: 100% }
.brand small { overflow-wrap: anywhere }
