/* Listing detail — refinement layer.

   SPECIFICITY NOTE (important): listing-dynamic.njk carries a ~700-line
   inline <style> block that duplicates listing.css. An inline <style>
   sits after our <link> in the document, so it wins every specificity
   tie. Every rule here is therefore scoped under `.lp` — the page root
   (<article class="lp">) — to out-specify that duplicate. The only
   exception is .lp-related, which is rendered OUTSIDE that article and
   so must stay unscoped.

   Scope of this file: structural polish only. Same monochrome palette,
   same layout skeleton. Two jobs:

   1. Repair contrast bugs left over from when --color-accent was rust.
      It is now #0a0a0a (pure black), which silently broke every
      accent-coloured element sitting on the dark CTA card.
   2. Add depth, spacing rhythm, and one orchestrated entrance so the
      page reads as authored rather than assembled. */

/* ─────────────────────────────────────────────────────────────
   HERO — atmosphere
   Flat white read as unfinished. A barely-there tonal wash plus a
   fine grain gives the type something to sit on. Pure neutrals, so
   the monochrome discipline holds.
   ───────────────────────────────────────────────────────────── */
.lp .lp-hero {
  position: relative;
  isolation: isolate;
  background:
    radial-gradient(120% 90% at 88% 0%, #f7f7f8 0%, transparent 62%),
    radial-gradient(80% 70% at 0% 100%, #fafafa 0%, transparent 55%),
    var(--color-bg);
}

/* SVG grain at ~3.5% — sits beneath content via z-index. */
.lp .lp-hero::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.5;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.035'/%3E%3C/svg%3E");
}

/* ─────────────────────────────────────────────────────────────
   HERO — entrance
   One staggered reveal beats scattered micro-interactions. Short
   enough that it never delays reading.
   ───────────────────────────────────────────────────────────── */
@keyframes lp-rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
@keyframes lp-rule {
  from { transform: scaleX(0); }
  to   { transform: none; }
}

.lp .lp-crumbs,
.lp .lp-hero__kicker,
.lp .lp-hero__name,
.lp .lp-hero__meta,
.lp .lp-hero__photo-frame {
  animation: lp-rise 620ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
.lp .lp-crumbs            { animation-delay: 0ms;   }
.lp .lp-hero__kicker      { animation-delay: 70ms;  }
.lp .lp-hero__name        { animation-delay: 140ms; }
.lp .lp-hero__meta        { animation-delay: 210ms; }
.lp .lp-hero__photo-frame { animation-delay: 120ms; }

/* The kicker's leading rule draws itself in. */
.lp .lp-hero__kicker::before {
  transform-origin: left center;
  animation: lp-rule 520ms cubic-bezier(0.22, 1, 0.36, 1) 260ms both;
}

/* ─────────────────────────────────────────────────────────────
   HERO — typography + meta rhythm
   ───────────────────────────────────────────────────────────── */
.lp .lp-hero__name {
  letter-spacing: -0.032em;
  word-spacing: -0.02em;
}

/* Hairline separators instead of loose dots, so the facts read as
   discrete data points rather than a run-on line. */
.lp .lp-hero__meta { gap: 0.5rem 0; }
.lp .lp-hero__meta-item {
  padding: 0.3rem 0.95rem 0.3rem 0;
  margin-right: 0.95rem;
  border-right: 1px solid var(--color-border);
  line-height: 1.2;
}
.lp .lp-hero__meta-item:last-child {
  border-right: 0;
  margin-right: 0;
  padding-right: 0;
}
.lp .lp-hero__meta-sep { display: none; }

/* ─────────────────────────────────────────────────────────────
   HERO — photo frame
   ───────────────────────────────────────────────────────────── */
.lp .lp-hero__photo-frame {
  box-shadow:
    0 1px 2px rgba(10, 10, 10, 0.04),
    0 14px 34px -10px rgba(10, 10, 10, 0.13);
  transition: transform 420ms cubic-bezier(0.22, 1, 0.36, 1),
              box-shadow 420ms cubic-bezier(0.22, 1, 0.36, 1);
}
.lp .lp-hero__photo-frame:hover {
  transform: translateY(-3px);
  box-shadow:
    0 1px 2px rgba(10, 10, 10, 0.04),
    0 22px 46px -12px rgba(10, 10, 10, 0.17);
}

/* ─────────────────────────────────────────────────────────────
   ACTION BAR
   Was a flat strip between two hairlines. Give the primary button
   real weight and let the ghosts fill on hover, so the row has a
   visible hierarchy.
   ───────────────────────────────────────────────────────────── */
.lp .lp-action {
  transition: transform 200ms cubic-bezier(0.22, 1, 0.36, 1),
              box-shadow 200ms ease,
              background-color 200ms ease,
              border-color 200ms ease,
              color 200ms ease;
}
.lp .lp-action--primary {
  box-shadow: 0 1px 2px rgba(10, 10, 10, 0.10),
              0 6px 16px -6px rgba(10, 10, 10, 0.30);
}
.lp .lp-action--primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 2px 4px rgba(10, 10, 10, 0.12),
              0 12px 24px -8px rgba(10, 10, 10, 0.34);
}
.lp .lp-action--ghost:hover {
  transform: translateY(-2px);
  background: var(--color-accent-light);
  border-color: var(--color-text-dim);
}

/* ─────────────────────────────────────────────────────────────
   SIDEBAR CARDS
   A top hairline that appears on hover gives each card a deliberate
   edge, so the column reads as authored rather than boxed.
   ───────────────────────────────────────────────────────────── */
.lp .lp-card {
  position: relative;
  transition: box-shadow 300ms ease,
              transform 300ms cubic-bezier(0.22, 1, 0.36, 1);
}
.lp .lp-card:not(.lp-cta)::before {
  content: '';
  position: absolute;
  top: -1px;
  left: -1px;
  right: -1px;
  height: 2px;
  background: var(--color-heading);
  opacity: 0;
  transition: opacity 300ms ease;
  border-top-left-radius: inherit;
  border-top-right-radius: inherit;
}
.lp .lp-card:not(.lp-cta):hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 26px -12px rgba(10, 10, 10, 0.18);
}
.lp .lp-card:not(.lp-cta):hover::before { opacity: 1; }

