/* 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
   Earlier this drew a full-width 2px black bar across the top edge on
   hover. It sat on the border radius, so the corners clipped it into a
   hard slab that read as a rendering glitch.

   Replaced with the same motif the hero kicker already uses: a short
   rule that grows in from the left. It echoes existing language on the
   page instead of introducing a new heavy element.
   ───────────────────────────────────────────────────────────── */
.lp .lp-card {
  position: relative;
  transition: box-shadow 300ms ease,
              border-color 300ms ease,
              transform 300ms cubic-bezier(0.22, 1, 0.36, 1);
}
.lp .lp-card:not(.lp-cta)::before {
  content: '';
  position: absolute;
  top: 1.15rem;
  left: 0;
  width: 3px;
  height: 0;
  background: var(--color-heading);
  border-radius: 0 2px 2px 0;
  transition: height 320ms cubic-bezier(0.22, 1, 0.36, 1);
}
.lp .lp-card:not(.lp-cta):hover {
  transform: translateY(-2px);
  border-color: var(--color-border-light);
  box-shadow: 0 10px 26px -12px rgba(10, 10, 10, 0.18);
}
/* Height is driven off the card's own heading row, so the mark reads as
   an accent on the title rather than a bar floating on the edge. */
.lp .lp-card:not(.lp-cta):hover::before { height: 1.05rem; }

/* ─────────────────────────────────────────────────────────────
   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 TRIGGER
   A real bordered control rather than a grey footnote — it should look
   clickable — but still clearly secondary to the black CTA above it:
   hairline border, no fill, muted text until hover.
   ───────────────────────────────────────────────────────────── */
.lp .lp-report-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  width: 100%;
  margin-top: 0.9rem;
  padding: 0.7rem 1rem;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.005em;
  color: var(--color-text-muted);
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-radius: var(--border-radius-md);
  text-decoration: none;
  cursor: pointer;
  transition: color 200ms ease, border-color 200ms ease,
              background-color 200ms ease, transform 200ms cubic-bezier(0.22, 1, 0.36, 1),
              box-shadow 200ms ease;
}
.lp .lp-report-link svg { flex-shrink: 0; opacity: 0.75; transition: opacity 200ms ease; }
.lp .lp-report-link:hover {
  color: var(--color-heading);
  border-color: var(--color-text-dim);
  background: var(--color-accent-light);
  transform: translateY(-1px);
  box-shadow: 0 6px 14px -8px rgba(10, 10, 10, 0.22);
}
.lp .lp-report-link:hover svg { opacity: 1; }
.lp .lp-report-link:focus-visible {
  outline: 2px solid var(--color-heading);
  outline-offset: 2px;
}

/* ─────────────────────────────────────────────────────────────
   REPORT DIALOG
   Appended to <body> by listing-detail.js, so it is NOT scoped under .lp.
   ───────────────────────────────────────────────────────────── */
.lj-report[hidden] { display: none; }
.lj-report {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.25rem;
}
.lj-report__scrim {
  position: absolute;
  inset: 0;
  background: rgba(10, 10, 10, 0.55);
  backdrop-filter: blur(2px);
  animation: lj-report-fade 200ms ease both;
}
.lj-report__panel {
  position: relative;
  width: 100%;
  max-width: 460px;
  max-height: calc(100vh - 2.5rem);
  overflow-y: auto;
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-radius: var(--border-radius-lg);
  padding: 1.75rem;
  box-shadow: 0 24px 60px -20px rgba(10, 10, 10, 0.45);
  animation: lj-report-rise 260ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes lj-report-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes lj-report-rise {
  from { opacity: 0; transform: translateY(12px) scale(0.99); }
  to   { opacity: 1; transform: none; }
}

.lj-report__x {
  position: absolute;
  top: 0.85rem;
  right: 0.85rem;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border: 0;
  border-radius: var(--border-radius-sm);
  background: transparent;
  color: var(--color-text-dim);
  cursor: pointer;
  transition: background-color 180ms ease, color 180ms ease;
}
.lj-report__x:hover { background: var(--color-bg-alt); color: var(--color-heading); }

.lj-report__title {
  font-family: var(--font-family-heading);
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--color-heading);
  margin: 0 2rem 0.4rem 0;
}
.lj-report__sub {
  font-size: 0.88rem;
  line-height: 1.55;
  color: var(--color-text-muted);
  margin: 0 0 1.25rem;
}
.lj-report__sub strong { color: var(--color-heading); }

