/* ═══════════════════════════════════════════════════════════
   Cymela — Home Page Styles
   Hero, mission, research areas, CTA banner
   ═══════════════════════════════════════════════════════════ */

/* ─── Hero ───
   This is the social card rebuilt as a live page, so the numbers below are
   the card's own, converted from its 1200×630 frame into proportions:
   its 76px margin is 6.33% of that width, the mark is 36.7%, and the
   headline is 4.5% — which is where the 4.5vw comes from. At a 1200px
   viewport the two are the same picture, pixel for pixel.

   The background is painted rather than shipped as an image so it scales
   to any viewport instead of stretching, and so the text stays real text. */
.hero {
  position: relative;
  min-height: 100vh;
  display: flex;
  align-items: center;
  overflow: hidden;
  /* The card's base, not --surface-000: it is two values lighter, and
     against the violet wash the difference is visible.

     It fades to nothing over the last third rather than stopping flat.
     Three things used to change on the same pixel row — the base tone
     (#050505 to the body's #0a0a0a), the lattice (the hero's 60px grid
     ending and the site aura's 68px one beginning at a different offset),
     and the violet (the hero's own glow stopping while the fixed aura
     blobs appeared from behind it). Any one of those is a visible line;
     all three together read as a slide change. Letting the hero dissolve
     hands all three over gradually instead of cutting between them. */
  background: linear-gradient(to bottom,
    #050505 0%, #050505 56%, rgba(5, 5, 5, 0.86) 76%, rgba(5, 5, 5, 0) 100%);
}

/* Violet wash bleeding in from the upper right, its faint counter-light
   at the lower left, and a whisper of olive in the corner. The card
   builds these with a squared falloff; the mid stops are that curve's
   value at half radius, which is what keeps them from reading as flat
   discs with a hard edge. */
.hero__glow {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(circle 75vw at 98% -9%,
      rgba(124, 92, 240, 0.34), rgba(124, 92, 240, 0.085) 50%, transparent 78%),
    radial-gradient(circle 60vw at 21% 111%,
      rgba(124, 92, 240, 0.10), rgba(124, 92, 240, 0.025) 50%, transparent 78%),
    radial-gradient(circle 35vw at 8% 95%,
      rgba(200, 216, 76, 0.045), transparent 72%);
}

/* 60px lattice, same as .site-aura__grid and the card */
.hero__grid {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, rgba(255, 255, 255, 0.027) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255, 255, 255, 0.027) 1px, transparent 1px);
  background-size: 60px 60px;
}

/* Both painted layers fade out with the base, so nothing has a hard lower
   edge. The grid goes first and faster — a lattice that stops mid-cell is
   the most legible cut of the three. */
.hero__grid {
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 40%, transparent 82%);
  mask-image: linear-gradient(to bottom, #000 0%, #000 40%, transparent 82%);
}

.hero__glow {
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 58%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0%, #000 58%, transparent 100%);
}

.hero__content {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(1.5rem, 4vw, 4rem);
  width: 100%;
  max-width: var(--max-width);
  margin: 0 auto;
  /* 6.33vw is the card's margin as a proportion; the floor keeps it usable
     on a phone and the ceiling stops it ballooning on an ultrawide */
  padding-inline: var(--page-inset);
  padding-block: calc(var(--header-height) + var(--space-8)) var(--space-8);
}

.hero__text {
  flex: 0 1 auto;
  min-width: 0;
}

.hero__title {
  /* base.css sets every h1/h2/h3 in mono, so without this the headline came
     out monospaced while the card draws it in Inter — a different typeface
     at the largest size on the page. Overridden here rather than in base,
     because the rest of the site's headings are meant to be mono. */
  font-family: var(--font-sans);
  /* 4.5vw lands on the card's 54px at a 1200px viewport */
  font-size: clamp(var(--text-3xl), 4.5vw, var(--text-6xl));
  font-weight: 500;
  line-height: 1.08;
  letter-spacing: -0.02em;
  color: var(--text-100);
  margin-bottom: var(--space-6);
}

.hero__title span {
  display: block;
}

/* Each line holds together as one line, always. The proportional sizing
   leaves only ~2.7% of slack on "Artificial Intelligence", which a larger
   browser default font size or a bit of zoom is enough to eat — and when it
   goes, it breaks the longest line in two. The mark yields instead: it is
   allowed to shrink so the headline never has to. */
@media (min-width: 901px) {
  .hero__title span {
    white-space: nowrap;
  }

  .hero__mark {
    flex: 0 1 auto;
    min-width: 0;
  }

  .hero__mark img {
    max-width: 100%;
  }
}

.hero__subtitle {
  font-size: clamp(1rem, 1.667vw, 1.375rem);   /* card: 20px at 1200 */
  line-height: 1.5;
  /* No hard break any more. A fixed <br> after "reasoning," is 522px of text
     in a column that narrows to 508px at 1200 — so the forced line wrapped a
     second time and stranded one word on its own row. Balance lets the
     browser pick even breaks at whatever width it gets: two lines where
     there is room, three that are evenly weighted where there isn't. */
  text-wrap: balance;
  color: rgba(255, 255, 255, 0.59);
  margin-bottom: clamp(2rem, 4.4vw, 3.25rem);
}

