/* Copyright (c) 2024 Ryan Leckey Media. All rights reserved.
   No use, distribution, or modification is permitted without prior written permission. */

/* ==========================================================================
   V2 supplement for the SEO landing pages (/marketing/, /industries/).

   The landing pages are built from the V2 design system: .v2-section,
   .v2-container, .v2-bento, .btn-v2, .label-line, .grad-text and .reveal
   all come from v2.css. This file adds only the components those
   pages need that V2 did not already have, using V2 tokens so nothing here
   introduces a second palette:

     .seo-crumb   breadcrumb trail
     .seo-chip    town / county / service pills (the internal-link rails)
     .seo-fact    small factual statement card
     .v2-orbit    same rail of links, arranged as a hub-and-spoke diagram
                  (market pages); falls back to plain .seo-chip pills
                  below the build width and with JS disabled

   Everything is scoped under .v2 to match v2.css specificity.
   ========================================================================== */

/* ---------------------------------------------------------------- breadcrumb */

.v2 .seo-crumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  font-family: var(--font-body);
  font-size: 0.82rem;
  letter-spacing: 0.01em;
  margin-bottom: 20px;
  color: rgba(255, 255, 255, 0.7);
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.55);
}
.v2 .seo-crumb a {
  color: rgba(255, 255, 255, 0.92);
  text-decoration: none;
  transition: color 0.25s var(--ease-out);
}
.v2 .seo-crumb a:hover { color: var(--c-cyan); }
.v2 .seo-crumb span[aria-hidden] { color: rgba(255, 255, 255, 0.7); }
/* The current page (the trailing span with no href and no aria-hidden)
   was inheriting the same dim color as the "/" separators, which made it
   read as the least important thing in the trail instead of the most. */
.v2 .seo-crumb span:not([aria-hidden]) {
  color: #fff;
  font-weight: 700;
}

/* --------------------------------------------------------------------- chips */

.v2 .seo-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 28px;
}

.v2 .seo-chip {
  display: inline-flex;
  align-items: center;
  padding: 9px 18px;
  border-radius: 999px;
  font-family: var(--font-body);
  font-size: 0.9rem;
  font-weight: 500;
  line-height: 1.2;
  text-decoration: none;
  color: var(--fg-2);
  background: rgba(255, 255, 255, 0.035);
  border: 1px solid var(--bd-white);
  transition: transform 0.3s var(--ease-out), border-color 0.3s var(--ease-out),
              color 0.3s var(--ease-out), background 0.3s var(--ease-out);
}
.v2 .seo-chip:hover {
  transform: translateY(-2px);
  color: #fff;
  border-color: var(--bd-strong);
  background: rgba(0, 240, 255, 0.07);
}

/* Primary markets and "see everything" links, so the eye can tell the rails apart. */
.v2 .seo-chip--hot {
  border-color: rgba(255, 0, 240, 0.28);
  background: rgba(255, 0, 240, 0.05);
}
.v2 .seo-chip--hot:hover {
  border-color: rgba(255, 0, 240, 0.55);
  background: rgba(255, 0, 240, 0.1);
}

/* ---------------------------------------------------------- orbit diagram */

/* Base state: identical to .seo-chip. JS turns .v2-orbit-list's own <a>
   tags into this layout by adding .is-built to .v2-orbit-stage above it;
   without JS, or under the build width, the links just stay a plain
   wrapped list of chips. */
.v2 .v2-orbit-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 28px;
}

.v2 .v2-orbit-stage.is-built {
  position: relative;
  width: min(660px, 100%);
  aspect-ratio: 1 / 1;
  margin: 0 auto;
}

.v2 .v2-orbit-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.v2 .v2-orbit-stage.is-built .v2-orbit-list {
  position: absolute;
  inset: 0;
  display: block;
  margin: 0;
  /* This box spans the whole diagram; without this, its own empty area
     sits on top of the SVG lines and icon nodes and swallows every hover
     that isn't directly over a label's own small box. */
  pointer-events: none;
}

