/* intro-bg.css — the New York background behind the intro (home page only).
   Markup: js/sections/intro-bg.js. Colours come from tokens.css (--text and
   --accent), so Day and Night mode need nothing extra. Nothing here changes
   the intro's layout: the background sits behind it and the curve only uses
   the room left under the text. */

.intro { isolation: isolate; }   /* lets the background sit behind the text and photo */

.intro-bg {
  /* Strength of each layer (0 = invisible). Same values in Day and Night. */
  --bg-grid: 0.08;     /* street grid                          */
  --bg-heat: 0.26;     /* extra grid strength around the peaks */
  --bg-bway: 0.2;      /* Broadway                             */
  --bg-curve: 0.46;
  --bg-fill: 0.06;
  --bg-rug: 0.28;
  --bg-axis: 0.48;

  /* Left edge of the content column (matches .intro__inner at any width) */
  --bg-x0: max(var(--gutter), (100% - var(--page-max)) / 2);
  /* Where the grid is pinned: Broadway crossing 6th Ave at 34th St */
  --bg-ax: calc(var(--bg-x0) + (100% - 2 * var(--bg-x0)) * 0.6);
  --bg-ay: 46%;
  /* The grid fades behind the text column */
  --bg-fade: linear-gradient(90deg,
               rgb(0 0 0 / 0.4) calc(var(--bg-x0) + (100% - 2 * var(--bg-x0)) * 0.42),
               #000 calc(var(--bg-x0) + (100% - 2 * var(--bg-x0)) * 0.6));
  --bg-bottom: calc(max(var(--space-4), env(safe-area-inset-bottom)) + 36px);   /* clears the scroll cue */

  position: absolute;
  inset: 0;
  z-index: -1;
  color: var(--text);
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
}
.intro-bg__defs { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ---- Grid layers: pinned at one point, so they never stretch ---- */
.intro-bg__layer { position: absolute; inset: 0; overflow: hidden; }
.intro-bg__layer > svg {
  position: absolute; left: var(--bg-ax); top: var(--bg-ay);
  width: 1px; height: 1px; max-width: none; overflow: visible;
}
.intro-bg__grid, .intro-bg__bway { -webkit-mask-image: var(--bg-fade); mask-image: var(--bg-fade); }
.intro-bg__grid { opacity: var(--bg-grid); }
.intro-bg__bway { opacity: var(--bg-bway); }
.intro-bg__heat {
  opacity: var(--bg-heat);
  --bg-hy: calc(100% - var(--bg-bottom) - var(--bg-plot-h, 120px) * 0.35);
  -webkit-mask-image:
    radial-gradient(ellipse 15% 46% at calc(var(--bg-x0) + (100% - 2 * var(--bg-x0)) * var(--bg-peak-1)) var(--bg-hy), rgb(0 0 0 / 0.9), transparent),
    radial-gradient(ellipse 19% 46% at calc(var(--bg-x0) + (100% - 2 * var(--bg-x0)) * var(--bg-peak-2)) var(--bg-hy), #000, transparent);
          mask-image:
    radial-gradient(ellipse 15% 46% at calc(var(--bg-x0) + (100% - 2 * var(--bg-x0)) * var(--bg-peak-1)) var(--bg-hy), rgb(0 0 0 / 0.9), transparent),
    radial-gradient(ellipse 19% 46% at calc(var(--bg-x0) + (100% - 2 * var(--bg-x0)) * var(--bg-peak-2)) var(--bg-hy), #000, transparent);
}
#intro-bg-tile path { fill: none; stroke: currentColor; vector-effect: non-scaling-stroke; }
#intro-bg-tile .t-minor { stroke-width: 1; stroke-opacity: 0.45; }
#intro-bg-tile .t-avenue { stroke-width: 1; stroke-opacity: 0.9; }
#intro-bg-tile .t-major { stroke-width: 1.4; }
#intro-bg-tile .t-node { stroke-width: 3.2; stroke-linecap: round; }
.intro-bg__bway path { fill: none; stroke: currentColor; stroke-width: 1.2; stroke-dasharray: 1 6; stroke-linecap: round; }

/* ---- Skyline curve, aligned to the content column ---- */
.intro-bg__plot { position: absolute; inset-inline: var(--bg-x0); bottom: var(--bg-bottom); }
.intro-bg__area { position: relative; height: var(--bg-plot-h, 120px); }
.intro-bg__area svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.intro-bg__area path { vector-effect: non-scaling-stroke; }
.intro-bg__fill { fill: url(#intro-bg-fill); }
#intro-bg-fill .s0 { stop-color: currentColor; stop-opacity: var(--bg-fill); }
#intro-bg-fill .s1 { stop-color: currentColor; stop-opacity: 0; }
.intro-bg__curve { fill: none; stroke: currentColor; stroke-opacity: var(--bg-curve); stroke-width: 1.25; stroke-linejoin: round; }
.intro-bg__rug { fill: none; stroke: currentColor; stroke-opacity: var(--bg-rug); stroke-width: 1; }
.intro-bg__base { fill: none; stroke: currentColor; stroke-opacity: calc(var(--bg-axis) * 0.45); stroke-width: 1; }

.intro-bg__point, .intro-bg__drop { position: absolute; left: var(--x); top: var(--y); }
.intro-bg__point {
  width: 9px; height: 9px; margin: -4.5px 0 0 -4.5px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-soft);
  transition: transform var(--dur-ui) var(--ease-spring), box-shadow var(--dur-ui) ease;
}
.intro-bg__drop { bottom: 0; border-left: 1px dashed var(--accent-line); }

.intro-bg__axis { position: relative; height: 22px; }
.intro-bg__axis li {
  position: absolute; left: var(--x); top: 0;
  padding-top: 9px;
  translate: -50% 0;
  font: 500 9.5px/1 var(--font-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  color: color-mix(in srgb, var(--text) calc(var(--bg-axis) * 100%), transparent);
}
.intro-bg__axis li::before { content: ''; position: absolute; left: 50%; top: 0; height: 5px; border-left: 1px solid; opacity: 0.8; }

/* A hidden find: one point that doesn't fit the curve, floating over the
   quiet stretch below 14th St. It leads to /outlier (the 404 page). */
.intro__inner { pointer-events: none; }            /* let the point be clicked */
.intro__inner > * { pointer-events: auto; }        /* text and photo behave as before */
.intro-bg__outlier {
  position: absolute; left: 20%; top: 18%;
  width: 36px; height: 36px; margin: -18px 0 0 -18px;   /* a comfortable target around a 4px point */
  display: grid; place-items: center;
  color: inherit;
  pointer-events: auto;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.intro-bg__outlier::before {
  content: '';
  width: 4px; height: 4px; border-radius: 50%;
  background: currentColor;
  opacity: var(--bg-curve);
  transition: transform var(--dur-ui) var(--ease-spring), background-color 200ms ease, opacity 200ms ease, box-shadow 200ms ease;
}
.intro-bg__outlier span {
  position: absolute; left: 30px; top: 50%;
  translate: -4px -50%;
  font: 500 9.5px/1 var(--font-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  color: color-mix(in srgb, var(--text) 72%, transparent);
  opacity: 0;
  transition: opacity 120ms ease, translate 120ms ease;
}
.intro-bg__outlier:hover::before { background: var(--accent); opacity: 1; transform: scale(1.75); box-shadow: 0 0 0 3px var(--accent-soft); }
.intro-bg__outlier:hover span { opacity: 1; translate: 0 -50%; transition: opacity 200ms ease 150ms, translate var(--dur-ui) var(--ease-spring) 150ms; }

/* Not enough room under the text (short windows, big zoom): the curve and
   its glow step aside; the grid stays. Set by intro-bg.js. */
.intro-bg--no-plot .intro-bg__plot,
.intro-bg--no-plot .intro-bg__heat { visibility: hidden; }

/* The pin and the point are the same place: hover one, light the other */
@media (hover: hover) {
  .intro:has(.intro__location:hover) .intro-bg__point { transform: scale(1.35); box-shadow: 0 0 0 7px var(--accent-soft); }
}

/* Phones and narrow tablets (same breakpoint as intro.css) */
@media (max-width: 819px) {
  .intro-bg {
    --bg-ax: 50%;
    --bg-ay: 64%;
    --bg-grid: 0.07;
    --bg-fade: linear-gradient(180deg, #000 0%, #000 40%, rgb(0 0 0 / 0.3) 52%, rgb(0 0 0 / 0.3) 76%, #000 92%);
  }
  .intro-bg__axis { height: 18px; }
  .intro-bg__axis li { font-size: 8.5px; padding-top: 7px; }
  .intro-bg__axis .is-minor { display: none; }
}

/* Entrance, in step with the intro's own: once the photo is in, the grid
   settles, the curve is plotted left to right, then the point lands. */
@media (prefers-reduced-motion: no-preference) {
  .js .intro:not(.is-ready) .intro-bg { opacity: 0; }
  .intro.is-ready .intro-bg__grid,
  .intro.is-ready .intro-bg__bway { animation: intro-bg-fade 1.4s ease-out both; }
  .intro.is-ready .intro-bg__heat { animation: intro-bg-fade 1.4s 0.9s ease-out both; }
  .intro.is-ready .intro-bg__area svg { animation: intro-bg-plot 1.8s 0.2s cubic-bezier(0.6, 0, 0.3, 1) both; }
  .intro.is-ready .intro-bg__axis,
  .intro.is-ready .intro-bg__drop { animation: intro-bg-fade 0.6s 0.2s ease-out both; }
  .intro.is-ready .intro-bg__drop { animation-delay: 1.8s; }
  .intro.is-ready .intro-bg__point { animation: intro-bg-land 0.6s 1.85s cubic-bezier(0.3, 1.5, 0.5, 1) both; }
  .intro.is-ready .intro-bg__outlier { animation: intro-bg-fade 0.6s 2.3s ease-out both; }
}
@keyframes intro-bg-fade { from { opacity: 0; } }
@keyframes intro-bg-plot { from { clip-path: inset(-20% 100% -20% 0); } to { clip-path: inset(-20% 0 -20% 0); } }
@keyframes intro-bg-land { from { opacity: 0; transform: scale(0); } }

/* Decoration only: off for high contrast, forced colours and print */
@media (prefers-contrast: more) {
  .intro-bg__grid, .intro-bg__heat, .intro-bg__bway { display: none; }
}
@media (forced-colors: active), print {
  .intro-bg { display: none; }
}
