/* tokens.css + homepage.css + nav.css + placeholder.css + sponsors.css
   (homepage-relevant subset) — Jinja port of the Claude Design
   prototype's Layout A homepage. See design/TimberAtlas_Homepage_Spec.md. */

:root {
  --ink: #1A1A1A;
  --bone: #FAFAF7;
  --bone-2: #F4F2EC;
  --umber: #8B5A3C;
  --forest: #1F3D2E;
  --border: #E5E3DE;
  --border-2: #D8D5CE;
  --muted: #6B6B66;
  --muted-2: #9B9B95;
  --pin-blue: #5B9BD5;   /* map pin fill (projects map + homepage map) */
  --sans: "Inter","Inter Tight",-apple-system,BlinkMacSystemFont,"Helvetica Neue",Arial,sans-serif;
  --mono: "JetBrains Mono","IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  --maxw: 1320px;
  --gutter: 28px;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body {
  font-family: var(--sans);
  color: var(--ink);
  background: var(--bone);
  -webkit-font-smoothing: antialiased;
}
/* tweaks.css — body umber accent retained */
body { --umber: #8B5A3C; }
img { display: block; max-width: 100%; }
button { font-family: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }
.container { max-width: var(--maxw); margin: 0 auto; padding: 0 var(--gutter); }
.serif { font-family: var(--sans); font-weight: 500; letter-spacing: -0.02em; }
.mono { font-family: var(--mono); }
.eyebrow {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--muted); font-weight: 500;
}
.rule {
  max-width: var(--maxw); margin: 0 auto;
  border: 0; border-top: 1px solid var(--border);
}

/* nav.css */
.nav {
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px var(--gutter); border-bottom: 1px solid var(--border);
  max-width: var(--maxw); margin: 0 auto;
}
/* The logo group must never participate in the header's flex squeeze —
   without flex-shrink:0 the img got compressed (437x203 → 17x38), breaking
   its aspect ratio. Pin shrink:0 on the stack, anchor and img; height fixed
   + width auto + object-fit:contain hold the 2.15 ratio at every width. */
.nav-logo-stack { flex-shrink: 0; }
.nav-logo {
  font-family: var(--mono); font-weight: 500; letter-spacing: 0.04em;
  padding: 4px 12px 4px 6px;
  display: inline-flex; align-items: center; flex-shrink: 0;
}
.nav-logo img { margin-right: 4px; }

/* v5.070 — merged TimberAtlas mark; replaces icon-box + span wordmark. */
.brand-logo--public {
  height: 38px; width: auto; max-width: none; display: block; margin: 0;
  flex-shrink: 0; object-fit: contain;
}
.nav-links {
  display: flex; gap: 24px;
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted);
}
.nav-links a { cursor: pointer; }
.nav-links a:hover { color: var(--umber); }
.nav-links a.is-active { color: var(--ink); }
.nav-beta { color: var(--muted-2); }
.nav-beta sup { font-size: 9px; letter-spacing: 0; margin-left: 1px; }
/* nav-actions absorbs the row's overflow; min-width:0 lets its search
   child actually shrink instead of forcing the logo to. */
.nav-actions { display: flex; gap: 14px; align-items: center; min-width: 0; }
.nav-search {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 12px; border: 1px solid var(--border); border-radius: 999px;
  font-family: var(--mono); font-size: 11px; color: var(--muted);
  background: transparent;
  flex-shrink: 1; min-width: 0;
}
/* Search is the flexible shrinker of the header row, with a usable floor. */
.nav-search input {
  border: 0; outline: 0; background: transparent;
  font: inherit; color: var(--ink);
  flex: 1 1 140px; width: auto; min-width: 90px;
}
.nav-pill {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em;
  text-transform: uppercase; padding: 8px 14px;
  border: 1px solid var(--border); border-radius: 999px;
  color: var(--muted-2); cursor: not-allowed;
}
.nav-icon { font-size: 14px; color: var(--muted); cursor: pointer; padding: 6px; }
.nav-icon:hover { color: var(--umber); }
.nav-icon-disabled { color: var(--muted-2); cursor: not-allowed; }
.nav-icon-disabled:hover { color: var(--muted-2); }

/* Masthead + ribbon */
.masthead {
  max-width: var(--maxw); margin: 0 auto;
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  padding: 14px var(--gutter); border-bottom: 1px solid var(--ink);
}
.masthead-lead {
  font-style: italic; font-size: 13px;
  letter-spacing: 0.02em; color: var(--ink);
}
.masthead-meta {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted); white-space: nowrap;
}
.masthead-meta .sep { color: var(--muted-2); }
.masthead-countdown {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted); white-space: nowrap;
}
.masthead-countdown-days { color: var(--ink); font-weight: 600; }
.masthead-stats {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted); text-align: right;
}
.ribbon {
  max-width: var(--maxw); margin: 0 auto;
  display: flex; align-items: stretch; padding: 0 var(--gutter);
  border-bottom: 0.5px solid var(--border);
  flex-wrap: nowrap; overflow-x: auto;
  scrollbar-width: thin;
}
.ribbon-cell {
  flex: 1 0 auto; display: flex; align-items: baseline; justify-content: center;
  gap: 6px; padding: 24px 16px; border-right: 1px solid var(--border);
  white-space: nowrap;
}
.ribbon-cell:last-child { border-right: 0; }
.ribbon-num { font-family: var(--sans); font-weight: 500; font-size: 18px; color: var(--ink); line-height: 1; }
.ribbon-lbl { font-family: var(--sans); font-weight: 400; font-size: 12px; color: var(--muted); }

/* Section frame */
.section {
  max-width: var(--maxw); margin: 0 auto;
  padding: 56px var(--gutter) 40px;
}
.section-head {
  display: flex; align-items: end; justify-content: space-between;
  gap: 24px; margin-bottom: 28px;
}
.section-titles { display: flex; flex-direction: column; gap: 12px; }
.section-h {
  font-family: var(--sans); font-weight: 380; font-size: 36px;
  line-height: 1.05; letter-spacing: -0.02em; color: var(--ink);
}
.section-link {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted);
}
.section-link:hover { color: var(--umber); }
.section-aside {
  display: flex; flex-direction: column; align-items: flex-end; gap: 6px;
}

/* Section 01 — Featured projects (Layout A) */
.feat-layout {
  display: grid;
  grid-template-columns: minmax(0, 3fr) minmax(0, 1fr);
  gap: 32px;
  align-items: stretch;
}
.feat-projects { min-width: 0; }
/* 620-448 — THE HOLE BETWEEN THE SQUARE AND THE VERTICAL. The rows were
   `1fr 1fr`, so each got half the column's height (the column stretches to the
   projects grid beside it). The square is a WIDTH-driven ratio box (620-443):
   it is ~one column-width tall, start-aligned in its half, and the rest of that
   half was empty — a band of nothing sitting above the vertical and, through
   it, above the horizontal band below.
   `auto` gives row 1 exactly the square's own height and hands the remainder to
   the vertical, which is HEIGHT-driven and takes it. Both boxes move up, the
   gap closes, and the column's total height is unchanged — so the Featured
   section does not move and 735-453's overflow cannot return. No ratio is
   touched here: the square is still 1/1 and the vertical still 2/5, both from
   SPONSOR_ASSET_SLOTS (620-445). */
.feat-sponsor-col {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  gap: 24px;
  min-height: 100%;
}
.feat-sponsor.placeholder-vertical {
  grid-template-columns: 1fr;
  align-items: stretch;
  justify-items: start;
  gap: 14px;
  padding: 24px 20px;
  height: 100%;
}
.feat-sponsor .placeholder-badge { align-self: flex-start; }
/* Live sponsor banners (620-061): the served <img> fits the placement box
   with object-fit:contain so the artwork is never cropped. */
.feat-sponsor.placeholder-square { align-items: stretch; height: 100%; padding: 24px 20px; }
.feat-sponsor.banner-live {
  display: block; padding: 0; overflow: hidden;
  border: 1px solid var(--border-2); background: var(--bone-2);
  transition: border-color 0.15s, transform 0.15s;
}
.feat-sponsor.banner-live:hover { border-color: var(--umber); transform: translateY(-2px); }
.feat-sponsor.banner-live img { width: 100%; height: 100%; object-fit: contain; display: block; }
/* 735-427 — these ratios ARE the slot specification, and the specification lives
   in ONE place: SPONSOR_ASSET_SLOTS in app/services/sponsor_asset_config.py
   (`aspect_ratio` = width/height). Square 1.0 → 1/1, vertical 0.4 → 2/5,
   horizontal 5.0 → 5/1. They read 3/4 and 4/1 until now — wrong, and invisible
   because object-fit:contain letterboxed the difference away. It stopped being
   invisible the moment demo mode inferred its generated creative's dimensions
   from this stylesheet instead of from the config. TAKE THE NUMBER FROM THERE. */
