/* =============================================================================
   The Corner — Lead Generation theme
   Shared by the hub page (/service/lead-generation) and every vertical page
   (/service/lead-generation/<slug>). Design tokens and component styles are
   lifted from v4.html so the whole site reads as one system.
   ========================================================================== */

html { scroll-behavior: smooth; }

:root {
  color-scheme: light;
  --c-g1000: 23 23 23;
  --c-g900: 102 102 102;
  --c-g700: 143 143 143;
  --c-bg100: 255 255 255;
  --c-bg200: 250 250 250;
  --c-line: 235 235 235;
  --c-soft: 244 244 244;
  --c-blue: 0 114 245;
  --c-green: 41 122 58;
  /* inverted pair for solid buttons */
  --c-solid-bg: 0 0 0;
  --c-solid-fg: 255 255 255;
  --c-accent-bg: 220 246 228;
  --c-accent-fg: 21 94 51;
  /* coverage tiers, same three the campaign pages use */
  --t0: #22c55e; --t1: #f59e0b; --t2: #94a3b8;
}
html.dark {
  color-scheme: dark;
  --c-g1000: 237 237 237;
  --c-g900: 161 161 161;
  --c-g700: 129 129 129;
  --c-bg100: 12 12 12;
  --c-bg200: 0 0 0;
  --c-line: 38 38 38;
  --c-soft: 30 30 30;
  --c-blue: 82 168 255;
  --c-green: 80 179 101;
  --c-solid-bg: 237 237 237;
  --c-solid-fg: 10 10 10;
  --c-accent-bg: 20 49 33;
  --c-accent-fg: 134 239 172;
  --t0: #86efac; --t1: #fcd34d; --t2: #6b7280;
}

body {
  font-family: Geist, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  background: rgb(var(--c-bg200));
  color: rgb(var(--c-g1000));
  -webkit-font-smoothing: antialiased;
  transition: background-color .3s ease, color .3s ease;
}
::selection { background: rgb(var(--c-blue)); color: #fff; }

.accent-surface { background: rgb(var(--c-accent-bg)); color: rgb(var(--c-accent-fg)); }
.btn-solid { background: rgb(var(--c-solid-bg)); color: rgb(var(--c-solid-fg)); }
.btn-solid:hover { opacity: .85; }

/* Reveal on scroll */
.reveal { opacity: 0; transform: translateY(28px); transition: opacity .7s cubic-bezier(.21,.47,.32,.98), transform .7s cubic-bezier(.21,.47,.32,.98); }
.reveal.in { opacity: 1; transform: none; }
.reveal-d1 { transition-delay: .1s; } .reveal-d2 { transition-delay: .2s; } .reveal-d3 { transition-delay: .3s; }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  html { scroll-behavior: auto; }
}

#siteHeader[data-scrolled="true"] { background: rgb(var(--c-bg200)); box-shadow: 0 1px 0 0 rgb(var(--c-line)); }

/* Nav dropdown — hover on pointer devices, click-toggled on touch */
.navdrop { visibility: hidden; opacity: 0; transform: translateY(-4px); transition: opacity .2s cubic-bezier(0,0,.2,1), transform .2s cubic-bezier(0,0,.2,1), visibility .2s; }
.navwrap:hover .navdrop, .navwrap:focus-within .navdrop { visibility: visible; opacity: 1; transform: translateY(0); }
.navwrap:hover .chev, .navwrap:focus-within .chev { transform: rotate(180deg); }
.chev { transition: transform .2s; }

/* Cards that sit on a 1px ring rather than a border, so hover can thicken it
   without shifting layout. */
.ship-card { transition: box-shadow .2s cubic-bezier(.4,0,.2,1), transform .2s cubic-bezier(.4,0,.2,1); box-shadow: 0 0 0 1px rgb(var(--c-line)); }
.ship-card:hover { box-shadow: 0 0 0 1px rgb(var(--c-g700) / .55); }
html.dark .ship-card:hover { box-shadow: 0 0 0 1px rgb(90 90 90); }

