/* ==========================================================================
   home.css - the home page (/)
   Sections, in document order: video hero, subscribe dialog, intro band,
   audience tiles, case-study carousel, pricing, FAQ band.
   ========================================================================== */

/* --------------------------------------------------------------------------
   hero
   -------------------------------------------------------------------------- */

.hero-video {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: 100vh;
  isolation: isolate;
  overflow: hidden;
}

/**
 * The still, behind the video. Sits at -2 so the video (-1) and the gradient
 * (-1, ::after) both stack above it.
 *
 * This exists because the video is lazily sourced by main.js and a 10MB file
 * takes a moment to arrive. Painting the still as the video's own poster=
 * attribute made the swap a hard cut between two unrelated photographs; as a
 * separate layer the video can fade in over it instead.
 */
.hero-video::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -2;
  background: var(--hero-poster) center / cover no-repeat;
}

.hero-video__media {
  position: absolute;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Revealed by main.js on the `playing` event. Staying at 0 is the correct
     resting state for the three cases where the video never runs: reduced
     motion, autoplay refused, and a failed fetch - all of them fall back to
     the still above rather than to an empty hero. */
  opacity: 0;
  transition: opacity 0.8s ease;
}

.hero-video__media.is-playing {
  opacity: 1;
}

/* Keeps the copy legible over any frame of the video. */
.hero-video::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.6) 0%, rgba(0, 0, 0, 0.15) 60%);
}

.hero-video__title {
  font-size: var(--text-2xl);
  font-weight: var(--weight-medium);
  color: var(--on-dark);
}

.hero-video__lead {
  margin-bottom: var(--space-3);
  font-size: var(--text-base);
  font-weight: var(--weight-normal);
  color: var(--on-dark);
}

.hero-video__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: var(--space-6);
}

@media (max-width: 767px) {
  .hero-video__title {
    font-size: var(--text-xl);
  }

  .hero-video__actions {
    margin-bottom: var(--space-5);
  }
}

/* --------------------------------------------------------------------------
   subscribe dialog
   --------------------------------------------------------------------------
   A native <dialog>. main.js calls showModal(); the browser supplies the
   focus trap, Escape handling and inertness of the page behind it.
   -------------------------------------------------------------------------- */

.subscribe-dialog {
  width: 35%;
  min-width: 320px;
  max-width: 560px;
  padding: var(--space-5);
  border: none;
  border-radius: var(--radius);
  background: var(--paper);
  color: var(--muted);
}

.subscribe-dialog::backdrop {
  background: rgba(0, 0, 0, 0.8);
}

.subscribe-dialog__image {
  width: 100%;
  height: 150px;
  margin-bottom: var(--space-3);
  border-radius: 6px;
  object-fit: cover;
  object-position: top center;
  filter: brightness(80%) saturate(0%);
}

.subscribe-dialog__title {
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  color: var(--ink);
}

.subscribe-dialog__lead {
  margin-block: var(--space-2) var(--space-3);
  font-size: var(--text-base);
  color: var(--muted);
}

.subscribe-form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.subscribe-form input {
  flex: 1 1 140px;
  min-width: 0;
  padding: 12px 16px;
  border: none;
  border-radius: 4px;
  background: var(--surface);
  color: var(--ink);
}

.subscribe-form button {
  flex-basis: 100%;
  padding: 14px;
  border-radius: 4px;
  background: var(--ink-raised);
  color: var(--on-dark);
  font-weight: var(--weight-medium);
  transition: background var(--transition), color var(--transition);
}

.subscribe-form button:hover,
.subscribe-form button:focus-visible {
  background: var(--line);
  color: var(--ink);
}

/**
 * main.js appends a .form-status paragraph to every form that posts to
 * /api/contact, this one included. The base styling in form.css is tuned for
 * the dark page background - its pale green/red text is close to unreadable on
 * the dialog's white panel - and as a flex child it would try to share a row
 * with the inputs. Both are corrected here.
 */
.subscribe-dialog .form-status {
  flex-basis: 100%;
  margin-top: 0;
}

.subscribe-dialog .form-status[data-state="ok"] {
  background: rgba(46, 125, 50, 0.12);
  color: #1B5E20;
}

.subscribe-dialog .form-status[data-state="error"] {
  background: rgba(198, 40, 40, 0.12);
  color: #B3261E;
}

.subscribe-dialog__close {
  position: absolute;
  inset-block-start: 12px;
  inset-inline-end: 12px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  color: var(--ink);
  font-size: 20px;
  line-height: 1;
}

.subscribe-dialog__close:hover {
  background: var(--surface);
}

@media (max-width: 1200px) {
  .subscribe-dialog {
    width: 65%;
  }
}

@media (max-width: 1024px) {
  .subscribe-dialog {
    width: 80%;
  }
}

@media (max-width: 767px) {
  .subscribe-dialog {
    width: calc(100vw - 32px);
    min-width: 0;
    padding: var(--space-3);
  }
}

