/* ==========================================================================
   components.css — reusable pieces. Never section-specific.
   ========================================================================== */

/* --- Button ---------------------------------------------------------------
   Two fills in the design: dark (hero, articles) and green (footer CTA).
   Green fill always carries --ink text: 11.26:1.                          */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--s-8);
  min-height: 50px;          /* min- not fixed: the label scales with --body-scale */
  padding-block: var(--s-3);
  padding-inline: 29px;
  border-radius: var(--r-pill);
  font-family: var(--font-body);
  font-size: var(--t-caption);
  font-weight: var(--w-medium);
  letter-spacing: var(--track-tight);
  white-space: nowrap;
  transition: background-color var(--d-base) var(--ease-out),
              color var(--d-base) var(--ease-out),
              transform var(--d-base) var(--ease-out);
}
.btn__icon {
  display: grid;
  place-items: center;
  width: 22px; height: 22px;
  flex: none;
  transition: transform var(--d-base) var(--ease-out);
}
.btn__icon svg { width: 100%; height: 100%; }

.btn:hover  { transform: translateY(-2px); }
.btn:hover .btn__icon { transform: translateX(4px); }
.btn:active { transform: translateY(0); }

.btn--dark  { background: var(--ink);   color: var(--on-dark); }
.btn--dark:hover { background: #14181A; }

.btn--green { background: var(--green); color: var(--ink); }
.btn--green:hover { background: var(--green-hover); }

.btn--ghost { background: transparent; color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink-12); }
.btn--ghost:hover { box-shadow: inset 0 0 0 1px var(--ink-24); }

/* --- Eyebrow --------------------------------------------------------------
   Green dot + label. The dot is a fill, so --green is safe here.          */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--t-micro);
  line-height: var(--lh-micro);
  font-weight: var(--w-medium);
  color: var(--ink-64);
}
.eyebrow::before {
  content: '';
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--green);
  flex: none;
}
.is-dark .eyebrow, .on-dark .eyebrow { color: var(--on-dark-72); }

/* --- Section header -------------------------------------------------------
   Heading left, supporting line right-aligned — the design's repeated shape. */
.sec-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: start;
  column-gap: var(--s-10);
  margin-bottom: var(--s-11);
}
.sec-head__title  { margin-top: var(--s-4); max-width: 18ch; }
.sec-head__intro  {
  align-self: end;
  justify-self: end;
  max-width: 46ch;
  text-align: right;
  font-size: var(--t-body-lg);
  line-height: var(--lh-body-lg);
  color: var(--ink-64);
}
.is-dark .sec-head__intro { color: var(--on-dark-72); }

@media (max-width: 860px) {
  .sec-head { grid-template-columns: 1fr; row-gap: var(--s-5); }
  .sec-head__intro { justify-self: start; text-align: left; }
  .sec-head__title { max-width: none; }
}

/* --- Dark panel -----------------------------------------------------------
   The bento card, the footer, the hero card and the team cards share this
   shell: near-black, the glossy render below, and a film-grain layer.     */
.panel-dark {
  position: relative;
  overflow: hidden;
  border-radius: 30px;               /* design: 30, not the 32 token */
  background-color: var(--ink-card);
  color: var(--on-dark);
}
/* film-grain layer, as in the design's "Background Noise" — above the gloss
   and below the content, the design's layer order */
.panel-dark::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: var(--noise);
  opacity: var(--noise-opacity);
  mix-blend-mode: screen;
}
.panel-dark > * { position: relative; z-index: 1; }
.panel-dark :where(h1, h2, h3, h4, h5) { color: var(--on-dark); }

/* --- Glossy finish ----------------------------------------------------------
   Every dark surface in the design carries the same glossy black render
   (Figma "image 60": 60% opacity, turned 115.475deg, scaled to its surface).
   The render is a media item picked on the Home page ("Site — Dark panel
   finish") and arrives as --gloss-img; without one the surfaces stay black.

   The layer is placed exactly as Figma places it: a box of the design's size
   and aspect, pivoting on its top-left corner. Size and pivot are fractions
   of the surface WIDTH (percentage margins resolve against the width), so
   the highlights land where the design puts them at any size.
     --gl-w     layer width / surface width
     --gl-x/y   pivot       / surface width
     --gl-ar    layer aspect ratio, w / h
     --gl-size, --gl-pos   crop, where a surface shows part of the render
     --gl-basis the width the fractions apply to (the surface, by default)
     --gl-shift extra x offset                                             */