.feat-sponsor.banner-square { aspect-ratio: 1/1; }
.feat-sponsor.banner-vertical { aspect-ratio: 2/5; height: 100%; }
.feat-sponsor.banner-horizontal { aspect-ratio: 5/1; width: 100%; }
/* 735-453 — THE RATIO DESCRIBES THE ARTWORK; THE COLUMN'S HEIGHT IS THE
   LAYOUT'S. In `.feat-sponsor-col` (a `1fr 1fr` grid whose height comes from
   the projects column beside it) an `aspect-ratio` contributes to the item's
   automatic MINIMUM size: a 2/5 box at the column's ~300px width demanded
   750px of height, `1fr 1fr` equalised BOTH tracks to it, and the Featured
   section grew past 1500px. `min-height:0` withdraws that demand, the definite
   height then drives the width through the same ratio, and the box lands at
   slot dimensions inside the space the design gives it. Only the two ratio
   classes are touched — the text placeholders still fill their own cell. */
/* 620-443 — THE TWO SLOTS ARE DRIVEN BY DIFFERENT AXES, and folding them into
   one rule is what broke the square. `height:100%; width:auto` asks the grid
   ROW for the size and lets the content settle the width, which is right for
   the vertical (735-453: a 2/5 box sized from the ~300px column demanded 750px
   of height and dragged the whole Featured section past 1500px) and wrong for
   the square in two different ways at once — ONE cause, two presentations:
     · ordinary/admin view — height came from the row (~390px) while the width
       was capped by the column (~300px), so a 1/1 box rendered PORTRAIT and
       read as a second vertical slot;
     · demo view — `width:auto` in a grid is fit-content, so the generated 800px
       creative supplied the width itself and the box blew out of the column.
   The square is a WIDTH-driven box: it takes the column and derives its height
   from the ratio, which is `aspect-ratio: 1/1` above and comes from
   SPONSOR_ASSET_SLOTS (620-358 — the config is the dimension source, this
   stylesheet is not; nothing here invents a number). The vertical keeps the
   735-453 behaviour exactly. */
.feat-sponsor-col > .banner-square {
  min-height: 0; width: 100%; height: auto; max-height: 100%;
  justify-self: stretch;
}
.feat-sponsor-col > .banner-vertical {
  min-height: 0; height: 100%; width: auto; max-width: 100%; justify-self: center;
}
/* The demo's "other coverage group" marker. 620-443 gave it no size at all, so
   it read as "nothing here"; 620-445 puts it back at the slot's real
   proportions and fills it a light grey, because the box is what tells a
   prospect how much space he is buying. The dashed border and the label stay —
   it must still be legible as a placeholder, not as a hidden competitor.
   NO RATIO IS DECLARED HERE. It arrives inline from `res.demo_aspect`, which
   the engine reads out of SPONSOR_ASSET_SLOTS; these rules carry only the
   CONTAINMENT, and they are keyed on the format so square and vertical can
   never again share one rule (620-358, 620-443 — that sharing is what made a
   1/1 box render portrait). */
.feat-sponsor.demo-other-slot {
  display: flex; align-items: center; justify-content: center;
  align-self: center; justify-self: center;
  min-height: 0; padding: 6px 10px;
  border: 1px dashed var(--border-2); background: var(--bone-2);
}
/* Horizontal: width-driven, the full row. */
.feat-sponsor.demo-other-slot[data-slot-format="banner_horizontal"] {
  width: 100%;
}
/* In the `1fr 1fr` sponsor column an aspect-ratio box contributes an automatic
   MINIMUM size (735-453) — `min-height: 0` above withdraws it, and each of these
   caps the box against the row so neither can grow the Featured section again.
   Square takes the column and derives height; vertical takes the row height and
   derives width. Same axes as the live banners immediately above. */
.feat-sponsor-col > .demo-other-slot[data-slot-format="banner_square"] {
  width: 100%; height: auto; max-height: 100%; justify-self: stretch;
}
.feat-sponsor-col > .demo-other-slot[data-slot-format="banner_vertical"] {
  height: 100%; width: auto; max-width: 100%; justify-self: center;
}
.demo-other-label {
  font-size: 10.5px; font-weight: 500; letter-spacing: 0.06em;
  text-transform: uppercase; color: #a8a49e; text-align: center;
}
/* Admin debug badge (620-063) — only ever rendered on a trapdoor render. */
.feat-sponsor.banner-live { position: relative; }
.banner-collapsed { display: inline-block; position: relative; }
.banner-dbg {
  position: absolute; top: 4px; right: 4px; z-index: 5;
  width: 18px; height: 18px; line-height: 18px; text-align: center;
  font-size: 12px; border-radius: 50%; cursor: pointer;
  background: rgba(20, 20, 20, 0.7); color: #fff;
}
.banner-dbg-box {
  display: none; position: absolute; top: 22px; right: 0; z-index: 6;
  width: 260px; padding: 8px 10px; text-align: left;
  font-size: 11px; line-height: 1.4; border-radius: 6px;
  background: #141414; color: #eee; box-shadow: 0 4px 14px rgba(0,0,0,0.4);
}
.banner-dbg:hover .banner-dbg-box, .banner-dbg.open .banner-dbg-box,
.banner-dbg:focus .banner-dbg-box { display: block; }
.feat-sponsor-row { display: grid; grid-template-rows: auto auto; gap: 16px; }
.feat-sponsor.placeholder-horizontal {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; padding: 20px 24px; aspect-ratio: 4/1;
}
.feat-top { display: grid; grid-template-columns: 2fr 1fr; gap: 20px; }
.feat-bottom {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px;
  padding-top: 20px; margin-top: 28px;
  border-top: 1px solid var(--border);
}
.feat-right { display: flex; flex-direction: column; gap: 20px; }

.tile { display: block; cursor: pointer; position: relative; }
.tile-img-wrap {
  position: relative; overflow: hidden;
  border: 1px solid var(--border-2); background: var(--bone-2);
  transition: border-color 0.15s, transform 0.15s;
}
.tile:hover .tile-img-wrap { border-color: var(--umber); transform: translateY(-2px); }
.tile-lead .tile-img-wrap { aspect-ratio: 16/10; }
.tile-small .tile-img-wrap { aspect-ratio: 3/2; }
.feat-projects .tile-lead .tile-title { font-size: 32px; }
.feat-projects .tile-oneliner { font-size: 14px; max-width: none; }
.tile-img-wrap img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tile-img-placeholder {
  width: 100%; height: 100%; display: flex; align-items: center;
  justify-content: center; color: var(--muted);
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em;
  text-transform: uppercase; padding: 0 12px; text-align: center;
}
.tile-pinned-badge {
  position: absolute; top: 12px; left: 12px;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--bone);
  background: rgba(26,26,26,0.78); padding: 4px 8px; border-radius: 999px;
}

/* Section 01 lead — a paid studio takes priority over admin-pinned. The
   pill replaces "Pinned · 1" when the lead came from a Pro studio's
   position-1 featured project. Purple (#6d28d9) is the paid-studio
   colour across the public surfaces. */
.tile-pro-badge {
  position: absolute; top: 12px; left: 12px;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em;
  text-transform: uppercase; color: #fff; font-weight: 600;
  background: #6d28d9; padding: 4px 10px; border-radius: 999px;
}
/* Static (non-absolute) variant for small surfaces — list rows, inline
   credits. Same pill identity (color/typography), just flows inline. */
.tile-pro-badge-inline {
  position: static; top: auto; left: auto;
  display: inline-block; padding: 2px 7px; font-size: 9px;
  vertical-align: middle;
}
/* Subtle "By <Studio>" caption row under the lead tile. Inherits the
   homepage typography rhythm: mono small caps for "By", sans for the
   studio name. No heavy borders. Logo is 32×32 rounded; degrades to
   text-only when the studio has no logo asset. */
.tile-pro-caption {
  display: flex; align-items: center; gap: 10px;
  margin-top: 10px; padding: 6px 0;
  text-decoration: none; color: var(--muted);
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em;
  text-transform: uppercase;
}
.tile-pro-caption:hover { color: var(--ink); }
.tile-pro-caption strong {
  font-family: var(--sans); font-weight: 600;
  font-size: 13px; letter-spacing: 0;
  text-transform: none; color: var(--ink);
}
.tile-pro-caption-logo {
  width: 32px; height: 32px; border-radius: 50%;
  object-fit: cover; background: var(--bone-2);
  border: 1px solid var(--line);
}

