/* ===========================================================================
   site-home.css — the homepage only: the hero and the floating dashboard
   scene beside it. Loaded by index.php AFTER assets/css/site.css, which owns
   the tokens, buttons, nav and base type this file builds on.

   Kept separate from site.css on purpose. Everything below is one page's
   furniture -- a Free Tools page has no hero and no scene, and should not pay
   for ~120 lines of it. Anything in here that a second page turns out to want
   moves up into site.css rather than being copied.

   THE INLINE STYLES FROM THE MOCKUP LIVE HERE NOW. The design export carried
   its layout in style="" attributes on every element, which is how a design
   tool emits, not how this page should be maintained: the numbers could not be
   reused, could not be overridden per breakpoint, and could not be read next
   to each other. Only the SVG geometry stays inline (an SVG path's shape is
   its data, not its styling), and the per-marker animation-delay stagger,
   which is genuinely per-element.
   =========================================================================== */

/* ----------------------------------------------------------------- hero --- */
/*
 * max-width is 1470px, NOT the mockup's 1320px. See the breakpoint block at
 * the foot of this file: at 1320 the two columns and the gap and the page
 * padding add up to more than the container, so the copy column was squeezed
 * below the width of its own headline at every viewport size. 1470 is the
 * smallest container the authored composition actually fits in:
 *
 *     460 (copy) + 48 (gap) + 826 (scene at 0.7) + 128 (padding) = 1462
 */
.hero {
  flex: 1;
  display: grid;
  grid-template-columns: minmax(360px, 460px) 1fr;
  align-items: center;
  gap: 48px;
  max-width: 1470px;
  width: 100%;
  margin: 0 auto;
  box-sizing: border-box;
  padding: clamp(40px, 6vw, 88px) clamp(20px, 5vw, 64px);
}

.hero__copy { max-width: 460px; }

.hero__eyebrow {
  display: block;
  font-size: 13px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--spark);
  margin-bottom: 22px;
  animation: fadeUp 0.7s ease-out 0.15s both;
}

.hero__title {
  font-weight: 700;
  font-size: clamp(34px, 3.6vw, 46px);
  line-height: 1.08;
  color: var(--deep-signal);
  margin: 0 0 24px;
}

/* Each line is a masked window with the text sliding up inside it, so the
 * three lines arrive in sequence. overflow:hidden on the outer span is what
 * makes the slide read as a reveal rather than a drift. */