.v2 .v2-orbit-stage.is-built .v2-orbit-list a {
  position: absolute;
  display: block;
  pointer-events: auto;
  max-width: 132px;
  transform: translate(-50%, -50%) scale(1);
  padding: 2px 3px;
  border: 0;
  border-radius: 4px;
  background: none;
  font-size: 0.72rem;
  line-height: 1.25;
  text-align: center;
  color: rgba(255, 255, 255, 0.85);
  transition: color 0.25s var(--ease-out), transform 0.25s var(--ease-out);
}
.v2 .v2-orbit-stage.is-built .v2-orbit-list a:focus-visible {
  color: var(--c-cyan);
  background: none;
  transform: translate(-50%, -50%) translate(var(--grow-x, 0px), var(--grow-y, 0px)) scale(1.1);
}
/* Mouse hover only changes color, never position/scale. This label is a
   real clickable link sitting on top of the invisible hit-line that
   drives the hover state -- if it also moved in response to its own
   hover class, the move could cover or uncover a stationary cursor
   without the cursor itself moving, which retriggers hover on whatever's
   now on top and flickers for the whole transition. Keyboard focus
   (above) doesn't have this problem, since it isn't cursor-position
   driven, so it keeps the full grow effect. */
.v2 .v2-orbit-stage.is-built .v2-orbit-list a.is-hover,
.v2 .v2-orbit-stage.is-built .v2-orbit-list a.is-pulse {
  color: var(--c-cyan);
  background: none;
}
.v2 .v2-orbit-stage.is-built .v2-orbit-list a.align-left {
  text-align: left;
  transform: translate(2px, -50%) scale(1);
}
.v2 .v2-orbit-stage.is-built .v2-orbit-list a.align-right {
  text-align: right;
  transform: translate(calc(-100% - 2px), -50%) scale(1);
}
.v2 .v2-orbit-stage.is-built .v2-orbit-list a.align-left:focus-visible {
  transform: translate(2px, -50%) translate(var(--grow-x, 0px), var(--grow-y, 0px)) scale(1.1);
}
.v2 .v2-orbit-stage.is-built .v2-orbit-list a.align-right:focus-visible {
  transform: translate(calc(-100% - 2px), -50%) translate(var(--grow-x, 0px), var(--grow-y, 0px)) scale(1.1);
}

.v2 .v2-orbit-spoke {
  stroke: rgba(255, 255, 255, 0.15);
  stroke-width: 1.1;
  transform: scale(1);
  /* Decorative only, same reasoning as the node -- it also grows on
     hover, so it must not be able to intercept the pointer itself. */
  pointer-events: none;
  transition: stroke 0.25s var(--ease-out), stroke-width 0.25s var(--ease-out),
              transform 0.25s var(--ease-out);
}
.v2 .v2-orbit-spoke.is-hover {
  stroke: #00f0ff;
  stroke-width: 2;
  transform: scale(1.1);
}
.v2 .v2-orbit-spoke.is-pulse {
  stroke: #00f0ff;
  stroke-width: 1.5;
  transform: scale(1.04);
}
.v2 .v2-orbit-spoke-hit {
  stroke: transparent;
  stroke-width: 44;
  pointer-events: stroke;
  cursor: pointer;
}
.v2 .v2-orbit-hub-disc {
  fill: rgba(255, 255, 255, 0.03);
  stroke-width: 2;
}
.v2 .v2-orbit-hub-label {
  fill: #fff;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 15px;
  text-anchor: middle;
}

.v2 .v2-orbit-nodes { position: absolute; inset: 0; pointer-events: none; }