.tile-meta {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 14px 0 8px;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted);
}
.tile-meta .sep { color: var(--border-2); }
.tile-lead .tile-title {
  font-family: var(--sans); font-weight: 380; font-size: 40px;
  line-height: 1.05; letter-spacing: -0.02em; color: var(--ink);
}
.tile-small .tile-title {
  font-family: var(--sans); font-weight: 400; font-size: 18px;
  line-height: 1.15; letter-spacing: -0.01em; color: var(--ink);
}
.tile-bottom-row .tile-title {
  font-family: var(--sans); font-weight: 380; font-size: 22px;
  line-height: 1.1; letter-spacing: -0.01em; color: var(--ink);
}
.tile:hover .tile-title { color: var(--umber); }
.tile-oneliner {
  font-size: 15px; line-height: 1.5; color: var(--muted);
  margin-top: 12px; max-width: 620px;
}
.tile-credits {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 12px;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted);
}
.tile-credits .sep { color: var(--border-2); }
.tile-credits-compact {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted); margin-top: 8px;
}

/* Remix button */
.remix-btn {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em;
  text-transform: uppercase; padding: 8px 14px;
  border: 1px solid var(--border); border-radius: 999px;
  color: var(--ink); background: var(--bone); cursor: pointer;
}
.remix-btn:hover { border-color: var(--umber); color: var(--umber); }
.remix-meta {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted-2);
}

/* sponsors.css — homepage-relevant subset */
.stats-grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 0;
  border: 1px solid var(--border); background: var(--bone);
}
.stats-cell {
  padding: 24px 20px; border-right: 1px solid var(--border);
}
.stats-cell:last-child { border-right: 0; }
.stats-num {
  font-family: var(--sans); font-weight: 380; font-size: 32px;
  letter-spacing: -0.02em; color: var(--ink); line-height: 1;
}
.stats-lbl {
  margin-top: 6px;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted);
}
.stats-foot {
  margin-top: 16px; font-size: 13px; color: var(--muted);
}

/* placeholder.css — "Coming soon" strip + map / chip stubs */
.placeholder {
  display: grid; grid-template-columns: auto 1fr auto; align-items: center;
  gap: 24px; padding: 28px 24px;
  border: 1px solid var(--border); background: var(--bone);
}
.placeholder-text { display: flex; flex-direction: column; gap: 6px; }
.placeholder-title {
  font-family: var(--sans); font-weight: 400; font-size: 18px;
  letter-spacing: -0.01em; color: var(--ink);
}
.placeholder-desc { font-size: 13px; color: var(--muted); line-height: 1.5; }
.placeholder-badge {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted-2);
  border: 1px solid var(--border); border-radius: 999px;
  padding: 6px 12px; background: var(--bone-2); white-space: nowrap;
}

/* Section 02 — News grid (international / continent / local) */
.news-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}
.news-grid .placeholder-vertical {
  display: flex; flex-direction: column; align-items: flex-start;
  gap: 12px; padding: 24px 20px;
}
@media (max-width: 760px) {
  .news-grid { grid-template-columns: 1fr; }
}

/* Section 05 — Map */
.map-wrap {
  position: relative; border: 1px solid var(--border);
  background: #d4dadc; height: 480px;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
.map-wrap img { width: 100%; height: 100%; object-fit: cover; }
#atlas-map { position: absolute; inset: 0; width: 100%; height: 100%; background: #d4dadc; }
.atlas-map-overlay {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  z-index: 500; background: var(--bone);
  border: 1px solid var(--border); padding: 10px 16px;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted-2);
}
@media (max-width: 720px) {
  .map-wrap { height: 320px; }
}
@media print { .map-wrap { display: none; } }

/* Leaflet popup look — match TimberAtlas tile cards */
.leaflet-popup-content-wrapper { border-radius: 0; padding: 0; }
.leaflet-popup-content { margin: 0; width: 220px !important; font-family: var(--sans, Inter, sans-serif); }
.atlas-popup-thumb {
  display: block; width: 100%; height: 130px; object-fit: cover; background: var(--bone-2);
}
.atlas-popup-text { padding: 10px 12px 12px; display: flex; flex-direction: column; gap: 4px; }
.atlas-popup-title {
  font-weight: 500; font-size: 13px; color: var(--ink, #111); line-height: 1.25;
}
.atlas-popup-text a { text-decoration: none; }
.atlas-popup-text a:hover .atlas-popup-title { text-decoration: underline; }
.atlas-popup-location {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted-2);
}
.atlas-popup-type {
  font-size: 11px; font-style: italic; color: var(--muted-2);
}
.map-chips {
  display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px;
}
.map-chip {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted-2);
  border: 1px solid var(--border); border-radius: 999px;
  padding: 6px 12px; cursor: not-allowed; background: var(--bone-2);
}

/* Footer */
.footer {
  margin-top: 80px; border-top: 1px solid var(--border);
  background: var(--bone);
}
.footer-inner {
  max-width: var(--maxw); margin: 0 auto;
  padding: 40px var(--gutter) 24px;
  display: grid; grid-template-columns: 2fr 1fr 1fr 1fr 1fr; gap: 32px;
}
.footer-brand { display: flex; flex-direction: column; gap: 8px; }
.footer-logo { font-family: var(--mono); font-size: 14px; letter-spacing: 0.04em; }
/* v5.070 — merged TimberAtlas mark in footer. Slightly smaller than nav. */
.brand-logo--footer { height: 30px; width: auto; display: block; margin: 0 0 6px; }
.footer-tag { font-size: 12px; color: var(--muted); }
.footer-social { display: flex; gap: 14px; margin-top: 10px; }
.footer-social-icon { color: var(--muted); line-height: 0; display: inline-flex; }
.footer-col h4 {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--muted); font-weight: 500;
  margin-bottom: 12px;
}
.footer-col ul { list-style: none; display: flex; flex-direction: column; gap: 6px; }
.footer-col a { font-size: 12px; color: var(--ink); }
.footer-col a:hover { color: var(--umber); }
.footer-bottom {
  border-top: 1px solid var(--border);
  padding: 18px var(--gutter);
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted);
  max-width: var(--maxw); margin: 0 auto;
  display: flex; justify-content: space-between;
}

/* ── /projects listing ──────────────────────────────────────────────── */
.filter-bar {
  display: grid;
  grid-template-columns: 2fr 1.2fr 1.8fr auto auto;
  gap: 12px; align-items: end;
  padding: 16px 0 24px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 28px;
}
.filter-field { display: flex; flex-direction: column; gap: 4px; }
.filter-field label {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--muted);
}
/* :not([type=range]) — the year-slider range inputs must NOT get the
   field chrome (border / bone bg / padding); they're a bare track line. */
.filter-field input:not([type=range]), .filter-field select {
  font-family: var(--sans); font-size: 13px; color: var(--ink);
  background: #fff; border: 1px solid var(--border);
  border-radius: 4px; padding: 8px 10px; outline: 0;
}
.filter-field input:not([type=range]):focus, .filter-field select:focus { border-color: var(--umber); }

/* ── Year range slider — Material-style: a BARE track line (no box, no
   border, no field background) with TWO solid circle handles. The visible
   handles + active fill are plain divs positioned by JS (so both circles
   ALWAYS render at their value positions — native range thumbs proved
   unreliable). Two transparent native range inputs overlay the track to
   provide drag + keyboard interaction only (their own thumbs are
   invisible). Bone/ink/umber palette, mono numerals. */
.filter-field--year { min-width: 0; display: flex; flex-direction: column; gap: 4px; }
/* Top line: caps label + "2012 – 2025" + (N), all on one row — same
   label treatment + baseline as the NAME / COUNTRY field labels. */
.year-top { display: flex; align-items: baseline; gap: 8px; min-height: 14px; }
.year-label {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--muted); white-space: nowrap;
}
.year-readout { font-family: var(--mono); font-size: 13px; color: var(--ink); }
.year-sep { color: var(--muted-2); margin: 0 5px; }
.year-count {
  font-family: var(--mono); font-size: 12px; color: var(--muted);
  margin-left: auto;
}
/* Track row — height matches the NAME / COUNTRY <input> so bottoms align
   (.filter-bar is align-items:end). The track itself is a thin LINE. */
/* Side padding = thumb radius, so the end handles at full-extent sit
   fully in view instead of clipping at the field edges. */