.lj-report__label {
  display: block;
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-weight: 700;
  color: var(--color-heading);
  margin: 0 0 0.45rem;
}
.lj-report__label span {
  text-transform: none;
  letter-spacing: 0;
  font-weight: 500;
  color: var(--color-text-dim);
}

.lj-report__select,
.lj-report__textarea,
.lj-report__input {
  width: 100%;
  box-sizing: border-box;
  padding: 0.7rem 0.8rem;
  margin: 0 0 1.1rem;
  font-family: var(--font-family-body);
  font-size: 0.92rem;
  color: var(--color-text);
  background: var(--color-bg);
  border: 1px solid var(--color-border-light);
  border-radius: var(--border-radius-md);
  transition: border-color 180ms ease, box-shadow 180ms ease;
}
.lj-report__textarea { resize: vertical; min-height: 92px; }

/* Same iOS sub-16px zoom-on-focus problem. .lj-report__input already lands
   at 16px, so this brings the select and textarea into line with the control
   sitting next to them rather than changing the dialog. Small screens only. */
@media (max-width: 768px) {
  .lj-report__select,
  .lj-report__textarea { font-size: 16px; }
}
.lj-report__select:focus,
.lj-report__textarea:focus,
.lj-report__input:focus {
  outline: none;
  border-color: var(--color-heading);
  box-shadow: 0 0 0 3px rgba(10, 10, 10, 0.08);
}

/* Honeypot — off-screen rather than display:none, which some bots skip. */
.lj-report__hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.lj-report__error {
  margin: 0 0 0.9rem;
  padding: 0.6rem 0.75rem;
  font-size: 0.84rem;
  color: #991b1b;
  background: #fef2f2;
  border: 1px solid #fecaca;
  border-radius: var(--border-radius-sm);
}

.lj-report__actions {
  display: flex;
  gap: 0.6rem;
  justify-content: flex-end;
}
.lj-report__btn {
  padding: 0.7rem 1.15rem;
  font-family: var(--font-family-body);
  font-size: 0.88rem;
  font-weight: 600;
  border-radius: var(--border-radius-md);
  cursor: pointer;
  transition: background-color 180ms ease, color 180ms ease,
              border-color 180ms ease, transform 180ms cubic-bezier(0.22, 1, 0.36, 1);
}
.lj-report__btn--ghost {
  background: transparent;
  color: var(--color-text-muted);
  border: 1px solid var(--color-border);
}
.lj-report__btn--ghost:hover {
  color: var(--color-heading);
  border-color: var(--color-text-dim);
}
.lj-report__btn--primary {
  background: var(--color-primary);
  color: var(--color-white);
  border: 1px solid var(--color-primary);
}
.lj-report__btn--primary:hover:not(:disabled) {
  background: var(--color-accent-hover);
  transform: translateY(-1px);
}
.lj-report__btn--primary:disabled { opacity: 0.55; cursor: default; }

.lj-report__done { text-align: center; padding: 0.5rem 0 0.25rem; }
.lj-report__done-icon {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  margin: 0 auto 0.9rem;
  border-radius: 50%;
  background: var(--color-accent-light);
  color: var(--color-heading);
}
.lj-report__done h3 {
  font-family: var(--font-family-heading);
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--color-heading);
  margin: 0 0 0.4rem;
}
.lj-report__done p {
  font-size: 0.88rem;
  color: var(--color-text-muted);
  margin: 0 0 1.25rem;
}