.v2 .v2-orbit-node {
  position: absolute;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Purely decorative now -- the hit-line underneath is the only thing
     that responds to hover, and this being on top of it in the DOM with
     pointer-events would otherwise swallow the pointer before it ever
     reaches that line, leaving a dead patch the size of the icon. */
  pointer-events: none;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: var(--grad);
  color: #fff;
  font-size: 1.05rem;
  transition: filter 0.25s var(--ease-out), transform 0.25s var(--ease-out),
              box-shadow 0.25s var(--ease-out);
}
.v2 .v2-orbit-node .icon-drone { width: 1.35em; height: 1.35em; }
.v2 .v2-orbit-node.is-hover {
  filter: brightness(1.18);
  transform: translate(-50%, -50%) translate(var(--grow-x, 0px), var(--grow-y, 0px)) scale(1.12);
  box-shadow: 0 0 22px rgba(0, 240, 255, 0.45);
}
.v2 .v2-orbit-node.is-pulse {
  filter: brightness(1.1);
  transform: translate(-50%, -50%) translate(var(--grow-x-sm, 0px), var(--grow-y-sm, 0px)) scale(1.05);
  box-shadow: 0 0 12px rgba(0, 240, 255, 0.3);
}

@media (prefers-reduced-motion: reduce) {
  .v2 .v2-orbit-spoke, .v2 .v2-orbit-node { transition: none; }
}

/* ------------------------------------------------------------- industry cards */

.v2 .seo-county.v2-industries-block h3 {
  text-align: center;
  font-size: clamp(1.9rem, 3.5vw, 2.6rem);
}

.v2 .seo-industry-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  max-width: 760px;
  margin: 28px auto 0;
}

.v2 .seo-industry-card {
  flex: 0 0 144px;
  aspect-ratio: 1 / 1;
  display: flex;
  flex-direction: column;
  padding: 8px;
  border-radius: var(--r-sm);
  border: 1px solid var(--bd-white);
  background: rgba(255, 255, 255, 0.03);
  text-decoration: none;
  text-align: center;
  transition: transform 0.3s var(--ease-out), border-color 0.3s var(--ease-out),
              background 0.3s var(--ease-out);
}
.v2 .seo-industry-card:hover {
  transform: translateY(-4px);
  border-color: var(--bd-strong);
  background: rgba(0, 240, 255, 0.06);
}

.v2 .seo-industry-icon {
  flex: 1 1 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: clamp(1.8rem, 5vw, 2.4rem);
  color: var(--c-cyan);
  transition: color 0.3s var(--ease-out);
}
.v2 .seo-industry-card:hover .seo-industry-icon { color: #fff; }

.v2 .seo-industry-label {
  flex: 1 1 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 4px;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.66rem;
  line-height: 1.2;
  color: var(--fg-2);
}

@media (prefers-reduced-motion: reduce) {
  .v2 .seo-industry-card, .v2 .seo-industry-icon { transition: none; }
}

/* ----------------------------------------------------------------- fact cards */

.v2 .seo-facts {
  display: grid;
  gap: 16px;
  margin-top: 36px;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}

.v2 .seo-fact {
  position: relative;
  padding: 24px;
  border-radius: var(--r);
  background: var(--bg-2);
  border: 1px solid var(--bd-white);
  overflow: hidden;
}
.v2 .seo-fact::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 2px;
  background: var(--grad);
  opacity: 0.7;
}
.v2 .seo-fact p {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--fg-3);
}

/* --------------------------------------------------------------- check lists */