.year-slider { display: flex; align-items: center; height: 34px; padding: 0 9px; }
.year-slider-track {
  position: relative; height: 4px; width: 100%;
  background: var(--border-2); border-radius: 999px;
}
/* Active segment between the two handles. */
.year-slider-fill {
  position: absolute; top: 0; bottom: 0;
  border-radius: 999px; background: var(--umber); z-index: 1;
}
/* Visible solid circle handles (positioned by JS via left:%). Umber fill
   + bone ring → reads clearly against the bone page at either end. */
.year-thumb {
  position: absolute; top: 50%; width: 16px; height: 16px;
  margin-left: -8px; transform: translateY(-50%);
  border-radius: 50%; background: var(--umber);
  border: 2px solid var(--bone); box-shadow: 0 1px 3px rgba(0,0,0,0.28);
  z-index: 3; pointer-events: none;
}
/* Transparent native inputs — interaction layer only (no chrome). */
.year-slider-input {
  position: absolute; left: 0; top: 50%; width: 100%; height: 34px;
  transform: translateY(-50%); margin: 0; padding: 0;
  background: transparent; -webkit-appearance: none; appearance: none;
  pointer-events: none; z-index: 4;
}
.year-slider-input::-webkit-slider-runnable-track {
  -webkit-appearance: none; appearance: none; background: transparent; height: 34px;
}
.year-slider-input::-moz-range-track { background: transparent; height: 34px; }
.year-slider-input::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 22px; height: 22px; border: 0; background: transparent;
  cursor: grab; pointer-events: auto;
}
.year-slider-input::-moz-range-thumb {
  width: 22px; height: 22px; border: 0; background: transparent;
  cursor: grab; pointer-events: auto;
}
.year-slider-input::-webkit-slider-thumb:active { cursor: grabbing; }
.year-slider-input::-moz-range-thumb:active { cursor: grabbing; }
.year-slider-input:focus { outline: none; }
/* Min input on top so an overlapping pair stays separable. */
.year-slider-input--min { z-index: 5; }
.filter-btn {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em;
  text-transform: uppercase; padding: 9px 16px;
  border: 1px solid var(--ink); border-radius: 999px;
  color: var(--bone); background: var(--ink); cursor: pointer;
}
.filter-btn:hover { background: var(--umber); border-color: var(--umber); }
.submit-project-btn { text-decoration: none; white-space: nowrap; align-self: center; }
/* Admin-only "Photographer projects" toggle chip (/projects?photographers=1).
   Outline when off, photographer-violet fill when on (matches the T7 badge). */
.photog-toggle-row { margin: 10px 0 0; }
.photog-toggle {
  text-decoration: none; white-space: nowrap;
  background: transparent; color: var(--ink);
}
.photog-toggle:hover { background: var(--bone-2); border-color: var(--ink); color: var(--ink); }
.photog-toggle.is-active { background: #7c3aed; border-color: #7c3aed; color: #fff; }
.photog-toggle.is-active:hover { background: #6d28d9; border-color: #6d28d9; }
/* Logged-out state: greyed, non-clickable (rendered as a <span>, so no
   navigation); keep hover-able for the title= tooltip — do NOT set
   pointer-events:none or the tooltip won't show. */
.filter-btn.is-disabled, .filter-btn.is-disabled:hover {
  background: var(--border); border-color: var(--border);
  color: var(--muted); cursor: not-allowed;
}
/* 620-290 — chips for filters that arrive by URL and own no field on the bar
   (?system= inherited from /products). Spans the whole grid so it reads as a
   statement about the result set, not as another control. */
.active-filters {
  grid-column: 1 / -1;
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
}
.filter-chip {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em;
  text-transform: uppercase; padding: 7px 14px;
  border: 1px solid var(--ink); border-radius: 999px;
  background: var(--ink); color: var(--bone); text-decoration: none;
}
.filter-chip:hover { background: var(--umber); border-color: var(--umber); }
.filter-chip-x { font-size: 13px; line-height: 1; opacity: 0.75; }
.filter-chip:hover .filter-chip-x { opacity: 1; }
/* The category row is a PICKER: outline when off, filled when on — it was
   solid black in BOTH states, which is why an active filter read as a label
   sitting under the view toggle. */
.system-filter-row { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 0; }
.system-chip {
  text-decoration: none; white-space: nowrap;
  background: transparent; color: var(--ink);
}
.system-chip:hover { background: var(--bone-2); border-color: var(--ink); color: var(--ink); }
.system-chip.is-active { background: var(--ink); border-color: var(--ink); color: var(--bone); }
.system-chip.is-active:hover { background: var(--umber); border-color: var(--umber); color: var(--bone); }
.filter-clear {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em;
  text-transform: uppercase; padding: 9px 16px;
  color: var(--muted); border: 1px solid var(--border); border-radius: 999px;
  background: var(--bone);
}
.filter-clear:hover { color: var(--umber); border-color: var(--umber); }
.results-meta {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted);
  margin-bottom: 18px;
}

.map-missing-geo {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.04em;
  color: var(--muted); margin: 8px 0 0;
}

.project-grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px;
}
.project-card { display: flex; flex-direction: column; cursor: pointer; }
.project-card .tile-img-wrap { aspect-ratio: 16/10; }
.project-card h3 {
  font-family: var(--sans); font-weight: 400; font-size: 16px;
  line-height: 1.2; letter-spacing: -0.01em; color: var(--ink);
  margin-top: 12px;
}
.project-card .card-country {
  margin-top: 4px;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted);
}
.project-card:hover h3 { color: var(--umber); }

.empty-state {
  border: 1px dashed var(--border-2);
  padding: 56px 24px; text-align: center;
  background: var(--bone-2); color: var(--muted);
}
.empty-state .empty-title {
  font-size: 16px; color: var(--ink); margin-bottom: 8px;
}

.pagination {
  display: flex; justify-content: center; gap: 16px;
  margin: 40px 0 0;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted);
}
.pagination a {
  padding: 8px 14px; border: 1px solid var(--border); border-radius: 999px;
  color: var(--ink);
}
.pagination a:hover { border-color: var(--umber); color: var(--umber); }
.pagination .current {
  padding: 8px 14px; color: var(--muted);
}
.pagination-jump { display: flex; align-items: center; gap: 6px; }
.pagination-jump input[type="number"] {
  width: 56px; padding: 7px 8px; border: 1px solid var(--border);
  border-radius: 999px; font-family: var(--mono); font-size: 11px;
  text-align: center; color: var(--ink); background: transparent;
}
.pagination-jump button {
  padding: 8px 14px; border: 1px solid var(--border); border-radius: 999px;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink); background: transparent;
  cursor: pointer;
}
.pagination-jump button:hover { border-color: var(--umber); color: var(--umber); }

@media (max-width: 1024px) {
  .filter-bar { grid-template-columns: 1fr 1fr; }
  .project-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
  .filter-bar { grid-template-columns: 1fr; }
  .project-grid { grid-template-columns: 1fr; }
}

/* ── Homepage Section 04 — recent articles ────────────────────────── */
.home-articles {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 24px; margin-top: 14px;
}
/* Default 2×3: three cards per row (gap 24px × 2 = 48px / 3 = 16px). */
.home-article-card-wrap {
  flex: 1 1 calc(33.333% - 16px); max-width: calc(33.333% - 16px);
}
.home-articles[data-count="1"] .home-article-card-wrap {
  flex: 0 1 800px; max-width: 800px;
}
.home-articles[data-count="2"] .home-article-card-wrap {
  flex: 1 1 calc(50% - 12px); max-width: calc(50% - 12px);
}
@media (max-width: 640px) {
  .home-article-card-wrap,
  .home-articles[data-count="2"] .home-article-card-wrap {
    flex: 1 1 100%; max-width: 100%;
  }
}
/* Sponsor-written cards (Stage 4): bold outline so the "Sponsored"
   treatment reads even before the badge. Outline keeps layout stable. */