/* Terminal caret in the CLI panels */
@keyframes cliBlink { 0%,49%{opacity:1} 50%,100%{opacity:0} }
.cli-caret { animation: cliBlink 1.1s steps(1) infinite; }

/* Theme switch */
.theme-btn[aria-pressed="true"] { color: rgb(var(--c-g1000)); box-shadow: 0 0 0 1px rgb(var(--c-g700) / .6); }

/* FAQ accordion. Questions are independent — opening one never closes another.
   leadgen.js animates each item's own height, so the sign and the answer only
   have to match that timing. */
.faq-item summary { list-style: none; cursor: pointer; }
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary .faq-plus { transition: transform .45s cubic-bezier(.32,.72,0,1); }
.faq-item[open] summary .faq-plus { transform: rotate(45deg); }
.faq-item summary .faq-q { transition: color .45s cubic-bezier(.32,.72,0,1); }
.faq-item[open] summary .faq-q { color: rgb(var(--c-g1000)); }
.faq-item[open] > :not(summary) { animation: faqIn .45s cubic-bezier(.32,.72,0,1) both; }
@keyframes faqIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .faq-item[open] > :not(summary) { animation: none; }
}

/* Ranking spread bars */
.spread-bar { height: 8px; border-radius: 999px; background: rgb(var(--c-soft)); overflow: hidden; }
.spread-bar > i { display: block; height: 100%; width: 0; border-radius: 999px; transition: width 1.1s cubic-bezier(.21,.47,.32,.98); }
.reveal.in .spread-bar > i { width: var(--w); }

/* Directory search: hide non-matching rows without reflowing the grid */
.vert-card[hidden] { display: none !important; }

/* Marquee for the mobile logo band */
@keyframes marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.marquee-track { animation: marquee 40s linear infinite; }
.marquee-track:hover { animation-play-state: paused; }

/* =============================================================================
   Coverage map — the intent lattice with a funnel wherever people search.
   Ported from the hiring homepage and pointed at customers instead.
   ========================================================================== */

/* ghost landing pages floating over the map */
.ghost-card {
  position: absolute; z-index: 10; width: 208px; pointer-events: none;
  padding: .5rem .6rem; border-radius: .5rem;
  border: 1px dashed rgb(var(--c-g700) / .45);
  background: rgb(var(--c-bg100) / .82);
  backdrop-filter: blur(3px);
  opacity: 0; transform: translateY(6px) scale(.96);
  transition: opacity .35s cubic-bezier(.21,.47,.32,.98), transform .35s cubic-bezier(.21,.47,.32,.98);
}
.ghost-card.on { opacity: 1; transform: none; }

/* running search log */
.log-line { transform: translateY(-4px); transition: opacity .35s ease, transform .35s ease; }
.log-line.in { transform: none; }

/* the query marquee between sections */
.qm-track { animation: marquee 52s linear infinite; }
.qm-track:hover { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) { .qm-track { animation: none; } }

/* layered corpus / rankings figure */
.stack-fig { transition: transform .5s cubic-bezier(.21,.47,.32,.98); }
.stack-fig .stack-back { transition: transform .5s cubic-bezier(.21,.47,.32,.98); }
.stack-fig:hover .stack-back { transform: translate(-6px, 4px); }
.stack-fig .stack-front { transition: transform .5s cubic-bezier(.21,.47,.32,.98); }
.stack-fig:hover .stack-front { transform: translate(6px, -4px); }

/* Break a section out of the centered container to the full viewport width. */
.bleed { margin-left: calc(50% - 50vw); margin-right: calc(50% - 50vw); }

/* The ghost cards are 208px wide and need room to sit beside a funnel without
   covering the map. Below the small breakpoint there is no such room. */
@media (max-width: 639px) {
  .ghost-card { display: none !important; }
}

/* =============================================================================
   Step timeline — numbered pills on a connector rail, laid out across a ten
   column grid so the eye zig-zags rather than reading a list.
   ========================================================================== */
.steps-grid { display: grid; grid-template-columns: repeat(10, minmax(0, 1fr)); gap: 54px 24px; }
.steps-head { grid-column: 1 / span 4; }
.step-1 { grid-column: 5 / span 3; }
.step-2 { grid-column: 8 / span 3; }
.step-3 { grid-column: 1 / span 3; }
.step-4 { grid-column: 4 / span 3; }
.step-5 { grid-column: 7 / span 3; }