.v2 .seo-check {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 14px;
}
.v2 .seo-check li {
  position: relative;
  padding-left: 32px;
  font-family: var(--font-body);
  font-size: 0.98rem;
  line-height: 1.6;
  color: var(--fg-3);
}
.v2 .seo-check li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.42em;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--grad);
}
/* Problem lists read differently from capability lists. */
.v2 .seo-check--warn li::before { background: linear-gradient(120deg, #ff8a0e, var(--c-pink)); }

/* --------------------------------------------------------------- two column */

.v2 .seo-split {
  display: grid;
  gap: clamp(28px, 4vw, 56px);
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  align-items: start;
  margin-top: 40px;
}
.v2 .seo-split h3 {
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0 0 18px;
  color: var(--fg);
}
.v2 .seo-split p {
  font-family: var(--font-body);
  font-size: 0.99rem;
  line-height: 1.75;
  color: var(--fg-3);
}
.v2 .seo-split p strong { color: var(--fg); font-weight: 600; }

/* A directory block per county on /marketing/. */
.v2 .seo-county + .seo-county { margin-top: 52px; }
.v2 .seo-county h3 {
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 2.4vw, 1.75rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  margin: 0;
}
.v2 .seo-county h3 a { color: var(--fg); text-decoration: none; }
.v2 .seo-county h3 a:hover { color: var(--c-cyan); }
.v2 .seo-county .count {
  font-family: var(--font-body);
  font-size: 0.85rem;
  font-weight: 400;
  color: var(--fg-4);
  margin-left: 10px;
}
.v2 .seo-county > p {
  font-family: var(--font-body);
  font-size: 0.96rem;
  line-height: 1.7;
  color: var(--fg-3);
  max-width: 78ch;
  margin: 10px 0 0;
}

@media (prefers-reduced-motion: reduce) {
  .v2 .seo-chip:hover { transform: none; }
}

/* ============================================================
   Industry roster on /industries/ — one row per vertical.
   Each row carries its own neon accent via --acc / --acc2;
   everything (beam, icon, eyebrow, chips, hover) derives from
   those two variables.
   ============================================================ */
.v2 .seo-roster { display: grid; gap: 14px; }

.v2 .seo-roster-row {
  --acc:  var(--c-cyan);
  --acc2: var(--c-pink);
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: 18px 48px;
  align-items: start;
  padding: 30px 34px 30px 38px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--bd-white);
  border-radius: var(--r-lg);
  text-decoration: none;
  overflow: hidden;
  isolation: isolate;
  transition: transform 0.45s var(--ease-out),
              border-color 0.45s ease,
              box-shadow 0.45s ease;
}
.v2 .seo-roster-row.acc-cyan    { --acc: #00f0ff; --acc2: #0080ff; }
.v2 .seo-roster-row.acc-magenta { --acc: #ff00f0; --acc2: #7a42ff; }
.v2 .seo-roster-row.acc-orange  { --acc: #ff8a0e; --acc2: #ffd400; }
.v2 .seo-roster-row.acc-violet  { --acc: #7a42ff; --acc2: #ff00f0; }
.v2 .seo-roster-row.acc-green   { --acc: #3dffa0; --acc2: #00f0ff; }
.v2 .seo-roster-row.acc-red     { --acc: #ff0040; --acc2: #ff8a0e; }

/* Accent beam on the left edge */
.v2 .seo-roster-row::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 4px;
  background: linear-gradient(180deg, var(--acc), var(--acc2));
  opacity: 0.85;
  z-index: 1;
}
/* Accent wash that floods in on hover */
.v2 .seo-roster-row::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(115deg,
              color-mix(in srgb, var(--acc) 14%, transparent),
              transparent 60%);
  opacity: 0;
  transition: opacity 0.45s ease;
  z-index: -1;
}
.v2 .seo-roster-row:hover,
.v2 .seo-roster-row:focus-visible {
  transform: translateX(8px);
  border-color: color-mix(in srgb, var(--acc) 55%, transparent);
  box-shadow: 0 18px 60px color-mix(in srgb, var(--acc) 20%, transparent);
}
.v2 .seo-roster-row:hover::after,
.v2 .seo-roster-row:focus-visible::after { opacity: 1; }

.v2 .seo-roster-id {
  display: flex;
  gap: 18px;
  align-items: center;
}
.v2 .seo-roster-icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px; height: 46px;
  border-radius: 14px;
  background: linear-gradient(135deg, var(--acc), var(--acc2));
  color: #0b0b0c;
  font-size: 1.05rem;
  box-shadow: 0 6px 22px color-mix(in srgb, var(--acc) 35%, transparent);
}
.v2 .seo-roster-name {
  font-family: var(--font-display);
  font-size: clamp(1.35rem, 2.2vw, 1.75rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.12;
  color: var(--fg);
  margin: 0;
}
.v2 .seo-roster-row:hover .seo-roster-name,
.v2 .seo-roster-row:focus-visible .seo-roster-name {
  background: linear-gradient(120deg, var(--acc), var(--acc2));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.v2 .seo-roster-body p {
  font-family: var(--font-body);
  font-size: 0.98rem;
  line-height: 1.7;
  color: var(--fg-3);
  margin: 0;
}
.v2 .seo-roster-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px 16px;
  margin-top: 18px;
}
.v2 .seo-roster-mix {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 8px;
}
.v2 .seo-roster-mix .chip {
  font-family: var(--font-body);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--acc) 40%, transparent);
  background: color-mix(in srgb, var(--acc) 8%, transparent);
  color: var(--fg-2);
  white-space: nowrap;
}
.v2 .seo-roster-go {
  font-family: var(--font-display);
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--acc);
  white-space: nowrap;
  margin-left: auto;
}
.v2 .seo-roster-go span {
  display: inline-block;
  transition: transform 0.35s var(--ease-out);
}
.v2 .seo-roster-row:hover .seo-roster-go span,
.v2 .seo-roster-row:focus-visible .seo-roster-go span { transform: translateX(6px); }

@media (max-width: 860px) {
  .v2 .seo-roster-row {
    grid-template-columns: 1fr;
    gap: 16px;
    padding: 24px 22px 24px 26px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .v2 .seo-roster-row,
  .v2 .seo-roster-row::after,
  .v2 .seo-roster-go span { transition: none; }
  .v2 .seo-roster-row:hover { transform: none; }
}

/* Roster variants: ranked rows (channel mix, where order = budget priority)
   and a two-column compact mode for cross-link blocks. */
.v2 .seo-roster-rank {
  flex: 0 0 auto;
  min-width: 46px;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.9rem;
  line-height: 1;
  color: var(--acc);
  text-align: center;
}
.v2 .seo-roster--duo { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.v2 .seo-roster--duo .seo-roster-row {
  grid-template-columns: 1fr;
  gap: 12px;
  padding: 24px 24px 24px 28px;
}
@media (max-width: 860px) {
  .v2 .seo-roster--duo { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------- market roster bento
   Landscape photo cards for the markets hub. Each card stacks its image and
   its text in the same grid cell rather than absolutely positioning the
   text over it, so a card with more copy (a longer summary, six city chips)
   can grow past the 16:9 preferred ratio instead of clipping -- the row
   track sizes to whichever child needs more room, image included. */

.v2 .v2-market-bento {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
  margin-top: 28px;
}

.v2 .v2-market-card {
  --acc:  var(--c-cyan);
  --acc2: var(--c-pink);
  display: block;
  aspect-ratio: 16 / 9;
  border-radius: var(--r-lg);
  overflow: hidden;
  position: relative;
  isolation: isolate;
  text-decoration: none;
  border: 1px solid var(--bd-white);
  transition: transform 0.45s var(--ease-out), border-color 0.45s ease,
              box-shadow 0.45s ease;
}
.v2 .v2-market-card.acc-cyan    { --acc: #00f0ff; --acc2: #0080ff; }
.v2 .v2-market-card.acc-magenta { --acc: #ff00f0; --acc2: #7a42ff; }
.v2 .v2-market-card.acc-orange  { --acc: #ff8a0e; --acc2: #ffd400; }
.v2 .v2-market-card.acc-violet  { --acc: #7a42ff; --acc2: #ff00f0; }
.v2 .v2-market-card.acc-green   { --acc: #3dffa0; --acc2: #00f0ff; }
.v2 .v2-market-card.acc-red     { --acc: #ff0040; --acc2: #ff8a0e; }

.v2 .v2-market-card img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: brightness(0.6);
  transition: transform 0.6s var(--ease-out), filter 0.4s var(--ease-out);
}
.v2 .v2-market-card:hover img,
.v2 .v2-market-card:focus-visible img {
  transform: scale(1.05);
  filter: brightness(0.7);
}

.v2 .v2-market-card-scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg,
              color-mix(in srgb, var(--acc) 22%, transparent) 0%,
              rgba(8, 8, 12, 0.3) 38%,
              rgba(8, 8, 12, 0.92) 100%);
}

.v2 .v2-market-card:hover,
.v2 .v2-market-card:focus-visible {
  transform: translateY(-4px);
  border-color: color-mix(in srgb, var(--acc) 55%, transparent);
  box-shadow: 0 18px 60px color-mix(in srgb, var(--acc) 25%, transparent);
}

.v2 .v2-market-card-content {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 8px;
  padding: clamp(16px, 2.6vw, 30px);
  box-sizing: border-box;
}

.v2 .v2-market-card-id {
  display: flex;
  gap: 12px;
  align-items: center;
}
.v2 .v2-market-card-icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px; height: 38px;
  border-radius: 12px;
  background: linear-gradient(135deg, var(--acc), var(--acc2));
  color: #0b0b0c;
  font-size: 0.92rem;
  box-shadow: 0 6px 22px color-mix(in srgb, var(--acc) 35%, transparent);
}
.v2 .v2-market-card-name {
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 1.8vw, 1.5rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: #fff;
  margin: 0;
}
.v2 .v2-market-card--featured .v2-market-card-name {
  font-size: clamp(1.3rem, 2vw, 1.65rem);
}

.v2 .v2-market-card-summary {
  font-family: var(--font-body);
  font-size: 0.88rem;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.82);
  margin: 0;
  max-width: 60ch;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.v2 .v2-market-card--featured .v2-market-card-summary {
  font-size: 0.92rem;
}

.v2 .v2-market-card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px 14px;
  margin-top: 4px;
}
.v2 .v2-market-card-mix {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 6px;
}
.v2 .v2-market-card-chip {
  font-family: var(--font-body);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  padding: 5px 10px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.28);
  /* No backdrop-filter here -- blurring what's behind each chip is one of
     the more expensive things a browser can paint, and with up to 4 per
     card across a whole grid of photos, it was a real contributor to the
     scroll lag. A plain darker fill reads the same over a photo without it. */
  background: rgba(10, 10, 14, 0.55);
  color: #fff;
  white-space: nowrap;
}
.v2 .v2-market-card-go {
  font-family: var(--font-display);
  font-size: 0.84rem;
  font-weight: 700;
  color: var(--acc);
  white-space: nowrap;
  margin-left: auto;
}
.v2 .v2-market-card-go span {
  display: inline-block;
  transition: transform 0.35s var(--ease-out);
}
.v2 .v2-market-card:hover .v2-market-card-go span,
.v2 .v2-market-card:focus-visible .v2-market-card-go span { transform: translateX(6px); }

@media (max-width: 640px) {
  .v2 .v2-market-bento { grid-template-columns: 1fr; }
  .v2 .v2-market-card { aspect-ratio: 4 / 3; }
}
@media (prefers-reduced-motion: reduce) {
  .v2 .v2-market-card,
  .v2 .v2-market-card img,
  .v2 .v2-market-card-go span { transition: none; }
  .v2 .v2-market-card:hover { transform: none; }
}

/* --------------------------------------------------------- market photo mosaic */

.v2 .v2-market-mosaic {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 160px;
  grid-auto-flow: dense;
  gap: 14px;
  margin-top: 28px;
}

.v2 .v2-market-tile {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--r);
  background: var(--bg-2);
  text-decoration: none;
}

.v2 .v2-market-tile img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: brightness(0.7);
  transition: transform 0.5s var(--ease-out), filter 0.4s var(--ease-out);
}
.v2 .v2-market-tile:hover img,
.v2 .v2-market-tile:focus-visible img {
  transform: scale(1.06);
  filter: brightness(0.85);
}

.v2 .v2-market-tile::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 45%, rgba(0, 0, 0, 0.8) 100%);
  pointer-events: none;
}

.v2 .v2-market-tile-label {
  position: absolute;
  left: 16px;
  right: 16px;
  bottom: 14px;
  z-index: 1;
  font-family: var(--font-display);
  font-weight: 800;
  letter-spacing: -0.01em;
  color: #fff;
  font-size: 1.05rem;
  line-height: 1.2;
}

/* A uniform grid never has a spare-sized "featured" tile to absorb whatever
   remainder is left over when the market count doesn't divide evenly by the
   column count -- so instead of one tile stretching to fill the gap, a
   trailing partial row is recentered instead of stranded on the left. Set
   server-side (locations/views.py:MarketDetailView) from the actual
   remainder against each breakpoint's own column count, so this keeps
   working no matter how many markets exist later. */
@media (min-width: 761px) {
  .v2 .v2-market-tile--center-a { grid-column: 2; }
  .v2 .v2-market-tile--center-b { grid-column: 3; }
  .v2 .v2-market-tile--center-span { grid-column: 2 / span 2; }
}

@media (max-width: 760px) {
  .v2 .v2-market-mosaic { grid-template-columns: repeat(2, 1fr); grid-auto-rows: 140px; }
  .v2 .v2-market-tile--mobile-full { grid-column: 1 / span 2; }
}
/* Phones: one market per row. */
@media (max-width: 560px) {
  .v2 .v2-market-mosaic { grid-template-columns: 1fr; grid-auto-rows: 180px; }
  .v2 .v2-market-mosaic > * { grid-column: 1 !important; grid-row: auto !important; }
}

@media (prefers-reduced-motion: reduce) {
  .v2 .v2-market-tile img { transition: none; }
}

/* ---------- Industries hub: image tiles ----------
   One photo, the industry name and its one-line pitch per tile. */
/* Three across in rows; an incomplete last row sits centered instead of
   leaving an empty slot, whatever the industry count. */
.v2 .seo-industry-tiles {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 16px;
}
.v2 .seo-industry-tiles > * { flex: 0 0 calc((100% - 32px) / 3); min-width: 0; }
.v2 .seo-industry-tile {
  position: relative;
  display: block;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: var(--r-lg);
  border: 1px solid var(--bd-white);
  background: var(--bg-2);
  text-decoration: none;
  color: #fff;
}
.v2 .seo-industry-tile img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.6s var(--ease-out);
}
.v2 .seo-industry-tile::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 35%, rgba(10, 10, 18, 0.88) 100%);
}
.v2 .seo-industry-tile:hover img { transform: scale(1.04); }
.v2 .seo-industry-tile:hover { border-color: var(--bd-strong); }
.v2 .seo-industry-tile-text {
  position: absolute;
  left: 18px;
  right: 18px;
  bottom: 16px;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.v2 .seo-industry-tile h3 {
  margin: 0;
  font-size: clamp(1rem, 1.4vw, 1.2rem);
  font-weight: 800;
  letter-spacing: -0.01em;
  line-height: 1.2;
}
/* Below three across, go straight to one full-width column (never two), so an
   odd count never leaves a lone card on its own row. Wider, shorter cards
   keep the single column from getting tall. */
@media (max-width: 900px) {
  .v2 .seo-industry-tiles { gap: 12px; }
  .v2 .seo-industry-tiles > * { flex-basis: 100%; }
  .v2 .seo-industry-tile { aspect-ratio: 16 / 9; }
}