/* ─────────────────────────────────────────────────────────────
   CTA CARD — contrast repair

   BUG: --color-accent resolves to #0a0a0a, the same value as this
   card's own background, so the button rendered black-on-black — an
   invisible box with floating white text — and the icon glyph was
   black on a near-black tint.

   Fix by inverting the button: white surface, black label. On a dark
   card that is both legible and unmistakably a button.
   ───────────────────────────────────────────────────────────── */
.lp .lp-cta {
  background:
    radial-gradient(120% 100% at 100% 0%, #1c1c1c 0%, transparent 58%),
    var(--color-primary);
}
.lp .lp-cta__icon {
  background: rgba(255, 255, 255, 0.10);
  color: #ffffff;
}
.lp .lp-cta__title   { color: rgba(255, 255, 255, 0.72); }
.lp .lp-cta__heading { letter-spacing: -0.015em; }
/* Lifted from 0.7 — thin against near-black at this size. */
.lp .lp-cta__sub     { color: rgba(255, 255, 255, 0.80); }

.lp .lp-cta__btn {
  background: #ffffff;
  color: var(--color-primary);
  border: 1px solid #ffffff;
  letter-spacing: 0.005em;
  box-shadow: 0 6px 18px -8px rgba(0, 0, 0, 0.55);
  transition: transform 200ms cubic-bezier(0.22, 1, 0.36, 1),
              background-color 200ms ease,
              box-shadow 200ms ease;
}
.lp .lp-cta__btn:hover {
  background: #f4f4f5;
  color: var(--color-primary);
  transform: translateY(-2px);
  box-shadow: 0 10px 24px -8px rgba(0, 0, 0, 0.65);
}
.lp .lp-cta__btn:active { transform: translateY(0); }

/* Replaces the report link that used to sit inside this card and read
   as a competing CTA. */
.lp .lp-cta__note {
  display: block;
  text-align: center;
  margin-top: 0.7rem;
  font-size: 0.72rem;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.45);
  font-weight: 600;
}

/* ─────────────────────────────────────────────────────────────
   REPORT LINK — utility action, deliberately quiet
   ───────────────────────────────────────────────────────────── */
.lp .lp-report-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  width: 100%;
  margin-top: 0.9rem;
  padding: 0.5rem 0;
  font-size: 0.78rem;
  color: var(--color-text-dim);
  text-decoration: none;
  transition: color 200ms ease;
}
.lp .lp-report-link svg   { flex-shrink: 0; }
.lp .lp-report-link:hover { color: var(--color-text-muted); }