/* Copy above a step varies from one line to four, so the article is a column
   with the media pushed to the bottom — every media box in a row then starts
   at the same height, because they are all the same height. */
.steps-grid > article { display: flex; flex-direction: column; }
.steps-head { align-self: start; }

.step-top { position: relative; }
.step-num {
  position: relative; z-index: 1;
  display: grid; place-items: center;
  width: 42px; height: 42px; border-radius: 13px;
  background: rgb(var(--c-solid-bg)); color: rgb(var(--c-solid-fg));
  font-family: "Geist Mono", ui-monospace, monospace; font-size: 16px;
}
.step-num.light {
  background: rgb(var(--c-bg100)); color: rgb(var(--c-g700));
  box-shadow: inset 0 0 0 1px rgb(var(--c-line));
}
/* the rail running out of each pill towards the next step */
.step-top::after {
  content: ""; position: absolute; left: 52px; top: 21px;
  width: calc(100% - 40px); height: 1px; background: rgb(var(--c-line));
}
.step-last .step-top::after { display: none; }

.step-media {
  margin-top: auto; padding-top: 16px; height: 24vw; max-height: 312px;
  /* padding is inside the fixed height, so add it back */
  box-sizing: content-box;
  border-radius: 13px; overflow: hidden;
  background: rgb(var(--c-bg100));
  box-shadow: 0 0 0 1px rgb(var(--c-line));
}
.step-media img { height: 100%; width: 100%; object-fit: cover; transition: transform 1.3s cubic-bezier(.21,.47,.32,.98); }
.step-media:hover img { transform: scale(1.035); }

@media (max-width: 1023px) {
  .steps-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 40px 20px; }
  .steps-head, .step-1, .step-2, .step-3, .step-4, .step-5 { grid-column: auto / span 1; }
  .steps-head { grid-column: 1 / -1; }
  .step-media { height: 38vw; }
  .step-top::after { display: none; }
}
@media (max-width: 639px) {
  .steps-grid { grid-template-columns: minmax(0, 1fr); }
  .step-media { height: 58vw; }
}

/* =============================================================================
   Horizontal card rails — one per letter in the industry directory.
   ========================================================================== */
.rail {
  display: flex; gap: 20px;
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  /* let cards bleed to the container edge and fade out rather than clip hard */
  padding: 4px 4px 18px;
  scroll-padding-left: 4px;
}
.rail::-webkit-scrollbar { display: none; }
.rail > * { flex: 0 0 264px; scroll-snap-align: start; }
@media (min-width: 640px) { .rail > * { flex-basis: 296px; } }

.rail-wrap { position: relative; }
/* arrows only where there is a pointer to use them */
.rail-btn {
  position: absolute; top: 50%; z-index: 2;
  display: none; place-items: center;
  width: 40px; height: 40px; border-radius: 999px;
  background: rgb(var(--c-bg100)); color: rgb(var(--c-g900));
  box-shadow: 0 0 0 1px rgb(var(--c-line)), 0 4px 14px rgb(0 0 0 / .06);
  transform: translateY(-50%);
  transition: color .2s, opacity .2s, transform .2s;
}
.rail-btn:hover { color: rgb(var(--c-g1000)); transform: translateY(-50%) scale(1.06); }
.rail-btn[disabled] { opacity: 0; pointer-events: none; }
.rail-prev { left: -18px; }
.rail-next { right: -18px; }
@media (hover: hover) and (min-width: 900px) { .rail-btn { display: grid; } }

.vert-avatar {
  width: 44px; height: 44px; border-radius: 999px; object-fit: cover;
  box-shadow: 0 0 0 1px rgb(var(--c-line));
  background: rgb(var(--c-soft));
}

/* =============================================================================
   Banner cards — image tile with the label sitting over the top edge.
   ========================================================================== */