.panel-dark::before,
.about-hero::before,
.founder::before,
.journey__card::before {
  content: '';
  position: absolute;
  top: 0; left: 0;
  z-index: 0;
  width: calc(var(--gl-w, 1.70388) * var(--gl-basis, 100%));
  aspect-ratio: var(--gl-ar, 1.52705);
  margin: calc(var(--gl-y, 0.17073) * var(--gl-basis, 100%)) 0 0
          calc(var(--gl-x, 1.3895) * var(--gl-basis, 100%) + var(--gl-shift, 0px));
  transform-origin: 0 0;
  transform: rotate(115.475deg);
  background: var(--gloss-img, none) no-repeat;
  background-size: var(--gl-size, 100% 100%);
  background-position: var(--gl-pos, 0 0);
  opacity: 0.6;
  pointer-events: none;
}
/* Placement per surface, from the design frames (surface size in the note) */
.hero__wide         { --gl-w: 0.83811; --gl-x: 0.54869; --gl-y: 0.05423; }   /*  541 x 199 */
.why__panel         { --gl-w: 1.70388; --gl-x: 1.38950; --gl-y: 0.17073; }   /* 1229 x 685 */
.site-footer__panel { --gl-w: 1.70388; --gl-x: 1.38242; --gl-y: 0.17324; }   /* 1229 x 499 */
.about-hero         { --gl-w: 1.63599; --gl-x: 1.36719; --gl-y: 0.16633; }   /* 1280 x 489 */
.founder            { --gl-w: 1.63599; --gl-x: 1.28023; --gl-y: 0.14440; }   /* 1280 x 738 */
/* 607 x 367 — the design stretches the render to a 2.1 box here */
.journey__card      { --gl-w: 0.93434; --gl-x: 1.22143; --gl-y: 0.09226; --gl-ar: 2.10288; }
/* 275 x 426 — shows the lower-left 72% of the render */
.team__card {
  --gl-w: 1.81327; --gl-x: 1.39737; --gl-y: 0.29983;
  --gl-size: 138.61% 138.61%; --gl-pos: 0 100%;
}
/* Phones: the full-width panels grow far taller than they are wide, which
   would leave the render as a strip along the top. Lay it out as on a
   720px-wide panel, centred, so the sheen reaches down the stack.        */
@media (max-width: 720px) {
  .why__panel, .site-footer__panel, .about-hero, .founder {
    --gl-basis: 720px;
    --gl-shift: calc((100% - 720px) / 2);
  }
}

/* --- Tile (bento cell) ----------------------------------------------------- */
.tile {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-lg);
  background: var(--white);
  background-image:
    radial-gradient(rgba(1,2,5,0.08) 0.8px, transparent 0.9px),
    linear-gradient(158deg, #FFFFFF 0%, #F4FBEA 58%, #E8F7D2 100%);
  background-size: 12px 12px, 100% 100%;
  padding: var(--s-6);
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}
.tile--plain { background-image: none; background: var(--white); }
.tile--dark  {
  background-image:
    radial-gradient(rgba(255,255,255,0.06) 0.8px, transparent 0.9px),
    linear-gradient(158deg, #0B0F13 0%, #15191E 100%);
  color: var(--on-dark);
}
.tile--dark .tile__title { color: var(--on-dark); }
.tile--dark .tile__text  { color: var(--on-dark-72); }

.tile__title {
  font-family: var(--font-display);
  font-size: var(--t-h5);
  line-height: 1.25;
  font-weight: var(--w-bold);
  letter-spacing: var(--track-tight);
  color: var(--ink);
}
.tile__text {
  font-size: var(--t-caption);
  line-height: var(--lh-caption);
  color: var(--ink-64);
  max-width: 34ch;
}
.tile__media { margin-top: auto; }

/* --- Category label (articles) — green underline, dark text ---------------- */
.cat {
  display: inline-block;
  padding-bottom: var(--s-1);
  border-bottom: 1.5px solid var(--green);
  font-size: var(--t-nano);
  line-height: var(--lh-nano);
  font-weight: var(--w-medium);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--ink-64);
}