/* The card's hairline runs to 700 of 1200, so it stops well short of the
   mark rather than reaching for it. Proportion kept, not the pixel. */
.hero__rule {
  /* The card's rule runs to 700 of 1200 — which is 16px PAST where the mark's
     box begins, because the mark carries transparent margin on its left and
     the wings do not actually start there. Capped to 100% it stopped at the
     text column instead and came up 64px short. */
  width: min(52vw, 40rem);
  height: 1px;
  background: rgba(255, 255, 255, 0.10);
  margin-bottom: var(--space-5);
}

.hero__strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.55em;
  font-family: var(--font-mono);
  font-size: clamp(0.7rem, 1.167vw, 0.875rem);   /* card: 14px at 1200 */
  font-weight: 500;
  letter-spacing: 0.157em;   /* the card's 2.2px on 14px */
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.41);
}

.hero__strip-domain {
  color: var(--accent);
}

.hero__strip-slash {
  color: rgba(255, 255, 255, 0.18);
}

.hero__strip-dot {
  color: rgba(255, 255, 255, 0.22);
}

.hero__strip a {
  color: inherit;
  text-decoration: none;
  transition: color var(--transition-base);
}

.hero__strip a:hover {
  color: var(--text-90);
}

/* The mark. The card's glow is its own silhouette blurred — which is
   exactly what drop-shadow does, so it is reproduced rather than faked
   with a box behind it. Two stacked passes: a tight rim and a wide bloom. */
.hero__mark {
  flex: 0 0 auto;
  line-height: 0;
}

/* <picture> is inline by default, which reintroduces the baseline gap
   line-height:0 exists to remove. */
.hero__mark picture {
  display: block;
}

.hero__mark img {
  display: block;
  /* 40% bigger than it was, measured on the butterfly rather than the file.
     The old asset carried the original artwork's white margin as transparent
     padding — only 80% of its width was ink — and the new one is trimmed to
     the wings. So 36.7vw of padded image (29.3vw of ink) becomes 41vw of
     ink: same 1.4x, without the trim quietly counting toward it. */
  width: clamp(252px, 41vw, 38rem);
  height: auto;
  max-height: 74vh;
  object-fit: contain;
  filter:
    drop-shadow(0 0 3vw rgba(124, 92, 240, 0.45))
    drop-shadow(0 0 8vw rgba(124, 92, 240, 0.28));
}

/* Restrained, and nothing like what was here before: a short rise on
   load so the panel assembles rather than snapping in. */
@keyframes heroRise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

.hero__title,
.hero__subtitle,
.hero__rule,
.hero__strip {
  animation: heroRise 0.7s var(--ease-out-expo) both;
}

.hero__title    { animation-delay: 0.06s; }
.hero__subtitle { animation-delay: 0.12s; }
.hero__rule     { animation-delay: 0.18s; }
.hero__strip    { animation-delay: 0.22s; }

.hero__mark img {
  animation: heroRise 0.9s var(--ease-out-expo) 0.1s both;
}

@media (prefers-reduced-motion: reduce) {
  .hero__title,
  .hero__subtitle,
  .hero__rule,
  .hero__strip,
  .hero__mark img {
    animation: none;
  }
}

/* Under 900px the mark stops being a companion to the text and starts
   competing with it for the same room, so it moves behind — held to one
   side, dimmed, and let out of the flow entirely. */
@media (max-width: 900px) {
  .hero__content {
    display: block;
  }

  .hero__mark {
    position: absolute;
    top: 50%;
    right: -14%;
    transform: translateY(-50%);
    z-index: -1;
    opacity: 0.5;
    pointer-events: none;
  }

  /* Only a small rise here. This sits behind the copy at half opacity, so
     the desktop's 40% would be bought straight out of legibility. Allowing
     for the trim, this is roughly a tenth larger than before. */
  .hero__mark img {
    width: min(70vw, 26rem);
    max-height: none;
  }

  .hero__rule {
    width: min(100%, 22rem);
  }
}

@media (max-width: 768px) {
  .hero {
    min-height: 88vh;
  }

  .hero__strip {
    gap: 0.45em;
    letter-spacing: 0.1em;
  }
}


/* ─── Metrics Section ─── */
.home-metrics {
  /* the hero's inset, so the row lines up under the headline instead of
     running 56px wider than it on anything narrower than 1440 */
  padding-inline: var(--page-inset);
}

.home-metrics .metrics {
  max-width: var(--max-width);
  margin: 0 auto;
  grid-template-columns: repeat(4, 1fr);
}

/* components.css drops .metrics to two columns under 768px, but that rule
   is a single class and this one is two — media queries add no specificity,
   so the desktop four-column rule would keep winning on a phone. Restated
   here at matching specificity so the breakpoint actually applies. */