.banner-card {
  position: relative; isolation: isolate; overflow: hidden;
  border-radius: 13px; aspect-ratio: 3 / 4;
  background: rgb(var(--c-soft));
  box-shadow: 0 0 0 1px rgb(var(--c-line));
}
.banner-card img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.4s cubic-bezier(.21,.47,.32,.98); }
.banner-card:hover img { transform: scale(1.04); }
/* a soft wash so white type holds over any photograph */
.banner-card::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(rgb(0 0 0 / .48), rgb(0 0 0 / .12) 34%, transparent 52%),
    linear-gradient(to top, rgb(0 0 0 / .52), rgb(0 0 0 / .14) 26%, transparent 46%);
}
/* the label sits at the top, the link at the bottom edge */
.banner-text {
  position: absolute; z-index: 2; inset: 20px 20px 20px 22px; color: #fff;
  display: flex; flex-direction: column; justify-content: space-between; gap: 12px;
}
@media (min-width: 1024px) { .banner-card { aspect-ratio: 4 / 5; } }

/* =============================================================================
   Data skin — the dark "Data" look (see /data/) laid over this theme.
   /assets/data/chrome.css (loaded after this file) maps the --c-* tokens onto
   the Data palette and styles the nav + footer; these rules restyle the page
   body. Selectors are scoped under `main` where they must beat the Tailwind
   CDN utilities, which are injected after every stylesheet.
   ========================================================================== */
.foot { border-top: 1px solid var(--line); padding-top: 56px; }
.foot .wrap { width: 100%; max-width: 1180px; margin: 0 auto; padding: 0 24px; }

/* line the page column up with the nav (1180px + the nav's own inset) */
main .max-w-\[1400px\] { max-width: 1196px; }

/* the nav floats (position: fixed, ~80px), so the first row clears it */
.lg-crumbs { padding-top: 112px; }

/* hero: a 0s-and-1s landscape under the copy, mountains in the bottom band */
.lg-hero { padding-bottom: clamp(140px, 20vw, 300px); }
.lg-hero > canvas.cn-field { top: 40%; height: 60%; }
/* the hub hero is already tall (it carries the coverage map), so less runway */
.lg-hero-map { padding-bottom: clamp(48px, 7vw, 110px); }
.lg-hero-map > canvas.cn-field { top: 30%; height: 70%; }
.lg-hero::after { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; background: linear-gradient(transparent 72%, var(--bg)); }
/* a soft dark halo knocks the digits back behind the copy (as on /data/) */
.lg-hero section header { position: relative; }
.lg-hero section header::before { content: ""; position: absolute; z-index: -1; left: 50%; top: 52%; width: 150%; height: 135%; transform: translate(-50%, -50%); pointer-events: none;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--sky-3) 92%, transparent) 45%, transparent 100%); }
/* the hub hero section clips its overflow (the map), so keep its halo inside */
#heroSec header::before { top: 50%; height: 104%; width: 140%; }
.lg-hero section header :is(h1, p:not(.font-mono), li), .lg-cta :is(h2, p) { text-shadow: 0 0 8px var(--bg), 0 0 18px var(--bg); }

/* closing call to action: sky fades in from the page, landscape underneath */
.cn-scape.lg-cta::before { background: linear-gradient(180deg, var(--bg) 0%, var(--sky-2) 42%, var(--sky-3) 70%, var(--bg) 100%); }
.lg-cta > canvas.cn-field { top: 30%; height: 70%; }
#start > div:first-child { position: relative; }
#start > div:first-child::before { content: ""; position: absolute; z-index: -1; left: 50%; top: 60%; width: 120%; height: 190%; transform: translate(-50%, -50%); pointer-events: none;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--sky-3) 92%, transparent) 45%, transparent 100%); }
.lg-cta::after { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; background: linear-gradient(transparent 70%, var(--bg)); }

/* type: light-weight headlines, serif-italic second halves */
main h1 { font-weight: 400; letter-spacing: -.03em; }
main :is(h1, h2) .serif { color: rgba(237,237,237,.58); letter-spacing: -.005em; }

/* the outlined announcement pill (was a green accent surface) */
.lg-pill { border: 1px solid var(--line-2); background: rgba(255,255,255,.035); color: var(--fg-2); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
.lg-pill a { color: var(--fg); }
/* translucent panel for cards sitting on the landscape */
main .lg-glass { background: rgba(23,23,23,.66); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); }