.hero__line { display: block; overflow: hidden; }
.hero__line > span {
  display: block;
  animation: lineUp 0.9s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.hero__line:nth-child(1) > span { animation-delay: 0.10s; }
.hero__line:nth-child(2) > span { animation-delay: 0.22s; }
.hero__line:nth-child(3) > span { animation-delay: 0.34s; color: var(--spark); }

.hero__sub {
  font-size: 18px;
  line-height: 28px;
  max-width: 46ch;
  margin: 0 0 30px;
  color: var(--ink-muted);
  animation: fadeUp 0.8s ease-out 0.5s both;
}

.hero__actions {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  animation: fadeUp 0.8s ease-out 0.65s both;
}

/* ---------------------------------------------------------------- scene --- */
/*
 * The scene is authored at its natural 1180x860 and scaled down as a whole,
 * so the three cards keep their exact relative offsets at any size. The
 * wrapper has to carry the SCALED box, because a transform does not affect
 * layout -- without it the grid column would reserve the full unscaled size
 * and shove the hero copy off-centre.
 *
 * --scene-scale is the ONE number, and the wrapper's box is derived from it.
 * The mockup hardcoded both (826 = 1180*0.7, 602 = 860*0.7), which meant three
 * numbers that had to be changed together and no way to retune the scale per
 * breakpoint without recomputing two more. The breakpoints below set only the
 * scale; the wrapper follows. Inheritance does the plumbing -- .scene is a
 * child of .scene-wrap, so it reads the same custom property.
 */
.scene-wrap {
  --scene-scale: 0.7;
  width: calc(1180px * var(--scene-scale));
  height: calc(860px * var(--scene-scale));
  flex: none;
}
.scene {
  position: relative;
  width: 1180px;
  height: 860px;
  transform: scale(var(--scene-scale));
  transform-origin: top left;
}

.dash-card {
  position: absolute;
  background: var(--canvas);
  border-radius: 16px;
  box-shadow: 0 24px 60px -18px rgba(0, 51, 84, 0.28),
              0 4px 14px -6px rgba(0, 51, 84, 0.14);
  box-sizing: border-box;
  animation: cardIn 0.7s cubic-bezier(0.22, 1, 0.36, 1) both;
}

/* Position and size per card, and the stagger they enter on. */
.card-traffic  { left: 200px; top:   0;    width: 840px; height: 470px; padding: 28px 34px; animation-delay: 0.15s; }
.card-sessions { left: 230px; top: 520px;  width: 520px; height: 520px; padding: 30px 34px; animation-delay: 0.30s; }
.card-channels { left: 660px; top: 640px;  width: 520px; height: 400px; padding: 30px 34px; animation-delay: 0.45s; }

.card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.card-head--top { align-items: flex-start; }

/* Icon well + title stack, kept together at the left of a card header. */
.card-head__group { display: flex; align-items: center; gap: 18px; }

.card-title { font-size: 22px; color: var(--deep-signal); }
.card-title--sm { font-size: 20px; }
.card-sub { font-size: 16px; color: var(--ink-muted); margin-top: 3px; }

/* The circular well each card's icon sits in. */
.icon-well {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--mist);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.icon-well--sm { width: 52px; height: 52px; }

/* Full-bleed rule under a card header: negative margin out to the card edge,
 * padding back in, so the line spans the card but the content does not. */
.card-rule {
  border-top: 1px solid var(--mist);
  margin: 22px -34px 0;
  padding: 22px 34px 0;
}

.card-figure {
  font-family: 'Montserrat', sans-serif;
  font-weight: 800;
  font-size: 46px;
  letter-spacing: -0.01em;
  color: var(--deep-signal);
  margin-top: 12px;
}
.card-figure-sub { font-size: 16px; color: var(--ink-muted); margin-top: 6px; }

.chart-svg { display: block; overflow: visible; }
.chart-svg--spaced { margin-top: 22px; }

.axis-label {
  font-size: 13px;
  fill: var(--ink-muted);
  font-family: 'Lato', sans-serif;
}

/* The little "someone is looking at this" props: a cursor, a user pill. */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: #fff;
  border: 1px solid var(--mist);
  border-radius: 10px;
  padding: 6px 12px;
  font-weight: 700;
  font-size: 14px;
  color: var(--deep-signal);
  font-family: 'Lato', sans-serif;
  box-shadow: 0 3px 8px -4px rgba(0, 51, 84, 0.2);
}
.avatar { width: 30px; height: 30px; border-radius: 50%; flex: none; }
.cursor-arrow { width: 22px; height: 22px; }

.viewer-tag { display: flex; align-items: center; gap: 10px; }