.home-article-card--sponsored {
  outline: 2px solid var(--ink, #1a1a1a); outline-offset: 3px;
  border-radius: 3px;
}
/* "Sponsored" flag sits OUTSIDE the card box, pinned to the top-left
   above the outline (offset 3px). Reuses the .article-badge--sponsored
   colour token; positioned via the position:relative card wrap. */
.home-article-sponsored-flag {
  position: absolute; top: -13px; left: -3px; z-index: 2;
}
/* Contributor-written cards: a green outline (the shared #5a9e78
   contributor colour, lighter than the old #3d6b50) — distinct from the
   sponsor bronze, and NOT a "Sponsored" treatment. Flows into the normal
   recent-article slots (no reservation). */
.home-article-card--contributor {
  outline: 2px solid #5a9e78; outline-offset: 3px;
  border-radius: 3px;
}
.home-article-thumb {
  aspect-ratio: 16/9; max-height: 180px; overflow: hidden;
}
.home-article-thumb img {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.home-article-lede {
  font-family: Inter, system-ui, sans-serif;
  font-size: var(--article-card-abstract-size, 10px); line-height: 1.5; font-style: italic;
  color: var(--ink, #1a1a1a); opacity: 0.78;
  margin: 6px 0 0;
}
/* Homepage ARTICLE card abstract: THREE lines, ellipsis on overflow (620-447
   — it was `white-space:nowrap` since 58b7016, which is one line whatever the
   card's width, so every abstract was cut mid-sentence). Shares
   --article-card-abstract-size with the /articles card (defined in
   articles.css). The modifier keeps this off the news home card, which
   reuses .home-article-lede with its own inline size. */
.home-article-lede--clamp {
  display: -webkit-box; -webkit-box-orient: vertical;
  -webkit-line-clamp: 3; line-clamp: 3;
  overflow: hidden;
}

/* ── /projects map heat-layer controls (v5.072) ────────────────────── */
.heat-controls {
  display: flex; flex-wrap: wrap; gap: 24px; align-items: center;
  padding: 12px 0 16px;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted);
}
.heat-controls .heat-group {
  display: flex; align-items: center; gap: 12px;
}
.heat-controls .heat-label {
  color: var(--muted-2); font-weight: 500;
}
.heat-controls label.radio {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--ink); cursor: pointer; text-transform: none;
  letter-spacing: 0.02em; font-size: 12px;
}
.heat-controls label.radio.is-disabled {
  color: var(--muted); cursor: not-allowed;
}
.heat-controls label.radio input[type="radio"] {
  accent-color: var(--ink);
}
.heat-disabled-hint {
  font-size: 10.5px; font-style: italic; color: var(--muted);
  text-transform: none; letter-spacing: 0.02em;
}
.heat-footnote {
  font-size: 11.5px; font-style: italic; color: var(--muted);
  margin-top: 10px;
}
.heat-legend {
  position: absolute; right: 12px; bottom: 12px; z-index: 500;
  background: var(--bone); border: 1px solid var(--border);
  padding: 10px 12px; min-width: 160px;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.04em;
  color: var(--ink);
}
.heat-legend .legend-title {
  font-size: 9.5px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--muted-2); margin-bottom: 6px;
}
.heat-legend .legend-row {
  display: flex; align-items: center; gap: 8px; margin: 2px 0;
}
.heat-legend .legend-swatch {
  width: 14px; height: 14px; flex: none; border: 1px solid var(--border-2);
}
#listing-map { position: relative; }
@media (max-width: 640px) {
  .heat-controls { gap: 14px; }
  .heat-controls .heat-group { gap: 8px; flex-wrap: wrap; }
  .heat-legend { right: 6px; bottom: 6px; min-width: 130px; padding: 8px 10px; }
}

/* ── /products + /studios listing ──────────────────────────────────── */
.listing-toolbar {
  display: flex; flex-wrap: wrap; gap: 12px; align-items: center;
  padding: 14px 0 18px; border-bottom: 1px solid var(--border);
  margin-bottom: 18px;
}
.view-toggle {
  display: inline-flex; border: 1px solid var(--border); border-radius: 999px;
  overflow: hidden; background: var(--bone);
}
.view-toggle a, .view-toggle .is-disabled {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em;
  text-transform: uppercase; padding: 8px 16px; color: var(--muted);
}
.view-toggle a.is-active { background: var(--ink); color: var(--bone); }
.view-toggle a:hover:not(.is-active) { color: var(--umber); }
.view-toggle .is-disabled { opacity: 0.4; cursor: not-allowed; }
.chip-row {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
}
.chip {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em;
  text-transform: uppercase; padding: 7px 12px;
  border: 1px solid var(--border); border-radius: 999px;
  color: var(--ink); background: var(--bone); cursor: pointer;
}
.chip.is-on { background: var(--ink); color: var(--bone); border-color: var(--ink); }
.chip:hover { border-color: var(--umber); }
.chip-groups { display: flex; flex-direction: column; gap: 10px; width: 100%; }
.chip-group { display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline; }
.chip-group-label {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--muted); min-width: 64px;
}
/* v0.5.692 — per-view facet as TABS (was a <details> accordion). One tab per
   mig-215 group, ONE panel visible at a time (switched client-side). A chip-
   search box (T5) filters chip names; a reset link (T4) clears everything;
   each tab shows a per-group selected "(N)" (T3). Zero-count chips stay greyed
   + disabled (kept, never removed) so the facet shape is stable. */
.facet-tabs-wrap { display: flex; flex-direction: column; gap: 8px; width: 100%; }
.facet-tabbar {
  display: flex; flex-wrap: nowrap; gap: 10px; align-items: center;
  border-bottom: 1px solid var(--border); padding-bottom: 6px;
}
/* v0.5.700 — tabs shrink/scroll so the controls cluster never wraps to a 2nd row */
.facet-tabs {
  display: flex; flex-wrap: nowrap; gap: 6px; align-items: center;
  flex: 1 1 auto; min-width: 0; overflow-x: auto;
}
.facet-controls {
  display: flex; flex-wrap: nowrap; gap: 8px; align-items: center;
  flex: 0 0 auto;   /* controls group hugs the right, never shrinks/wraps */
  margin-left: auto;
}
.facet-tab {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--muted); cursor: pointer;
  background: none; border: none; padding: 6px 8px; border-radius: 6px;
}
.facet-tab.is-active { color: var(--ink); background: rgba(0, 0, 0, 0.05); }
.facet-tab:hover { color: var(--umber); }
.facet-tab.has-search-hit { color: var(--umber); box-shadow: inset 0 -2px 0 var(--umber); }
.facet-tab-count { color: var(--umber); }
.facet-chip-search {
  font-family: var(--sans); font-size: 12px;
  color: var(--ink); background: #fff; border: 1px solid var(--border);
  border-radius: 999px; padding: 5px 12px; min-width: 160px;
}
.facet-panels { display: contents; }               /* wrapper is layout-neutral when open */
.facet-panels.is-collapsed { display: none; }       /* v0.5.697 — collapse hides all panels */
.facet-panel { display: none; flex-wrap: wrap; gap: 8px; align-items: baseline; }
.facet-panel.is-active { display: flex; }
/* v0.5.701 — collapse toggle is an arrow icon (chevron flips ▾/▸), sitting at the
   LEFT end of the divider between the tab row and the chip panels. The tab-row
   border-bottom IS the divider; align-self:flex-start + a negative top margin
   pulls the arrow up onto that line. */
.facet-collapse {
  display: inline-flex; align-items: center; justify-content: center;
  align-self: flex-start; margin-top: -18px;
  color: var(--muted); background: var(--bone);
  border: 1px solid var(--border); border-radius: 999px;
  width: 30px; height: 28px; padding: 0; cursor: pointer;
}
.facet-collapse-arrow { font-size: 11px; line-height: 1; }
.facet-collapse:hover { color: var(--umber); border-color: var(--umber); }
/* v0.5.700 — save-search is a bookmark-icon-only button. The FORM (empty, just a
   hidden input) stays display:contents; the BUTTON is a real clickable element. */
.save-search { display: contents; }
.save-search-btn {
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--muted); background: none;
  border: 1px solid var(--border); border-radius: 999px;
  width: 30px; height: 28px; padding: 0; cursor: pointer;
}
.save-search-icon { display: block; }
.save-search-btn:hover { color: var(--umber); border-color: var(--umber); }
/* Saved state reuses the .bm-toggle is-on fill (same --umber token) — the
   filled/empty glyph itself comes from the svg fill (currentColor vs none). */
.save-search-btn.is-on { color: var(--umber); border-color: var(--umber); }
.save-search-btn.is-disabled,
.save-search-btn:disabled { opacity: 0.35; cursor: not-allowed; }
.save-search-btn:disabled:hover { color: var(--muted); border-color: var(--border); }
.filter-reset {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted); text-decoration: underline;
  align-self: center; margin-left: auto;   /* v0.5.696 — bottom-RIGHT */
}
.filter-reset:hover { color: var(--umber); }
.chip .chip-count { color: var(--muted); font-size: 10px; }
.chip.is-on .chip-count { color: var(--bone); }
.chip.is-disabled {
  opacity: 0.4; cursor: not-allowed; border-style: dashed;
}
.chip.is-disabled:hover { border-color: var(--border); }
.listing-country { min-width: 180px; }
.listing-country select {
  font-family: var(--sans); font-size: 13px; color: var(--ink);
  background: #ffffff; border: 1px solid var(--border);
  border-radius: 999px; padding: 8px 14px; width: 100%;
}
/* v0.5.699 — the tom-select wrapper collapsed to ~1px when unsized inside the
   flex controls row; pin it to the country column width so it renders visibly. */