/* surfaces: hairlines and 20px corners on #171717 */
main .border-line, main .divide-line > * + * { border-color: var(--line); }
main .rounded-xl, main .rounded-2xl { border-radius: 20px; }
.ship-card { border-radius: 20px; box-shadow: 0 0 0 1px var(--line); }
.ship-card:hover, html.dark .ship-card:hover { box-shadow: 0 0 0 1px var(--line-2); }
.banner-card { border-radius: 20px; box-shadow: 0 0 0 1px var(--line); }
.step-media { border-radius: 20px; box-shadow: 0 0 0 1px var(--line); }
.vert-avatar { box-shadow: 0 0 0 1px var(--line-2); }
.rail-btn { background: rgba(24,24,26,.85); box-shadow: 0 0 0 1px var(--line-2); backdrop-filter: blur(8px); }
.spread-bar { background: rgba(255,255,255,.06); }
.ghost-card { background: rgba(23,23,23,.85); }

/* step pills: amber for the ends, outlined in between */
.step-num { font-family: var(--mono); background: rgba(231,164,107,.12); color: var(--amber); box-shadow: inset 0 0 0 1px rgba(231,164,107,.3); }
.step-num.light { background: var(--bg-2); color: var(--fg-3); box-shadow: inset 0 0 0 1px var(--line-2); }
.step-top::after { background: var(--line); }

/* split buttons sit in rows that were built for pills */
main .btn { text-decoration: none; }
@media (max-width: 639px) {
  main .btn { width: 100%; max-width: 340px; justify-content: space-between; }
}