/* ─────────────────────────────────────────────────────────────
   MAP — match the card treatment so the column reads as a set
   ───────────────────────────────────────────────────────────── */
.lp .lp-map__frame { transition: box-shadow 300ms ease; }
.lp .lp-map__frame:hover {
  box-shadow: 0 10px 26px -12px rgba(10, 10, 10, 0.18);
}

/* ─────────────────────────────────────────────────────────────
   PROSE — comfortable measure, calmer rhythm
   ───────────────────────────────────────────────────────────── */
.lp .lp-prose__body {
  max-width: 68ch;
  letter-spacing: -0.003em;
}
.lp .lp-prose__title { letter-spacing: -0.02em; }

/* ─────────────────────────────────────────────────────────────
   CLOSING BLOCK (share + back)
   These were two floating rows with a tall dead gap before the next
   section, because the sidebar column runs taller than the main one.
   Treat them as a single closing unit and trim the void.
   ───────────────────────────────────────────────────────────── */
.lp .lp-back--tight {
  margin-top: 0;
  padding-top: 1.1rem;
  border-top: 0;
}
.lp .lp-back a {
  transition: transform 200ms cubic-bezier(0.22, 1, 0.36, 1),
              border-color 200ms ease,
              color 200ms ease,
              box-shadow 200ms ease;
}
.lp .lp-back a:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 18px -8px rgba(10, 10, 10, 0.22);
}
.lp .lp-body { padding-bottom: clamp(1.5rem, 3vw, 2.25rem); }

/* ─────────────────────────────────────────────────────────────
   RELATED LISTING CARDS
   NOTE: .lp-related sits OUTSIDE <article class="lp">, so these stay
   unscoped on purpose — adding .lp here would match nothing.
   ───────────────────────────────────────────────────────────── */
.lp-related .dir-card {
  transition: transform 300ms cubic-bezier(0.22, 1, 0.36, 1),
              box-shadow 300ms ease,
              border-color 300ms ease;
}
.lp-related .dir-card:hover {
  transform: translateY(-4px);
  border-color: var(--color-border-light);
  box-shadow: 0 14px 30px -14px rgba(10, 10, 10, 0.22);
}
.lp-related .dir-card__logo {
  transition: transform 400ms cubic-bezier(0.22, 1, 0.36, 1);
}
.lp-related .dir-card:hover .dir-card__logo { transform: scale(1.04); }
.lp-related .dir-card__arrow {
  transition: transform 300ms cubic-bezier(0.22, 1, 0.36, 1);
}
.lp-related .dir-card:hover .dir-card__arrow { transform: translateX(3px); }

/* ─────────────────────────────────────────────────────────────
   MOBILE — keep the meta row readable once it wraps
   ───────────────────────────────────────────────────────────── */
@media (max-width: 600px) {
  .lp .lp-hero__meta-item {
    border-right: 0;
    margin-right: 0.9rem;
    padding-right: 0;
  }

  /* Long trails (Home / Directory / North Carolina / Transportation &
     Logistics) ran past the viewport and were clipped mid-word. Let the
     crumb rail scroll on its own instead, and bleed it to the container
     edge so the cut-off looks intentional. */
  .lp .lp-crumbs {
    display: flex;
    flex-wrap: nowrap;
    max-width: 100%;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 0.2rem;
  }
  .lp .lp-crumbs::-webkit-scrollbar { display: none; }
  .lp .lp-crumbs > * { flex: 0 0 auto; white-space: nowrap; }
}

/* ─────────────────────────────────────────────────────────────
   MOTION OPT-OUT — everything above is decorative
   ───────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .lp .lp-crumbs,
  .lp .lp-hero__kicker,
  .lp .lp-hero__name,
  .lp .lp-hero__meta,
  .lp .lp-hero__photo-frame,
  .lp .lp-hero__kicker::before {
    animation: none;
  }
  .lp .lp-hero__photo-frame:hover,
  .lp .lp-action--primary:hover,
  .lp .lp-action--ghost:hover,
  .lp .lp-card:not(.lp-cta):hover,
  .lp .lp-cta__btn:hover,
  .lp .lp-back a:hover,
  .lp-related .dir-card:hover,
  .lp-related .dir-card:hover .dir-card__logo,
  .lp-related .dir-card:hover .dir-card__arrow {
    transform: none;
  }
}