@media (max-width: 768px) {
  /* minmax(0, …) not plain 1fr: 1fr floors at the content's own min width,
     so the "SELF-FUNDED RESEARCH" cell refuses to shrink and the two
     columns come out 105px / 230px instead of even. Allowing zero as the
     floor lets the label wrap and the halves match. */
  .home-metrics .metrics {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}


/* ─── Mission Section ─── */
.mission {
  padding: var(--section-gap) 0;
}

.mission__inner {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 var(--space-5);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-16);
  align-items: start;
}

.mission__sticky {
  position: sticky;
  top: calc(var(--header-height) + var(--space-8));
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-4);
}

.mission__heading {
  font-size: clamp(var(--text-2xl), 3vw, var(--text-4xl));
  font-weight: 500;
  color: var(--text-100);
  line-height: var(--leading-tight);
}

.mission__body {
  padding-top: var(--space-2);
}

.mission__body p {
  font-size: var(--text-lg);
  color: var(--text-50);
  line-height: var(--leading-relaxed);
  margin-bottom: var(--space-6);
  max-width: none;
}

.text-accent {
  color: var(--accent);
}

@media (max-width: 768px) {
  .mission__inner {
    grid-template-columns: 1fr;
    gap: var(--space-8);
  }

  .mission__sticky {
    position: static;
  }
}


/* ─── Research Areas ─── */
.research-areas {
  padding: 0 var(--space-5);
  padding-bottom: var(--section-gap);
}

.research-areas__inner {
  max-width: var(--max-width);
  margin: 0 auto;
}

.research-areas__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0;
  border: 1px solid var(--border);
}

.research-card {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 340px;
  overflow: hidden;
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  background: var(--surface-200);
  transition: background var(--transition-slow);
}

.research-card:nth-child(2n) {
  border-right: none;
}

.research-card:nth-child(n+3) {
  border-bottom: none;
}

.research-card:hover {
  background: var(--surface-300);
}

.research-card__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  opacity: 0.12;
  transition: opacity var(--transition-slow);
}

.research-card:hover .research-card__bg {
  opacity: 0.2;
}

.research-card__bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* the CLI screenshot (2.78:1) is far wider than the card it sits in
   (~1.8:1) — object-fit:cover was cropping ~17% off each side, cutting
   into the wordmark and the status-line text. contain shows the whole
   capture instead. */
.research-card__bg--top img {
  object-fit: contain;
  object-position: top;
}

/* contain only covers the top ~65% of the card, so the bottom third is
   letterbox. With nothing painted there the bare card surface shows
   through and the boundary reads as a horizontal seam — most obvious on
   hover, where the gap between the two sides widens as opacity climbs.
   Painting this layer the screenshot's own body color (rgb(12,12,12))
   means image and letterbox composite to an identical value at every
   opacity, so the seam disappears instead of just getting quieter. */
.research-card--cli .research-card__bg {
  background-color: #0c0c0c;
  opacity: 0.34;
}

.research-card--cli:hover .research-card__bg {
  opacity: 0.48;
}

.research-card__label {
  position: relative;
  z-index: 1;
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-widest);
  color: var(--text-25);
  padding: var(--space-3) var(--space-5);
}

.research-card__content {
  position: relative;
  z-index: 1;
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: var(--space-5);
  gap: var(--space-3);
}

.research-card__title {
  font-family: var(--font-mono);
  font-size: clamp(var(--text-xl), 2vw, var(--text-2xl));
  font-weight: 500;
  color: var(--text-100);
  line-height: var(--leading-snug);
}

.research-card__desc {
  font-size: var(--text-sm);
  color: var(--text-50);
  line-height: var(--leading-relaxed);
  max-width: 40ch;
}

.research-card__link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--text-50);
  margin-top: var(--space-2);
  transition: color var(--transition-fast);
}

.research-card__link:hover {
  color: var(--text-100);
}

@media (max-width: 768px) {
  .research-areas__grid {
    grid-template-columns: 1fr;
  }

  .research-card {
    border-right: none;
    border-bottom: 1px solid var(--border);
  }

  .research-card:last-child {
    border-bottom: none;
  }
}


/* ─── CTA Banner ─── */
/* No fill, no border — just the text sitting directly on the page,
   same continuous background as everything around it. */
.cta-banner {
  padding: var(--section-gap) var(--space-5);
}

.cta-banner__inner {
  max-width: var(--max-width);
  margin: 0 auto;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-8);
}

.cta-banner__text {
  font-family: var(--font-mono);
  font-size: clamp(var(--text-2xl), 3vw, var(--text-4xl));
  font-weight: 500;
  color: var(--text-100);
  line-height: var(--leading-tight);
  max-width: 25ch;
}

/* Own line, so the break lands between the two sentences instead of
   wherever the 25ch cap happens to fall — which split it as
   "It thinks first. Language / comes second." White claim on top,
   grey consequence under it. */
.cta-banner__text span {
  display: block;
  color: var(--text-50);
}