/* match the Search pages: green announcement pill, golden-hour sky, white active tab */
.lg-pill { border-color: rgba(123,216,143,.3) !important; background: rgba(18,32,22,.88) !important; color: var(--green) !important; }
.lg-pill a { color: #b9f5c7 !important; }
body { --sky-1: #46413d; --sky-2: #332e2b; --sky-3: #1e1b19; }

/* ===== v3: person-at-computer heroes, centred copy in the solid sky, map in its own panel (like /search/hiring-campaigns) ===== */
.lg-hero.lg-hero-person { padding: 0 0 clamp(260px, 30vw, 440px); min-height: 100svh; }
.lg-hero.lg-hero-person::before { background: linear-gradient(180deg, var(--sky-1) 0%, var(--sky-2) 38%, var(--sky-3) 70%, var(--bg) 100%) !important; }
.lg-hero.lg-hero-person > canvas.cn-field { top: 34%; height: 66%; }
.lg-hero-center header :is(h1, p, li) { text-shadow: 0 0 8px var(--bg), 0 0 18px var(--bg); }
.lg-hero-center header::before { display: none; }
.lg-crumbs ol { justify-content: center; }

.lg-cta.lg-cta-person > section, .lg-cta.lg-cta-person #start { padding-top: 7rem; }
.lg-cta.lg-cta-person > canvas.cn-field { top: 36%; height: 64%; }
.cn-scape.lg-cta.lg-cta-person::before { background: linear-gradient(180deg, var(--bg) 0%, var(--sky-2) 22%, var(--sky-3) 60%, var(--bg) 100%) !important; }

.map-panel { position: relative; border: 1px solid var(--line-2); border-radius: 24px; background: var(--bg-2); padding: 56px 32px 150px; overflow: hidden; }
.map-legend { position: absolute; top: 22px; right: 26px; display: grid; gap: 8px; justify-items: end; font: 400 13px var(--mono); color: var(--fg-2); z-index: 3; }
.map-legend span { display: inline-flex; align-items: center; gap: 9px; }
.map-legend i { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.map-log { position: absolute; left: 28px; bottom: 26px; width: min(460px, 60%); z-index: 3; }
.map-stats { position: absolute; right: 28px; bottom: 26px; width: min(360px, 34%); z-index: 3; }
.map-stats dl { border-top: 0 !important; padding-top: 0 !important; }
.lg-cov-head { text-align: center; display: grid; gap: 18px; margin: 0 auto 40px; }
.lg-cov-foot { display: grid; grid-template-columns: 1fr; gap: 14px; max-width: 760px; margin: 28px auto 0; }
.lg-cov-foot > p { text-align: center; }
#coverage { margin-top: 0 !important; }
@media (max-width: 760px) {
  .map-panel { padding: 64px 12px 260px; }
  .map-stats { left: 20px; right: 20px; width: auto; bottom: 140px; }
  .map-log { left: 20px; right: 20px; width: auto; }
}
/* Search pages: the sky above the 0s-and-1s scenes is our flat dark background */
html body, :root body { --sky-1: #121212; --sky-2: #121212; --sky-3: #121212; }

/* hub: title above the map, more air before "Build a funnel" */
.lg-map-head { display: grid; gap: 14px; margin: 0 0 32px; }
/* "How a campaign runs" as a pinned scroll story: heading left, one step at a time right */
.lg-steps-story { height: 420svh; }
.lg-steps-story .steps-pin { position: sticky; top: 0; height: 100svh; display: flex; align-items: center; }
.lg-steps-story .steps-grid { position: relative; width: 100%; display: grid; grid-template-columns: 1fr 1.15fr; gap: 64px; align-items: center; }
.lg-steps-story .steps-head { grid-column: 1; grid-row: 1; }
.lg-steps-story .steps-grid > article { grid-column: 2; grid-row: 1; opacity: 0; transform: translateY(30px); filter: blur(4px); transition: opacity .55s var(--ease), transform .55s var(--ease), filter .55s var(--ease); pointer-events: none; }
.lg-steps-story .steps-grid > article.on { opacity: 1; transform: none; filter: none; pointer-events: auto; }
.lg-steps-story .steps-grid > article.past { transform: translateY(-30px); }
.lg-steps-story .steps-grid > article .step-media { min-height: 340px; }
.lg-steps-story .steps-grid > article h3 { font-size: 30px !important; }
.lg-steps-story .steps-grid > article p { font-size: 16px !important; min-height: 0 !important; }
.steps-track { position: absolute; left: 0; bottom: -60px; display: flex; gap: 8px; width: 220px; }
.steps-track i { flex: 1; height: 2px; border-radius: 2px; background: linear-gradient(90deg, var(--fg) calc(var(--f, 0) * 100%), var(--line-2) calc(var(--f, 0) * 100%)); }
.lg-steps-story.static { height: auto; }
.lg-steps-story.static .steps-pin { position: static; height: auto; display: block; }
.lg-steps-story.static .steps-grid { grid-template-columns: 1fr; gap: 48px; }
.lg-steps-story.static .steps-grid > * { grid-column: 1 !important; grid-row: auto !important; opacity: 1; transform: none; filter: none; }
.lg-steps-story.static .steps-track { display: none; }
.lg-hero.lg-hero-person .lg-hero-center { padding-top: clamp(130px, 18vh, 200px); }
.lg-pill { border-color: rgba(255,255,255,.12) !important; background: rgba(38,38,40,.92) !important; color: var(--fg-2) !important; }
.lg-pill a { color: var(--fg) !important; }

/* =============================================================================
   Film grain overlay. Lead-gen photos ship as clean, toned WebP (~25KB) and this
   one shared noise tile adds the grain on top (tools/compress_images.py).
   192px tile drawn at 96px = one grain dot per device pixel on retina screens.
   ========================================================================== */
.step-media, .grain-wrap { position: relative; }
.step-media::after, .grain-wrap::after {
  content: ""; position: absolute; pointer-events: none;
  background: url(/assets/grain.webp) 0 0 / 96px 96px;
}
.step-media::after { inset: 16px 0 0; }
.grain-wrap::after { inset: 0; border-radius: .75rem; }
.banner-card::after {
  background:
    url(/assets/grain.webp) 0 0 / 96px 96px,
    linear-gradient(rgb(0 0 0 / .48), rgb(0 0 0 / .12) 34%, transparent 52%),
    linear-gradient(to top, rgb(0 0 0 / .52), rgb(0 0 0 / .14) 26%, transparent 46%);
}