/* --- Arrow pill (article cards) -------------------------------------------- */
.arrow-pill {
  display: grid;
  place-items: center;
  width: 38px; height: 38px;
  border-radius: 50%;
  background: var(--white);
  color: var(--ink);
  box-shadow: var(--shadow-md);
  transition: background-color var(--d-base) var(--ease-out),
              transform var(--d-base) var(--ease-out);
}
.arrow-pill svg { width: 16px; height: 16px; }

/* --- Media frame ----------------------------------------------------------
   Every image sits in one of these so the reveal has something to clip.   */
.media {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-lg);
  background: var(--surface);
}
.media > img,
.media > video { width: 100%; height: 100%; object-fit: cover; }
/* A loaded image needs no backdrop — transparent exports would show it */
.media:has(> img) { background: transparent; }
.media--ratio-4x3 { aspect-ratio: 4 / 3; }
.media--ratio-3x2 { aspect-ratio: 3 / 2; }
.media--ratio-1x1 { aspect-ratio: 1 / 1; }

/* Placeholder shown until a real export is dropped in. Labelled so an empty
   slot is obvious in review rather than silently blank. */
.media--placeholder {
  display: grid;
  place-items: center;
  background:
    repeating-linear-gradient(135deg, var(--surface) 0 10px, #EAEAEA 10px 20px);
}
.media--placeholder::after {
  content: attr(data-label);
  font-family: var(--font-body);
  font-size: var(--t-nano);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--ink-48);
  text-align: center;
  padding: var(--s-3);
}

/* --- Accordion (FAQ) -------------------------------------------------------- */
.acc { display: flex; flex-direction: column; gap: var(--s-3); }

.acc__item {
  border-radius: var(--r-lg);
  background: var(--surface);
  overflow: hidden;
  transition: background-color var(--d-base) var(--ease-out);
}
.acc__item.is-open { background: var(--surface); }

.acc__btn {
  display: grid;
  grid-template-columns: 38px minmax(0, 1fr) 28px;
  align-items: center;
  gap: var(--s-2);
  width: 100%;
  padding: var(--s-5) var(--s-6);
  text-align: left;
}
.acc__num {
  font-family: var(--font-display);
  font-size: var(--t-caption);
  font-weight: var(--w-semi);
  color: var(--ink-48);
}
.acc__q {
  font-family: var(--font-display);
  font-size: var(--t-h5);
  line-height: var(--lh-h5);
  font-weight: var(--w-bold);
  letter-spacing: var(--track-tight);
}
.acc__sign { position: relative; width: 18px; height: 18px; justify-self: end; }
.acc__sign::before,
.acc__sign::after {
  content: ''; position: absolute; inset: 50% 0 auto 0;
  height: 1.5px; background: var(--ink);
  transform: translateY(-50%);
  transition: transform var(--d-base) var(--ease-out), opacity var(--d-base) var(--ease-out);
}
.acc__sign::after { transform: translateY(-50%) rotate(90deg); }
.is-open .acc__sign::after { transform: translateY(-50%) rotate(0deg); opacity: 0; }

/* Height animation runs on a grid row — no JS height measuring. */
.acc__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--d-slow) var(--ease-reveal);
}
.is-open .acc__panel { grid-template-rows: 1fr; }
.acc__panel > div { overflow: hidden; }
.acc__a {
  padding: 0 var(--s-6) var(--s-5) calc(38px + var(--s-6) + var(--s-2));
  font-size: var(--t-caption);
  line-height: var(--lh-caption);
  color: var(--ink-64);
  max-width: 58ch;
}

/* --- Marquee (client stories) ---------------------------------------------- */
.marquee {
  position: relative;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 9%, #000 91%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 9%, #000 91%, transparent 100%);
}
.marquee__track {
  display: flex;
  gap: var(--s-5);
  width: max-content;
  animation: marquee-left var(--marquee-duration, 60s) linear infinite;
}
.marquee--reverse .marquee__track { animation-name: marquee-right; }
.marquee:hover .marquee__track,
.marquee__track:focus-within { animation-play-state: paused; }