/* -------------------------------------------------------- channel donut --- */
.donut-row { display: flex; align-items: center; gap: 30px; margin-top: 18px; }
.donut { position: relative; width: 210px; height: 210px; flex: none; }
.donut__centre {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.donut__pct {
  font-family: 'Montserrat', sans-serif;
  font-weight: 800;
  font-size: 40px;
  color: var(--deep-signal);
  line-height: 1;
}
.donut__label {
  font-size: 12px;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
  font-weight: 600;
  margin-top: 6px;
}

.legend {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.leg {
  display: flex;
  align-items: center;
  gap: 12px;
  opacity: 0;
  animation: legIn 0.5s ease-out both;
}
.leg:nth-child(1) { animation-delay: 1.50s; }
.leg:nth-child(2) { animation-delay: 1.65s; }
.leg:nth-child(3) { animation-delay: 1.80s; }
.leg__swatch { width: 18px; height: 12px; border-radius: 4px; flex: none; }
.leg__name {
  font-family: 'Montserrat', sans-serif;
  font-weight: 600;
  font-size: 17px;
  color: var(--deep-signal);
}
/* Driven by site-home.js, which walks it down the legend rows. */
.legend__cursor {
  position: absolute;
  left: 0;
  top: 0;
  opacity: 0;
  transition: transform 0.55s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.4s ease;
}

/* ----------------------------------------------------------- animations --- */
@keyframes cardIn { from { opacity: 0; transform: translateY(24px) scale(0.98); } to { opacity: 1; transform: translateY(0) scale(1); } }
@keyframes lineUp { from { transform: translateY(103%); } to { transform: translateY(0); } }
@keyframes draw   { to { stroke-dashoffset: 0; } }
@keyframes floaty { 0%, 100% { transform: translate(0, 0); } 50% { transform: translate(-5px, 4px); } }
@keyframes pop    { from { opacity: 0; transform: scale(0); } to { opacity: 1; transform: scale(1); } }
@keyframes fadeIn { to { opacity: 1; } }
@keyframes legIn  { from { opacity: 0; transform: translateX(12px); } to { opacity: 1; transform: translateX(0); } }

/* Line-drawing: dasharray is set generously past each path's real length, so
 * one value covers both charts without measuring. */
.line-anim   { stroke-dasharray: 2600; stroke-dashoffset: 2600; animation: draw 1.6s ease-out 0.6s forwards; }
.line-anim-2 { stroke-dasharray: 1400; stroke-dashoffset: 1400; animation: draw 1.4s ease-out 0.8s forwards; }
.float-a     { animation: floaty 5s ease-in-out infinite; }
.dash-in     { opacity: 0; animation: fadeIn 0.7s ease-out 1.85s forwards; }
.area-in     { opacity: 0; animation: fadeIn 0.9s ease-out 0.6s forwards; }

/* transform-box:fill-box so scale() pops each marker about its own centre
 * rather than the SVG origin. */
.mk {
  transform-box: fill-box;
  transform-origin: center;
  opacity: 0;
  animation: pop 0.45s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

/* -------------------------------------------------------- breakpoints --- */
/*
 * THE MOCKUP'S HEADLINE WAS CLIPPED AT EVERY VIEWPORT SIZE, AND THIS IS WHY.
 *
 * The composition needs 1462px of container to hold itself:
 *
 *     460 (copy) + 48 (gap) + 826 (scene at 0.7) + 128 (padding) = 1462
 *
 * The mockup capped the container at max-width: 1320px. So the two tracks
 * always had 1144px to share, the scene's 826 took its share first (it is a
 * fixed width, and the 1fr track's automatic minimum is its content), and the
 * copy column was pushed to the 360px floor of its own
 * minmax(360px, 460px) -- at 1920px just as much as at 1400px, because past
 * 1470 the container stops growing and the arithmetic never changes.
 *
 * "PERFORMANCE" is 395px at Montserrat 700 / 46px with the brand's 0.03em
 * tracking (measured in the browser, not estimated). It does not fit in 360,
 * and .hero__line's overflow:hidden -- the mask that makes the line-reveal
 * work -- CUT IT SILENTLY instead of overflowing where someone would notice.
 * The homepage read "MAKE SEARCH PERFORMANC".
 *
 * Fixed by giving the container the 1470px it needs (see .hero above) and then
 * shrinking the SCENE, never the copy, on the way down. The copy column's
 * 460px is now the one measurement that never gives -- it is the one holding
 * type at a fixed size.
 *
 *   >= 1462   two columns, scene at 0.7 as authored
 *   1300-1461 two columns, scene at 0.54 -- 1461-176 = 1285 holds 460+637
 *    940-1299 stacked, scene back to 0.7 with the full width to itself
 *    720-939  stacked, scene at 0.54 -- at 720 the padding has clamped down
 *             to 36, leaving 648 for a 637px scene
 *   <  720    scene dropped entirely
 */
@media (max-width: 1461px) {
  .scene-wrap { --scene-scale: 0.54; }
}

/* Stacked: copy above, scene centred under it, full size again. */
@media (max-width: 1299px) {
  .hero { grid-template-columns: 1fr; }
  .scene-wrap { --scene-scale: 0.7; margin: 0 auto; }
}

@media (max-width: 939px) {
  .scene-wrap { --scene-scale: 0.54; }
}

/* The scene is a decorative product shot, not content -- at phone widths it
 * costs more than it says, so it goes. The hero copy and both CTAs stay. */
@media (max-width: 719px) {
  .scene-wrap { display: none; }
}

/* ------------------------------------------------------------ a11y base --- */
/*
 * Everything this sheet animates, stilled. site-home.js checks the same query
 * and paints the charts' final state directly instead of running its loops, so
 * the page still reads as finished rather than half-drawn.
 */
@media (prefers-reduced-motion: reduce) {
  .hero__eyebrow,
  .hero__line > span,
  .hero__sub,
  .hero__actions,
  .dash-card,
  .line-anim,
  .line-anim-2,
  .float-a,
  .mk,
  .dash-in,
  .area-in,
  .leg {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
    stroke-dashoffset: 0 !important;
  }
}