.listing-country .ts-wrapper { width: 100%; min-width: 180px; }
.listing-country .ts-control { border-radius: 999px; }
/* v0.5.694 — company-NAME search (server-side ?q=), LEFT of the facet tabs /
   chip-search. Positioned relative so the autocomplete list anchors under it. */
/* v0.5.696 — name-search on the RIGHT of the tab row (margin-left:auto absorbs
   the free space, carrying it + the chip-search to the right; country stays
   left, after the tabs). */
.listing-name-search { position: relative; }
.listing-name-input {
  font-family: var(--sans); font-size: 12px; color: var(--ink);
  background: #ffffff; border: 1px solid var(--border);
  border-radius: 999px; padding: 5px 12px; min-width: 200px;
}
.name-suggest-list {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 40;
  margin: 0; padding: 4px; list-style: none;
  background: var(--bone); border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12); max-height: 260px; overflow-y: auto;
}
.name-suggest-item {
  font-family: var(--sans); font-size: 13px; color: var(--ink);
  padding: 7px 10px; border-radius: 6px; cursor: pointer;
}
.name-suggest-item:hover { background: rgba(0, 0, 0, 0.06); color: var(--umber); }
/* v0.5.339 — /studios + /products logo grid. Its own class (NOT the
   shared .project-grid, which the /projects catalog image cards use) so
   the logo tiles can run 6-wide on desktop with smaller logos while the
   catalog stays 4-wide. .company-logo is width:100%, so column count
   drives logo size automatically. Responsive ladder:
   ≥1280:6 · ≤1280:5 · ≤1024:4 · ≤768:3 · ≤520:2. */