@keyframes marquee-left  { from { transform: translate3d(0,0,0); }      to { transform: translate3d(-50%,0,0); } }
@keyframes marquee-right { from { transform: translate3d(-50%,0,0); }   to { transform: translate3d(0,0,0); } }

@media (prefers-reduced-motion: reduce) {
  .marquee__track { animation: none; }
  .marquee { overflow-x: auto; }
}

.quote-card {
  flex: none;
  width: 320px;
  border-radius: var(--r-md);
  background: var(--white);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.quote-card .media { border-radius: 0; }

/* --- Lightbox (testimonial screenshots) ------------------------------------
   The cards are 320px wide, so the screenshots read as thumbnails. Clicking
   one opens the full-size upload over a dimmed page; arrows walk the set.  */
.quote-card { cursor: zoom-in; }
.quote-card:focus-visible { outline: 2px solid var(--green); outline-offset: 3px; }

html.has-lightbox { overflow: hidden; }

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-5);
  padding: clamp(56px, 9vh, 88px) var(--s-5);
  background: rgba(1, 2, 5, 0.88);
  -webkit-backdrop-filter: blur(8px);
          backdrop-filter: blur(8px);
  opacity: 0;
  visibility: hidden;
  /* visibility flips instantly on open (so the close button can take focus)
     and only after the fade on close */
  transition: opacity .28s var(--ease-out), visibility 0s linear .28s;
}
.lightbox.is-open {
  opacity: 1;
  visibility: visible;
  transition: opacity .28s var(--ease-out), visibility 0s;
}

.lightbox__frame {
  margin: 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.lightbox__frame img {
  display: block;
  max-width: min(100%, 860px);
  max-height: 78vh;
  width: auto;
  height: auto;
  border-radius: var(--r-md);
  background: var(--white);
  box-shadow: 0 32px 80px rgba(0, 0, 0, 0.45);
  transform: scale(.97);
  transition: transform .32s var(--ease-out);
}
.lightbox.is-open .lightbox__frame img { transform: scale(1); }

.lightbox__count {
  margin-top: var(--s-4);
  font-size: var(--t-caption);
  letter-spacing: .04em;
  color: rgba(255, 255, 255, 0.56);
}

.lightbox__close,
.lightbox__nav {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-pill);
  border: 1px solid rgba(255, 255, 255, 0.24);
  background: rgba(255, 255, 255, 0.08);
  color: var(--white);
  cursor: pointer;
  transition: background .2s var(--ease-out), border-color .2s var(--ease-out);
}
.lightbox__close:hover,
.lightbox__nav:hover { background: rgba(255, 255, 255, 0.18); border-color: rgba(255, 255, 255, 0.44); }
.lightbox__close svg,
.lightbox__nav svg { width: 20px; height: 20px; }

.lightbox__close {
  position: absolute;
  top: var(--s-5);
  right: var(--s-5);
  width: 44px;
  height: 44px;
}
.lightbox__nav { width: 52px; height: 52px; }
.lightbox__nav--prev svg { transform: rotate(180deg); }
.lightbox--single .lightbox__nav { display: none; }
.lightbox--single .lightbox__count { display: none; }

@media (max-width: 720px) {
  .lightbox {
    flex-wrap: wrap;
    padding: 64px var(--gutter) 92px;
    gap: var(--s-4);
  }
  .lightbox__frame { order: 1; flex: 1 0 100%; }
  .lightbox__frame img { max-height: 62vh; }
  .lightbox__nav {
    order: 2;
    position: absolute;
    bottom: var(--s-6);
    width: 48px;
    height: 48px;
  }
  .lightbox__nav--prev { left: calc(50% - 52px); }
  .lightbox__nav--next { left: calc(50% + 4px); }
  .lightbox__close { top: var(--s-4); right: var(--gutter); }
}

@media (prefers-reduced-motion: reduce) {
  .lightbox,
  .lightbox__frame img { transition: none; }
  .lightbox__frame img { transform: none; }
}