/* --------------------------------------------------------------------------
   intro band - copy beside a tall portrait image
   -------------------------------------------------------------------------- */

/**
 * padding, not margin. Neither .wrap nor .band has vertical padding or a
 * border, so a margin here collapses straight out through both and lands
 * OUTSIDE .band--dark - leaving a white strip of page background above and
 * below the section instead of dark space inside it. Every band on this page
 * (.intro, .carousel, .faq) spaces itself this way for that reason - reach for
 * padding-block, not margin-block, when adding another.
 */
.intro {
  display: flex;
  gap: var(--space-3);
  padding-block: var(--space-6);
}

.intro__copy {
  flex: 0 1 60%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-3);
}

.intro__figure {
  flex: 0 1 40%;
  border-radius: var(--radius);
  overflow: hidden;
}

.intro__figure img {
  width: 100%;
  height: 595px;
  object-fit: cover;
  border-radius: var(--radius);
  filter: brightness(80%) saturate(0%);
  transition: transform var(--transition);
}

.intro__figure:hover img {
  transform: scale(1.1);
}

.intro__software {
  margin-block: 1em;
}

.intro__software strong {
  color: var(--on-dark);
  font-weight: var(--weight-bold);
}

.intro__software li::before {
  content: "\2013";
  margin-inline-end: 0.5em;
  color: var(--line);
  font-weight: var(--weight-medium);
}

@media (max-width: 1200px) {
  .intro {
    padding-block: var(--space-5);
  }

  .intro__figure img {
    height: 665px;
  }
}

@media (max-width: 1024px) {
  .intro__figure img {
    height: 785px;
  }
}

@media (max-width: 767px) {
  .intro {
    flex-direction: column;
  }

  .intro__figure img {
    height: 420px;
  }
}

/* --------------------------------------------------------------------------
   audience tiles
   -------------------------------------------------------------------------- */

.tiles--audience {
  grid-template-columns: repeat(4, 1fr);
}

@media (max-width: 1024px) {
  .tiles--audience {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 767px) {
  .tiles--audience {
    grid-template-columns: 1fr;
  }
}

/* --------------------------------------------------------------------------
   case-study carousel
   --------------------------------------------------------------------------
   CSS scroll-snap, not a JS slider. Without JS it is still a usable
   horizontally scrollable strip; main.js only wires up the arrow buttons.
   -------------------------------------------------------------------------- */

.carousel {
  position: relative;
  padding-top: var(--space-6);
  padding-bottom: var(--space-6);
}

.carousel__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}

.carousel__nav {
  display: flex;
  gap: var(--space-2);
}

.carousel__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px;
  border-radius: var(--radius-sm);
  background: var(--ink-raised);
  color: var(--muted);
  transition: background var(--transition), color var(--transition);
}

.carousel__btn:hover,
.carousel__btn:focus-visible {
  background: var(--line);
  color: var(--ink);
}

.carousel__btn svg {
  width: 20px;
  height: 20px;
  fill: currentColor;
}

.carousel__track {
  display: flex;
  gap: var(--space-3);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  /* Room for the focus ring on the slides. */
  padding-block: 4px;
}

.carousel__track::-webkit-scrollbar {
  display: none;
}

.carousel__slide {
  flex: 0 0 calc((100% - 2 * var(--space-3)) / 3);
  scroll-snap-align: start;
}

/* The card is a link to its /case-studies page - it was a non-interactive
   <article> while the slides were placeholders. <a> is inline by default, so
   it needs to be a block for the figure and text to stack. */
.case-card {
  display: block;
  color: inherit;
}

.case-card__figure {
  border-radius: var(--radius);
  overflow: hidden;
}

.case-card__figure img {
  width: 100%;
  height: 250px;
  object-fit: cover;
  border-radius: var(--radius);
  transition: transform var(--transition);
}

.case-card:hover .case-card__figure img {
  transform: scale(1.1);
}

.case-card__title {
  margin-block: var(--space-3) var(--space-2);
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--on-dark);
}

@media (max-width: 1024px) {
  .carousel {
    padding-top: var(--space-5);
    padding-bottom: var(--space-5);
  }

  .carousel__slide {
    flex-basis: calc((100% - var(--space-3)) / 2);
  }
}

@media (max-width: 767px) {
  .carousel__slide {
    flex-basis: 100%;
  }
}

/* --------------------------------------------------------------------------
   pricing
   -------------------------------------------------------------------------- */

.pricing {
  padding-block: var(--space-6);
}

.pricing__lead {
  margin-bottom: var(--space-3);
  text-align: center;
}

.pricing__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-3);
}

.price-card {
  /* Inset of the hairline between features, as a share of card width. */
  --rule-inset: 30%;
  border-radius: var(--radius);
  background: #F9FAFA;
  overflow: hidden;
  text-align: center;
  transition: box-shadow var(--transition);
}