@media (max-width: 480px) {
  .lj-report { padding: 0.75rem; }
  .lj-report__panel { padding: 1.35rem; }
  .lj-report__actions { flex-direction: column-reverse; }
  .lj-report__btn { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  .lj-report__scrim,
  .lj-report__panel { animation: none; }
  .lj-report__btn--primary:hover:not(:disabled),
  .lp .lp-report-link:hover { transform: none; }
}

/* ─────────────────────────────────────────────────────────────
   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;
  }
}

/* ==========================================================================
   LISTING NOT FOUND — "the index card"
   --------------------------------------------------------------------------
   A dead listing URL still tells us what the visitor wanted, so this page is
   built around that name rather than around an apology. The reconstructed
   title carries the page, the requested address is recorded plainly beneath
   it, and live matches from the directory sit directly under both.

   Same ink-and-hairline register as the rest of the site — no colour, no
   illustration, no oversized glyph. The information is the design.
   ========================================================================== */

.lnf {
  max-width: 620px;
  margin: 0 auto;
  padding: clamp(1.75rem, 5vw, 3rem) 0 clamp(2.5rem, 6vw, 3.5rem);
}

.lnf-kicker {
  display: block;
  font-family: 'Plus Jakarta Sans', system-ui, sans-serif;
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #a3a3a3;
  margin-bottom: 0.55rem;
}

/* The name they were after, set as the subject of the page. Tight leading
   and a hard optical size — this is the one thing worth reading twice. */
.lnf-title {
  font-family: 'Plus Jakarta Sans', system-ui, sans-serif;
  font-size: clamp(1.6rem, 5.5vw, 2.35rem);
  font-weight: 800;
  line-height: 1.12;
  letter-spacing: -0.025em;
  color: #0a0a0a;
  margin: 0 0 0.7rem;
  overflow-wrap: break-word;
}

.lnf-lead {
  font-size: 0.95rem;
  line-height: 1.6;
  color: #525252;
  margin: 0 0 1.4rem;
}

/* The address, recorded rather than hidden. Mono, because it is a machine
   fact, and struck through because the catalogue could not fulfil it. */
.lnf-record {
  display: flex;
  align-items: baseline;
  gap: 0.9rem;
  padding: 0.65rem 0.85rem;
  margin: 0 0 clamp(1.75rem, 4vw, 2.25rem);
  background: #fafafa;
  border: 1px solid #e7e5e4;
  border-radius: 3px;
}
.lnf-record__k {
  flex: 0 0 auto;
  font-family: 'Plus Jakarta Sans', system-ui, sans-serif;
  font-size: 0.56rem;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #a3a3a3;
}
.lnf-record__v {
  flex: 1 1 auto;
  min-width: 0;
  font-family: 'Fira Code', 'Courier New', monospace;
  font-size: 0.76rem;
  color: #737373;
  text-decoration: line-through;
  text-decoration-thickness: 1px;
  word-break: break-all;
}

/* ── Section rules ── */
.lnf-rule {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  margin: 0 0 1rem;
  padding-bottom: 0.45rem;
  border-bottom: 1px solid #0a0a0a;
}
.lnf-rule__num {
  /* Jakarta, not Fira Code — Fira Code has no numero-sign glyph. */
  font-family: 'Plus Jakarta Sans', system-ui, sans-serif;
  font-size: 0.6rem;
  letter-spacing: 0.1em;
  color: #737373;
  font-weight: 600;
  padding: 0.18rem 0.45rem;
  border: 1px solid #d4d4d4;
  border-radius: 2px;
  background: #fafafa;
  white-space: nowrap;
}
.lnf-rule__label {
  font-family: 'Plus Jakarta Sans', system-ui, sans-serif;
  font-size: 0.82rem;
  font-weight: 800;
  color: #0a0a0a;
  letter-spacing: -0.005em;
}

/* ── Live matches ──────────────────────────────────────────────────────
   Rows, not cards. Someone who hit the wrong address is scanning for a
   name, and a stack of hairline-separated rows is read top-to-bottom far
   faster than a grid of boxes is read left-to-right. */
.lnf-hits {
  margin: 0 0 clamp(1.75rem, 4vw, 2.25rem);
  border-top: 1px solid #e7e5e4;
}
.lnf-hit {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.7rem 0.5rem;
  border-bottom: 1px solid #e7e5e4;
  text-decoration: none;
  color: inherit;
  transition: background 140ms ease, padding-left 140ms ease;
}
.lnf-hit:hover,
.lnf-hit:focus-visible {
  background: #fafafa;
  padding-left: 0.75rem;
}
.lnf-hit__shot {
  flex: 0 0 auto;
  width: 42px;
  height: 42px;
  border-radius: 3px;
  overflow: hidden;
  background: #fafafa;
  border: 1px solid #e7e5e4;
}
.lnf-hit__shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.lnf-hit__text {
  flex: 1 1 auto;
  min-width: 0;
}
.lnf-hit__name {
  display: block;
  font-family: 'Plus Jakarta Sans', system-ui, sans-serif;
  font-size: 0.9rem;
  font-weight: 700;
  color: #0a0a0a;
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lnf-hit__meta {
  display: block;
  margin-top: 0.12rem;
  font-size: 0.74rem;
  color: #737373;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Held back until hover so a list of six does not read as six arrows. */
.lnf-hit__go {
  flex: 0 0 auto;
  font-size: 0.9rem;
  color: #a3a3a3;
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity 140ms ease, transform 140ms ease;
}
.lnf-hit:hover .lnf-hit__go,
.lnf-hit:focus-visible .lnf-hit__go {
  opacity: 1;
  transform: translateX(0);
  color: #0a0a0a;
}

/* ── Search ── */
.lnf-search { margin: 0 0 1.5rem; }
.lnf-search__row {
  display: flex;
  border: 1.5px solid #0a0a0a;
  border-radius: 3px;
  overflow: hidden;
  background: #fff;
  transition: box-shadow 140ms ease;
}
.lnf-search__row:focus-within { box-shadow: 0 0 0 3px rgba(10, 10, 10, 0.1); }
.lnf-search__input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0.85rem 0.95rem;
  border: none;
  background: transparent;
  font-family: inherit;
  /* 16px floor so iOS does not zoom the page when it takes focus. */
  font-size: 1rem;
  color: #0a0a0a;
}
.lnf-search__input:focus { outline: none; }
.lnf-search__input::placeholder { color: #a3a3a3; }
.lnf-search__btn {
  flex: 0 0 auto;
  background: #0a0a0a;
  color: #fff;
  border: none;
  padding: 0 1.25rem;
  font-family: 'Plus Jakarta Sans', system-ui, sans-serif;
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 140ms ease;
}
.lnf-search__btn:hover { background: #333; }

/* ── Actions and claim line ── */
.lnf-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}
.lnf-actions .btn { flex: 1 1 auto; justify-content: center; text-align: center; }

.lnf-claim {
  margin: 1.25rem 0 0;
  padding-top: 1rem;
  border-top: 1px solid #f4f4f5;
  font-size: 0.83rem;
  line-height: 1.55;
  color: #737373;
}
.lnf-claim strong { color: #0a0a0a; font-weight: 700; }

@media (max-width: 480px) {
  .lnf-record { display: block; }
  .lnf-record__k { display: block; margin-bottom: 0.2rem; }
  .lnf-actions .btn { flex: 1 1 100%; }
}

/* ============================================================
   THE PRO DESCRIPTION LINK
   ------------------------------------------------------------
   The one link allowed inside a listing's body copy (Pro only;
   built at render time from two plain columns, never from
   markup the owner typed). It sits in a paragraph of otherwise
   plain text, so it has to be unmistakably a link without a
   second colour: ink-coloured, always underlined, and on hover
   a marker-style band lifts the words off the line.

   Lives HERE, not in portal.css -- the listing page does not
   load portal.css, and a first version of this rule sat there
   doing nothing while the link rendered as a bare anchor.
   ============================================================ */
.lp-prose__link {
  color: #0a0a0a;
  font-weight: 600;
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 0.16em;
  text-decoration-color: #0a0a0a;
  /* The highlight is painted by box-shadow, not background: a background
     stops at the glyph box, while the shadow gives the band a little
     breathing room above and below the letters. */
  border-radius: 2px;
  transition: box-shadow 0.15s ease, background-color 0.15s ease;
}
.lp-prose__link:hover,
.lp-prose__link:focus-visible {
  /* Pinned: global.css sets a:hover to --color-accent-hover (#2a2a2a), and
     without this the text greys out on the very band meant to lift it. */
  color: #0a0a0a;
  background-color: #e5e5e5;
  box-shadow: 0 0 0 3px #e5e5e5;
  outline: none;
}