.company-grid {
  display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 20px;
}
@media (max-width: 1280px) { .company-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
@media (max-width: 1024px) { .company-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (max-width: 768px)  { .company-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 520px)  { .company-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.company-tile {
  position: relative;
  display: flex; flex-direction: column; gap: 8px;
  border: 1px solid var(--border); border-radius: 6px;
  padding: 16px; background: var(--bone);
}
.company-tile:hover { border-color: var(--umber); }
.company-logo {
  aspect-ratio: 1/1; width: 100%; border-radius: 4px;
  background: var(--bone-2); overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.company-logo img { width: 100%; height: 100%; object-fit: contain; padding: 8%; }
.company-logo-placeholder {
  font-family: var(--mono); font-size: 36px; color: var(--muted);
}
/* Free supplier (stub) — neutral mark, no brand letter. A small muted
   square keeps the tile dignified without implying a missing logo. */
.company-logo-placeholder-stub {
  width: 22px; height: 22px; border-radius: 3px;
  background: var(--border-2);
}
.company-tile h3 {
  font-family: var(--sans); font-weight: 500; font-size: 15px;
  line-height: 1.25; color: var(--ink); margin: 0;
}
.company-tile .tile-country {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted);
}
.company-tile .tile-cats {
  display: flex; flex-wrap: wrap; gap: 4px;
}
.company-tile .tile-cat {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted);
  padding: 3px 8px; border: 1px solid var(--border-2); border-radius: 999px;
}

/* Free-supplier stub page — dignified, minimal. Reuses .section tokens. */
.supplier-stub-bio {
  font-family: var(--sans); font-size: 15px; line-height: 1.6;
  color: var(--ink); max-width: 640px; margin: 14px 0 0;
}
/* The "ask to be linked" line (735-395). ONE component, two surfaces: the
   stub keeps its wider top margin through .supplier-stub-claim, the studio
   hero takes the base rule. Same tokens either way — no parallel component. */
.company-claim-line {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.04em;
  color: var(--muted); margin-top: 14px;
}
.company-claim-line a { color: var(--forest); text-decoration: underline; }
.supplier-stub-claim { margin-top: 28px; }

#listing-map {
  height: 70vh; min-height: 480px; width: 100%;
  border: 1px solid var(--border); border-radius: 6px; overflow: hidden;
}
/* All map markers (dots + logo pins, both highlight states) now come
   from the shared factory app/static/shared/map_markers.js, which
   self-injects its own CSS. Marker styling lives ONLY there. */

.company-tile-link {
  text-decoration: none; color: inherit; display: flex;
  flex-direction: column; gap: 8px;
}
.company-tile.is-featured { border-color: #6d28d9; }
.company-tile h3 { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.tile-pill {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.08em;
  text-transform: uppercase; font-weight: 600;
  padding: 2px 7px; border: 1px solid currentColor; border-radius: 999px;
  white-space: nowrap;
}
.tile-pill-pro      { color: #1d4ed8; }
.tile-pill-free     { color: var(--muted, #6b7280); }

.company-popup .name { font-weight: 600; font-size: 14px; color: var(--ink); }
.company-popup .name a { color: var(--ink); text-decoration: underline; }
.company-popup .country {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted); margin-top: 2px;
}
.company-popup .cats { margin-top: 6px; display: flex; flex-wrap: wrap; gap: 3px; }
.company-popup .cats span {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted);
  padding: 2px 7px; border: 1px solid var(--border-2); border-radius: 999px;
}

@media (max-width: 1024px) {
  .feat-layout { grid-template-columns: 1fr; gap: 24px; }
  .feat-sponsor-col { grid-template-rows: auto auto; min-height: 0; }
  .feat-sponsor.placeholder-vertical { position: static; height: auto; }
  .feat-top { grid-template-columns: 1fr; }
  .feat-bottom { grid-template-columns: repeat(2, 1fr); }
  .tile-lead .tile-title { font-size: 32px; }
  .stats-grid { grid-template-columns: repeat(2, 1fr); }
  .footer-inner { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 760px) {
  .masthead { justify-content: center; text-align: center; }
  .masthead-stats { text-align: center; }
  .ribbon { flex-wrap: nowrap; overflow-x: auto; }
  .ribbon-cell { flex: 0 0 auto; }
  .feat-bottom { grid-template-columns: 1fr; }
  .section-h { font-size: 28px; }
  .stats-grid { grid-template-columns: 1fr; }
  .placeholder { grid-template-columns: 1fr; }
  .footer-inner { grid-template-columns: 1fr; }
}

/* ── Bookmarks (v0.5.101) ───────────────────────────────────────────
   .bm-toggle: the icon button placed on project cards, the project
   page title block, and over gallery images. Outline by default;
   .is-on fills the bookmark. Cards/list rows put it in the top-right;
   gallery tiles use .bm-overlay for the semi-opaque chip background. */
.bm-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 0; padding: 4px; margin: 0;
  color: var(--ink); cursor: pointer; line-height: 0;
  border-radius: 999px;
  transition: color 0.15s, background 0.15s, transform 0.1s;
}
.bm-toggle:hover  { color: var(--umber); }
.bm-toggle:active { transform: scale(0.92); }
.bm-toggle.is-on  { color: var(--umber); }
.bm-toggle:focus-visible {
  outline: 2px solid var(--umber); outline-offset: 1px;
}
.bm-toggle[disabled] { opacity: 0.5; cursor: not-allowed; }

/* Card-corner positioning. Project grid cards mark their parent with
   position:relative and use .bm-card-corner for the absolute placement. */
.bm-card-corner {
  position: absolute; top: 8px; right: 8px; z-index: 2;
  background: rgba(255, 255, 255, 0.92);
  box-shadow: 0 1px 3px rgba(0,0,0,0.15);
}
.bm-card-corner:hover { background: #fff; }

/* Gallery image overlay variant — translucent dark chip so it reads
   on any background image. Shown always on touch / always visible. */
.bm-overlay {
  position: absolute; top: 8px; right: 8px; z-index: 3;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
}
.bm-overlay:hover { background: rgba(0, 0, 0, 0.78); color: #fff; }
.bm-overlay.is-on { color: #ffd766; background: rgba(0,0,0,0.7); }

/* Project page title bar inline variant — sits beside the share/cite
   buttons in the rail. */
.bm-title-inline {
  border: 1px solid var(--border);
  padding: 6px 10px; border-radius: 999px;
  font-family: var(--mono); font-size: 11px;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink); display: inline-flex; gap: 6px;
}
.bm-title-inline:hover { border-color: var(--umber); color: var(--umber); }
.bm-title-inline.is-on { color: var(--umber); border-color: var(--umber); }

/* ── /account bookmarks dashboard ───────────────────────────────── */
.bm-dashboard {
  display: grid; grid-template-columns: 240px 1fr; gap: 28px;
  margin-top: 8px;
}
.bm-side h3 {
  font-family: var(--mono); font-size: 11px;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--muted); margin: 0 0 10px;
}
.bm-folder-list {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 2px;
}
.bm-folder-row {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px; border-radius: 4px;
  font-size: 14px; color: var(--ink); cursor: pointer;
  position: relative;
}
.bm-folder-row:hover { background: var(--bone-2); }
.bm-folder-row.is-active { background: var(--bone-2); font-weight: 500; }
.bm-folder-row.is-drop-target {
  outline: 2px dashed var(--umber); background: var(--bone-2);
}
.bm-folder-star {
  font-size: 14px; color: var(--umber); width: 14px; text-align: center;
  flex-shrink: 0;
}
.bm-folder-name { flex: 1 1 auto; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.bm-folder-count {
  font-family: var(--mono); font-size: 11px; color: var(--muted);
  flex-shrink: 0;
}
.bm-folder-actions {
  display: none; gap: 6px; flex-shrink: 0;
}
.bm-folder-row:hover .bm-folder-actions { display: inline-flex; }
.bm-folder-actions button {
  background: transparent; border: 0; padding: 2px;
  font-size: 11px; color: var(--muted); cursor: pointer;
}
.bm-folder-actions button:hover { color: var(--umber); }

.bm-new-folder {
  display: flex; gap: 6px; margin-top: 10px;
}
.bm-new-folder input {
  flex: 1 1 auto; min-width: 0;
  padding: 7px 10px; border: 1px solid var(--border-2);
  border-radius: 2px; font: inherit;
}
.bm-new-folder button {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 7px 12px; border: 1px solid var(--ink);
  background: var(--ink); color: var(--bone);
  border-radius: 2px; cursor: pointer;
}

.bm-list-head {
  display: flex; align-items: center; gap: 14px;
  padding-bottom: 12px; border-bottom: 1px solid var(--border);
  margin-bottom: 14px;
}
.bm-list-head select {
  padding: 6px 8px; border: 1px solid var(--border-2);
  font: inherit; font-size: 13px; border-radius: 2px;
}
.bm-list-empty {
  padding: 36px 12px; text-align: center; color: var(--muted);
  font-size: 14px;
}
.bm-list {
  display: flex; flex-direction: column; gap: 8px;
}
.bm-card {
  display: grid; grid-template-columns: 96px 1fr auto auto;
  align-items: center; gap: 14px;
  padding: 10px 12px; border: 1px solid var(--border);
  border-radius: 4px; background: #fff;
}
.bm-card[draggable="true"] { cursor: grab; }
.bm-card.is-dragging { opacity: 0.4; }
.bm-card-thumb {
  width: 96px; height: 64px; background: var(--bone-2);
  border-radius: 2px; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  color: var(--muted-2); font-family: var(--mono);
  font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase;
}
.bm-card-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bm-card-body { min-width: 0; }
.bm-card-title {
  font-size: 14px; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bm-card-title a { color: inherit; }
.bm-card-title a:hover { color: var(--umber); }
.bm-card-sub {
  font-family: var(--mono); font-size: 11px; color: var(--muted);
  letter-spacing: 0.04em; margin-top: 4px;
}
.bm-card-type {
  display: inline-block; padding: 2px 8px; border: 1px solid var(--border-2);
  border-radius: 999px; font-family: var(--mono); font-size: 10px;
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted);
}
.bm-card-kebab {
  position: relative;
}
.bm-card-kebab > button {
  background: transparent; border: 0; padding: 4px 8px;
  font-size: 18px; color: var(--muted); cursor: pointer; border-radius: 4px;
}
.bm-card-kebab > button:hover { background: var(--bone-2); color: var(--ink); }
.bm-card-menu {
  position: absolute; top: 100%; right: 0; z-index: 50;
  background: #fff; border: 1px solid var(--border-2);
  border-radius: 4px; min-width: 200px; padding: 6px;
  box-shadow: 0 6px 16px rgba(0,0,0,0.08);
  display: none;
}
.bm-card-menu.is-open { display: block; }
.bm-card-menu button, .bm-card-menu .bm-menu-item {
  display: block; width: 100%; text-align: left;
  padding: 7px 10px; background: transparent; border: 0;
  font: inherit; font-size: 13px; color: var(--ink);
  cursor: pointer; border-radius: 3px;
}
.bm-card-menu button:hover, .bm-card-menu .bm-menu-item:hover {
  background: var(--bone-2);
}
.bm-card-menu hr {
  border: 0; border-top: 1px solid var(--border); margin: 4px 0;
}
.bm-card-menu .bm-menu-section {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted-2);
  padding: 6px 10px;
}

@media (max-width: 720px) {
  .bm-dashboard { grid-template-columns: 1fr; }
  .bm-card { grid-template-columns: 72px 1fr auto; }
  .bm-card-type { display: none; }
}

/* v0.5.102 — bookmark-card list refinements.
   bm-card-list-icon: small fill state always visible in the card rail.
   Hover/active styling matches the umber accent used elsewhere. */
.bm-card { grid-template-columns: 96px 1fr auto auto; }
.bm-card-list-icon {
  color: var(--umber);
  padding: 6px;
}
.bm-card-list-icon:hover { color: #6d4429; }

/* 620-209 — per-bookmark free note. Full-width row under the card,
   editable ONLY on the bookmarks page (the toggle never asks for one). */
.bm-card-note { grid-column: 1 / -1; }
.bm-card-note textarea {
  width: 100%; box-sizing: border-box; resize: vertical;
  min-height: 32px; margin: 0;
  padding: 6px 8px; border: 1px solid var(--border);
  border-radius: 3px; background: var(--bone-2);
  font-family: var(--mono); font-size: 11px; line-height: 1.5;
  letter-spacing: 0.03em; color: var(--ink);
}
.bm-card-note textarea:focus {
  background: #fff; border-color: var(--umber); outline: none;
}
.bm-card-note textarea.is-saved { border-color: #2f6b3a; }

/* ── P3.3 — Stats ribbon (2-row compact) + Upcoming events widget.
   Signed-in homepage layout: stats wrap to 2 rows on the left, widget
   on the right. Anonymous visitors keep the original single-row
   .ribbon. */
.ribbon-with-events {
  max-width: var(--maxw); margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(260px, 36%);
  gap: 0;
  border-bottom: 0.5px solid var(--border);
  align-items: stretch;
}
.ribbon-with-events .ribbon--compact {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  align-items: stretch;
  padding: 0 var(--gutter);
  overflow: visible;
  border-bottom: 0;
  border-right: 1px solid var(--border);
}
.ribbon-with-events .ribbon--compact .ribbon-cell {
  padding: 14px 12px;
  border-right: 1px solid var(--border);
  border-top: 1px solid var(--border);
  white-space: nowrap;
}
/* Drop the top-border on the first row so the strip's top edge stays
   clean (matches the original single-row ribbon's top edge). */
.ribbon-with-events .ribbon--compact .ribbon-cell:nth-child(-n+4) {
  border-top: 0;
}
.ribbon-with-events .ribbon--compact .ribbon-cell:nth-child(4n) {
  border-right: 0;
}

.upcoming-events-widget {
  padding: 14px var(--gutter);
  display: flex; flex-direction: column;
  font-family: var(--sans);
  min-width: 0;
}
.upcoming-events-head {
  display: flex; align-items: center; gap: 8px;
  font-family: var(--mono);
  font-size: 11px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted);
  margin-bottom: 8px;
}
.upcoming-events-icon { font-size: 14px; }
.upcoming-events-list {
  display: flex; flex-direction: column; gap: 8px;
  /* Show ~2 events worth, scroll the rest. */
  max-height: 116px;
  overflow-y: auto;
  scrollbar-width: thin;
}
.upcoming-event {
  display: block; padding: 6px 8px;
  border: 0.5px solid var(--border);
  border-radius: 4px;
  text-decoration: none; color: inherit;
  background: transparent;
}
.upcoming-event:hover { background: rgba(0,0,0,0.03); }
.upcoming-event-title {
  font-weight: 500; font-size: 13px; color: var(--ink);
  line-height: 1.3;
  /* Single-line clamp so a long headline doesn't blow the widget out. */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.upcoming-event-meta {
  display: flex; flex-wrap: wrap; gap: 6px;
  font-size: 11px; color: var(--muted); margin-top: 2px;
  align-items: baseline;
}
.upcoming-event-countdown {
  margin-left: auto;
  font-family: var(--mono);
  font-weight: 500;
  letter-spacing: 0.02em;
}
.upcoming-event-countdown.is-urgent {
  color: #c1342f;  /* Studio "urgent" red, matches publish-warnings */
}
.upcoming-events-empty {
  font-size: 12px; color: var(--muted); font-style: italic;
  padding: 6px 0;
}

@media (max-width: 720px) {
  /* Mobile: widget stacks below the (now full-width) stats grid. */
  .ribbon-with-events {
    grid-template-columns: 1fr;
  }
  .ribbon-with-events .ribbon--compact {
    border-right: 0;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .ribbon-with-events .ribbon--compact .ribbon-cell:nth-child(4n) {
    border-right: 1px solid var(--border);
  }
  .ribbon-with-events .ribbon--compact .ribbon-cell:nth-child(2n) {
    border-right: 0;
  }
  .ribbon-with-events .ribbon--compact .ribbon-cell:nth-child(-n+4) {
    border-top: 1px solid var(--border);
  }
  .ribbon-with-events .ribbon--compact .ribbon-cell:nth-child(-n+2) {
    border-top: 0;
  }
  .upcoming-events-widget {
    border-top: 1px solid var(--border);
  }
}

/* ── Shared image credit/caption overlay (single source) ─────────────
   Used by tile_overlay() in partials/_image_overlay.html. Credit chip
   always visible (small, legible on light + dark via dark pill); caption
   card on hover (desktop) / tap (touch). NEVER fork per surface. */
.img-meta {
  position: absolute; inset: 0; pointer-events: none; z-index: 3;
}
.img-credit {
  position: absolute; left: 6px; bottom: 6px; max-width: calc(100% - 12px);
  font-family: var(--mono); font-size: 9px; line-height: 1.3;
  letter-spacing: 0.05em; text-transform: uppercase;
  color: #fff; background: rgba(0,0,0,0.55);
  padding: 2px 6px; border-radius: 3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  text-shadow: 0 1px 2px rgba(0,0,0,0.45); pointer-events: none;
}
.img-caption-toggle {
  position: absolute; right: 6px; bottom: 6px;
  width: 20px; height: 20px; border: 0; border-radius: 50%;
  background: rgba(0,0,0,0.55); color: #fff;
  font-family: var(--mono); font-size: 11px; font-style: italic; line-height: 20px;
  text-align: center; cursor: pointer; pointer-events: auto; display: none;
}
.img-caption-card {
  position: absolute; left: 6px; right: 6px; bottom: 6px;
  background: rgba(0,0,0,0.82); color: #fff;
  padding: 10px 12px; border-radius: 4px; pointer-events: none;
  opacity: 0; transform: translateY(4px); transition: opacity .15s, transform .15s;
}
.img-caption-card .icc-caption {
  font-size: 8.8px; line-height: 1.45;
}
.img-caption-card .icc-credit {
  margin-top: 6px;
  font-family: var(--mono); font-size: 7.7px; letter-spacing: 0.05em;
  text-transform: uppercase; color: rgba(255,255,255,0.82);
}
/* SOURCE = provenance, not a rights claim: dimmer + italic to distinguish */
.img-credit--source { font-style: italic; }
/* CONFIRMED photographer (T6): a real link, so it must be clickable (the base
   chip is pointer-events:none). Violet tint echoes the Photographer badge. */
.img-credit--photographer {
  pointer-events: auto; text-decoration: none;
  background: rgba(124,58,237,0.72); color: #fff;
}
.img-caption-card .icc-source {
  margin-top: 4px;
  font-family: var(--mono); font-size: 7.7px; letter-spacing: 0.05em;
  text-transform: lowercase; color: rgba(255,255,255,0.6); font-style: italic;
}
/* desktop: hover reveals caption card, hides the always-visible credit chip */
@media (hover: hover) {
  *:hover > .img-meta > .img-caption-card { opacity: 1; transform: translateY(0); }
  *:hover > .img-meta:has(.img-caption-card) > .img-credit { opacity: 0; }
}
/* touch: tap the (i) toggle to reveal */
@media (hover: none) {
  .img-meta .img-caption-toggle { display: block; }
  .img-meta.show .img-caption-card { opacity: 1; transform: translateY(0); pointer-events: auto; }
  .img-meta.show .img-credit { opacity: 0; }
}

/* Lightbox credit/caption bar (focused view: credit always shown) */
.lightbox-meta {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 14px 20px; text-align: center; color: #fff;
  background: linear-gradient(to top, rgba(0,0,0,0.6), rgba(0,0,0,0));
  pointer-events: none;
}
.lightbox-meta .lm-caption { font-size: 14px; line-height: 1.5; }
.lightbox-meta .lm-credit {
  margin-top: 6px;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em;
  text-transform: uppercase; color: rgba(255,255,255,0.85);
}
.lightbox-meta .lm-source {
  margin-top: 4px;
  font-size: 11px; font-style: italic;
  color: rgba(255,255,255,0.6);
}
.lightbox-meta:empty { display: none; }

/* Machine-translation notice banner (shared; project pages). Same affordance
   + i18n keys as the article banner, styled on the public palette tokens. */
.mt-banner {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 0 0 18px; padding: 10px 14px;
  background: var(--bone-2); border: 1px solid var(--border-2); border-radius: 6px;
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.02em;
  color: var(--muted);
}
.mt-banner__icon { font-size: 14px; }
.mt-banner__link {
  color: var(--forest); font-weight: 500; text-decoration: underline;
}
.mt-banner__link:hover { opacity: 0.8; }

/* ── Anonymous-visitor content gate (shared: project_page + articles) ──────
   Single source for the shared/_content_gate.html partial. Both the top
   "unlock" banner (.gate-cta) and the per-section "more" gate (.section-gate)
   render through that ONE partial; never fork these classes. */
.gate-cta {
  background: #1f3a2b; color: #f4f1e8;
  padding: 22px 26px; margin: 24px 0 28px;
  display: grid; grid-template-columns: 40px 1fr auto; gap: 20px; align-items: center;
  border: 1px solid #16271d;
}
.gate-cta .gate-icon { display: inline-grid; place-items: center; opacity: 0.9; }
.gate-cta .gate-copy { font-size: 14.5px; line-height: 1.45; color: #e9e4d6; }
.gate-cta .gate-copy strong { color: #fff; font-weight: 500; }
.gate-cta .gate-actions { display: flex; gap: 10px; }
.gate-btn {
  display: inline-block; padding: 8px 16px; font-size: 13px; font-family: var(--sans, Inter);
  border-radius: 2px; cursor: pointer; text-decoration: none;
  border: 1px solid #fff;
}
.gate-btn-primary { background: #fff; color: #1f3a2b; }
.gate-btn-primary:hover { background: #f0ebd9; }
.gate-btn-outline { background: transparent; color: #fff; }
.gate-btn-outline:hover { background: rgba(255,255,255,0.1); }
.section-gate {
  position: relative; margin: 12px 0 0;
  padding: 18px 16px 16px;
  background: linear-gradient(to bottom, rgba(247,245,239,0) 0%, var(--bone-2) 60%);
  border-top: 1px dashed var(--border-2);
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  font-size: 13px; color: var(--muted-2);
}
.section-gate .section-gate-text { display: flex; align-items: center; gap: 8px; }
.section-gate a { color: var(--ink, #111); text-decoration: underline; }
/* Anon article teaser: soft fade over the tail of the shown blocks (opaque
   top, transparent by the bottom edge) so the teaser dissolves into the gate
   instead of a hard cut. CSS-only; applied only when the body is gated. */
.article-teaser-fade {
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 60%, transparent 100%);
          mask-image: linear-gradient(to bottom, #000 0%, #000 60%, transparent 100%);
}

/* TEMP: non-sponsor tag-count teaser (company pages). Remove later. Reuses
   the green/bone tokens — no parallel component. */
.company-tag-teaser {
  margin: 0 0 22px; padding: 16px 18px;
  background: var(--bone-2, #f2efe6);
  border: 1px solid var(--border-2, #d9d3c4);
  border-left: 3px solid var(--forest, #1F3D2E);
  border-radius: 3px;
}
.company-tag-teaser-copy {
  margin: 0; font-size: 14px; line-height: 1.5; color: var(--muted-2, #5a5449);
}
.company-tag-teaser-count {
  margin: 8px 0 0; font-size: 13.5px; color: var(--ink, #1f2a24);
}
.company-tag-teaser-count strong { font-size: 20px; font-weight: 600; color: var(--forest, #1F3D2E); }
.company-potential-band {
  margin: 0 0 22px; padding: 14px 18px;
  background: var(--bone-2, #f2efe6);
  border: 1px solid var(--border-2, #d9d3c4);
  border-radius: 3px;
  font-size: 13.5px; line-height: 1.5; color: var(--muted-2, #5a5449);
}