.price-card:hover {
  box-shadow: var(--shadow-hover);
}

.price-card__header {
  padding-block: var(--space-3);
  background: var(--ink-soft);
  color: var(--on-dark);
}

.price-card__name {
  font-size: var(--text-lg);
  font-weight: var(--weight-medium);
  line-height: 1.2;
}

.price-card__note {
  font-size: var(--text-sm);
  font-weight: var(--weight-normal);
}

.price-card__price {
  display: flex;
  align-items: center;
  justify-content: center;
  padding-block: var(--space-4);
  background: var(--surface);
  color: #555;
  font-size: var(--text-price);
  font-weight: var(--weight-bold);
}

.price-card__currency {
  align-self: flex-start;
  margin-inline-end: 3px;
  font-size: 0.4em;
  line-height: 1;
}

.price-card__amount {
  line-height: 0.8;
}

.price-card__features {
  padding-block: 0;
  background: var(--surface);
  color: var(--muted);
}

.price-card__features li {
  padding-inline: 15px;
  font-size: var(--text-base);
  line-height: 25px;
}

.price-card__features li:not(:first-child)::before {
  content: "";
  display: block;
  margin: var(--space-2) var(--rule-inset);
  border-top: 2px solid #DDD;
}

.price-card__footer {
  padding-block: 30px;
  background: var(--surface);
}

.price-card__btn {
  display: inline-block;
  padding: 12px 24px;
  border-radius: 3px;
  background: var(--ink-raised);
  color: var(--on-dark);
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  line-height: 1;
  transition: background var(--transition), color var(--transition);
}

.price-card__btn:hover,
.price-card__btn:focus-visible {
  background: var(--line);
  color: var(--ink);
}

@media (max-width: 1200px) {
  .pricing {
    padding-block: var(--space-5);
  }

  .price-card {
    --rule-inset: 5%;
  }
}

@media (max-width: 1024px) {
  .pricing__grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .price-card__name {
    font-size: var(--text-base);
  }

  .price-card__price {
    font-size: 40px;
  }
}

@media (max-width: 767px) {
  .pricing__grid {
    grid-template-columns: 1fr;
  }

  .price-card {
    --rule-inset: 15%;
  }

  .price-card__name {
    font-size: var(--text-lg);
  }

  .price-card__note {
    font-size: var(--text-base);
  }

  .price-card__price {
    font-size: var(--text-price);
  }
}

/* --------------------------------------------------------------------------
   FAQ band - image + copy beside an accordion
   -------------------------------------------------------------------------- */

/* padding for the same reason as .intro - see the note there. The bottom was
   --space-3 while the top was --space-6; now that the band actually paints
   the gap, that asymmetry read as the section being cut off short, so both
   sides match .intro and .carousel. */
.faq {
  display: flex;
  gap: 25px;
  padding-block: var(--space-6);
}

.faq__aside {
  flex: 0 1 40%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-3);
}

.faq__figure {
  width: 100%;
  border-radius: var(--radius);
  overflow: hidden;
}

.faq__figure img {
  width: 100%;
  height: 280px;
  object-fit: cover;
  border-radius: var(--radius);
  filter: brightness(80%) saturate(0%);
  transition: transform var(--transition);
}

.faq__figure:hover img {
  transform: scale(1.1);
}

.faq__list {
  flex: 0 1 60%;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

/* Native <details>, so it works with JavaScript disabled. */
.faq-item {
  color: var(--on-dark);
}

.faq-item__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-2) 15px;
  border-radius: var(--radius-sm);
  background: var(--ink-raised);
  color: var(--on-dark);
  cursor: pointer;
  list-style: none;
  font-size: 1rem;
  transition: color var(--transition);
}

.faq-item__summary::-webkit-details-marker {
  display: none;
}

.faq-item:not([open]) .faq-item__summary:hover {
  color: #D9D9D9;
}

.faq-item__summary svg {
  flex-shrink: 0;
  width: 15px;
  height: 15px;
  fill: currentColor;
  transition: transform var(--transition);
}

.faq-item[open] .faq-item__summary svg {
  transform: rotate(180deg);
}

/* main.js keeps `open` set for the length of the collapse animation, so the
   chevron would stay flipped until the panel had finished closing. This class
   is added at the start of that animation to send it back in step. */
.faq-item.is-closing .faq-item__summary svg {
  transform: rotate(0deg);
}

.faq-item__panel {
  margin-top: var(--space-1);
  padding: var(--space-2) 15px;
  border-radius: var(--radius-sm);
  background: var(--ink-raised);
  color: var(--muted);
}

@media (max-width: 1200px) {
  .faq {
    padding-block: var(--space-5);
  }

  .faq__figure img {
    height: 275px;
  }
}

@media (max-width: 767px) {
  .faq {
    flex-direction: column;
  }

  .faq__list {
    margin-top: var(--space-3);
  }
}
