/* ==========================================================================
   PledgePay Uganda Limited Corporate Website
   Author: PledgePay Digital Team
   Theme : Purple (from the PledgeCard logo)
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Design Tokens
   -------------------------------------------------------------------------- */
:root {
  /* Brand purple, sampled from the PledgeCard logo */
  --brand: #7b2cbf;
  --brand-600: #6a21ab;
  --brand-700: #5a189a;
  --brand-400: #9d4edd;
  --brand-300: #c77dff;
  --brand-tint: #f3ebff;
  --brand-tint-2: #ede3fb;

  --ink: #14082b;
  --ink-2: #2a2140;
  --body: #5c5670;
  --muted: #8b8698;
  --line: #e8e5ee;
  --line-2: #efedf4;

  --white: #ffffff;
  --paper: #f5f4f8;
  --paper-2: #faf9fc;
  --dark: #150c2e;
  --dark-2: #1d1140;

  --radius-sm: 8px;
  --radius: 14px;
  --radius-lg: 20px;
  --radius-xl: 28px;

  --shadow-sm: 0 2px 10px rgba(20, 8, 43, .05);
  --shadow: 0 10px 40px rgba(20, 8, 43, .07);
  --shadow-lg: 0 24px 70px rgba(20, 8, 43, .12);
  --shadow-brand: 0 14px 34px rgba(123, 44, 191, .28);

  --container: 1200px;
  --header-h: 82px;

  --ease: cubic-bezier(.4, .0, .2, 1);
}

/* --------------------------------------------------------------------------
   2. Reset & Base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: "Plus Jakarta Sans", "Segoe UI", system-ui, -apple-system, sans-serif;
  font-size: 16px;
  line-height: 1.75;
  color: var(--body);
  background: var(--white);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

body.nav-open { overflow: hidden; }

h1, h2, h3, h4, h5, h6 {
  margin: 0 0 .6em;
  color: var(--ink);
  font-weight: 700;
  line-height: 1.22;
  letter-spacing: -.02em;
}

h1 { font-size: clamp(2.15rem, 4.6vw, 3.65rem); font-weight: 800; }
h2 { font-size: clamp(1.65rem, 3.1vw, 2.5rem); }
h3 { font-size: clamp(1.15rem, 1.8vw, 1.375rem); }
h4 { font-size: 1.0625rem; }

p { margin: 0 0 1rem; }
a { color: inherit; text-decoration: none; transition: color .25s var(--ease); }
img { max-width: 100%; display: block; }
ul { margin: 0; padding: 0; list-style: none; }
button, input, textarea, select { font: inherit; color: inherit; }
svg { flex-shrink: 0; }

/* --------------------------------------------------------------------------
   3. Layout helpers
   -------------------------------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 24px;
}

.section { padding: 96px 0; }
.section--tight { padding: 76px 0; }
.section--paper { background: var(--paper); }
.section--paper-2 { background: var(--paper-2); }
.section--dark { background: var(--dark); }

.sec-head { max-width: 640px; margin: 0 auto 54px; text-align: center; }
.sec-head p { color: var(--body); margin-bottom: 0; }
.sec-head--left { margin-left: 0; text-align: left; }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 14px;
  font-size: .8125rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--brand);
}
/* The small decorative rule that used to sit before each eyebrow has been
   removed at the client's request. */
.sec-head .eyebrow { text-transform: none; letter-spacing: 0; font-size: .95rem; }

.lead { font-size: 1.0625rem; }
.text-white { color: #fff; }

/* --------------------------------------------------------------------------
   4. Buttons
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 14px 26px;
  border: 1px solid transparent;
  border-radius: 10px;
  font-size: .9375rem;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  white-space: nowrap;
  transition: transform .25s var(--ease), background .25s var(--ease),
              color .25s var(--ease), box-shadow .25s var(--ease), border-color .25s var(--ease);
}
.btn svg { transition: transform .3s var(--ease); }
.btn:hover { transform: translateY(-2px); }
.btn:hover svg { transform: translate(3px, -3px); }

.btn--primary { background: var(--brand); color: #fff; box-shadow: var(--shadow-brand); }
.btn--primary:hover { background: var(--brand-700); }

.btn--light { background: #fff; color: var(--ink); border-color: var(--line); box-shadow: var(--shadow-sm); }
.btn--light:hover { border-color: var(--brand); color: var(--brand); }

.btn--outline { background: transparent; color: var(--ink); border-color: rgba(20, 8, 43, .16); }
.btn--outline:hover { background: var(--ink); color: #fff; border-color: var(--ink); }

.btn--ghost-light { background: rgba(255, 255, 255, .08); color: #fff; border-color: rgba(255, 255, 255, .24); }
.btn--ghost-light:hover { background: #fff; color: var(--ink); }

.btn--block { width: 100%; }
.btn--sm { padding: 11px 20px; font-size: .875rem; }

.link-more {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: .875rem;
  font-weight: 700;
  color: var(--ink);
}
.link-more svg { transition: transform .3s var(--ease); }
.link-more:hover { color: var(--brand); }
.link-more:hover svg { transform: translate(3px, -3px); }

/* --------------------------------------------------------------------------
   5. Top bar
   -------------------------------------------------------------------------- */
.topbar {
  background: var(--paper);
  border-bottom: 1px solid var(--line);
  font-size: .8125rem;
  color: var(--body);
}
.topbar__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  min-height: 44px;
  padding-top: 6px;
  padding-bottom: 6px;
}
.topbar__list { display: flex; align-items: center; gap: 26px; flex-wrap: wrap; }
.topbar__item { display: inline-flex; align-items: center; gap: 8px; }
.topbar__item svg { color: var(--brand); }
.topbar__item a:hover { color: var(--brand); }
.topbar__socials { display: flex; align-items: center; gap: 14px; }
.topbar__socials a { color: var(--ink-2); opacity: .75; }
.topbar__socials a:hover { color: var(--brand); opacity: 1; }

/* --------------------------------------------------------------------------
   6. Header / Navigation
   -------------------------------------------------------------------------- */
.header {
  position: sticky;
  top: 0;
  z-index: 900;
  background: #fff;
  border-bottom: 1px solid var(--line-2);
  transition: box-shadow .3s var(--ease);
}
.header.is-stuck { box-shadow: 0 6px 26px rgba(20, 8, 43, .08); }

.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* 16px rather than 24px: the header is width-bound, and the company name
     is editable from the dashboard, so the nav needs slack to absorb a
     longer brand without the links wrapping. */
  gap: 16px;
  min-height: var(--header-h);
}

/* Logo */
.logo { display: inline-flex; align-items: center; gap: 11px; }
.logo__mark { width: 40px; height: 40px; flex: 0 0 40px; }
.logo__text { display: flex; flex-direction: column; line-height: 1.05; }
.logo__name {
  font-size: 1.3125rem;
  font-weight: 800;
  letter-spacing: -.02em;
  color: var(--ink);
}
.logo__name em { font-style: normal; color: var(--brand); }
.logo__sub {
  font-size: .625rem;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Desktop nav */
.nav { display: flex; align-items: center; }
.nav__list { display: flex; align-items: center; gap: 2px; }
.nav__item { position: relative; }
.nav__link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  /* 11px, not 16px: seven items plus the logo and buttons need 1212px at
     16px, but the container caps usable width at 1152px — so labels wrapped
     onto two lines at every screen size. */
  padding: 12px 11px;
  white-space: nowrap;
  font-size: .9375rem;
  font-weight: 600;
  color: var(--ink-2);
  border-radius: 8px;
}
.nav__link:hover, .nav__item.is-active > .nav__link { color: var(--brand); }
.nav__link .caret { transition: transform .3s var(--ease); }
.nav__item:hover .caret { transform: rotate(180deg); }

.nav__dropdown {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  min-width: 224px;
  padding: 10px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px);
  transition: all .28s var(--ease);
}
.nav__item:hover > .nav__dropdown { opacity: 1; visibility: visible; transform: translateY(0); }
.nav__dropdown a {
  display: block;
  padding: 9px 14px;
  border-radius: 8px;
  font-size: .9rem;
  font-weight: 600;
  color: var(--ink-2);
}
.nav__dropdown a:hover { background: var(--brand-tint); color: var(--brand); }

.header__actions { display: flex; align-items: center; gap: 12px; }

/* Hamburger, shown at every width, not just mobile, so the drawer (and the
   Admin Login inside it) stays reachable on desktop too. */
.burger {
  display: block;
  width: 46px;
  height: 46px;
  padding: 0;
  background: var(--brand-tint);
  border: 1px solid var(--brand-tint-2);
  border-radius: 12px;
  cursor: pointer;
  position: relative;
}
.burger span {
  position: absolute;
  left: 50%;
  width: 20px;
  height: 2px;
  margin-left: -10px;
  background: var(--brand);
  border-radius: 2px;
  transition: transform .3s var(--ease), opacity .2s var(--ease), top .3s var(--ease);
}
.burger span:nth-child(1) { top: 16px; }
.burger span:nth-child(2) { top: 22px; }
.burger span:nth-child(3) { top: 28px; }
.burger.is-open span:nth-child(1) { top: 22px; transform: rotate(45deg); }
.burger.is-open span:nth-child(2) { opacity: 0; }
.burger.is-open span:nth-child(3) { top: 22px; transform: rotate(-45deg); }

/* Mobile drawer */
.mnav {
  position: fixed;
  top: 0;
  right: 0;
  z-index: 1000;
  width: min(360px, 88vw);
  height: 100dvh;
  padding: 22px 22px 40px;
  background: #fff;
  box-shadow: -20px 0 60px rgba(20, 8, 43, .18);
  transform: translateX(100%);
  transition: transform .38s var(--ease);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}
.mnav.is-open { transform: translateX(0); }
.mnav__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 18px;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--line);
}
.mnav__close {
  width: 40px; height: 40px;
  display: grid; place-items: center;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 10px;
  cursor: pointer;
  color: var(--ink);
}
.mnav__close:hover { background: var(--brand); color: #fff; border-color: var(--brand); }

.mnav__list { padding: 6px 0; }
.mnav__item { border-bottom: 1px solid var(--line-2); }
.mnav__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 15px 4px;
  background: none;
  border: 0;
  text-align: left;
  font-size: 1rem;
  font-weight: 700;
  color: var(--ink);
  cursor: pointer;
}
.mnav__link:hover { color: var(--brand); }
.mnav__link .caret { transition: transform .3s var(--ease); color: var(--muted); }
.mnav__item.is-open > .mnav__link .caret { transform: rotate(180deg); color: var(--brand); }
/* Admin and staff entry point, deliberately set apart from the marketing links */
.mnav__link--admin { color: var(--brand); }
.mnav__link--admin svg { color: var(--brand); opacity: .8; }
.mnav__link--admin:hover { color: var(--brand-700); }

.mnav__sub { max-height: 0; overflow: hidden; transition: max-height .35s var(--ease); }
.mnav__item.is-open .mnav__sub { max-height: 340px; }
.mnav__sub a {
  display: block;
  padding: 10px 4px 10px 18px;
  font-size: .9375rem;
  font-weight: 600;
  color: var(--body);
  border-left: 2px solid var(--line);
}
.mnav__sub a:hover { color: var(--brand); border-color: var(--brand); }
.mnav__sub li:last-child a { padding-bottom: 16px; }

.mnav__foot { margin-top: auto; padding-top: 26px; }
.mnav__contact { display: grid; gap: 12px; margin-bottom: 20px; }
.mnav__contact li { display: flex; gap: 10px; font-size: .875rem; }
.mnav__contact svg { color: var(--brand); margin-top: 4px; }
.mnav__socials { display: flex; gap: 10px; margin-top: 18px; }
.mnav__socials a {
  width: 38px; height: 38px;
  display: grid; place-items: center;
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--ink-2);
}
.mnav__socials a:hover { background: var(--brand); border-color: var(--brand); color: #fff; }

.backdrop {
  position: fixed;
  inset: 0;
  z-index: 990;
  background: rgba(20, 8, 43, .5);
  backdrop-filter: blur(2px);
  opacity: 0;
  visibility: hidden;
  transition: opacity .3s var(--ease), visibility .3s var(--ease);
}
.backdrop.is-open { opacity: 1; visibility: visible; }

/* --------------------------------------------------------------------------
   7. Hero
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  padding: 74px 0 96px;
  background: linear-gradient(180deg, var(--paper) 0%, var(--paper) 62%, #fff 100%);
  overflow: hidden;
}
.hero::before,
.hero::after {
  content: "";
  position: absolute;
  border-radius: 50%;
  filter: blur(10px);
  pointer-events: none;
}
.hero::before {
  width: 460px; height: 460px;
  top: -190px; left: -170px;
  background: radial-gradient(circle, rgba(157, 78, 221, .18), transparent 68%);
}
.hero::after {
  width: 560px; height: 560px;
  bottom: -260px; right: -180px;
  background: radial-gradient(circle, rgba(199, 125, 255, .2), transparent 68%);
}

.hero__grid {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: 1.04fr .96fr;
  gap: 56px;
  align-items: center;
}
.hero__title { margin-bottom: 20px; }
/* Second half of the headline. Kept inside the h1 so the page still has one
   heading, but set smaller so the hero does not run to six full-size lines. */
.hero__title-sub {
  display: block;
  margin-top: .3em;
  font-size: .46em;
  line-height: 1.3;
  font-weight: 600;
  color: var(--body);
}
.hero__text { max-width: 520px; font-size: 1.0625rem; margin-bottom: 32px; }
.hero__actions { display: flex; flex-wrap: wrap; gap: 14px; }

/* Hero visual */
.hero__visual { position: relative; }
/* Organic purple shape sitting behind and slightly around the photo */
.hero__blob {
  position: absolute;
  inset: 12% -22px -11% -22px;
  background: linear-gradient(160deg, var(--brand-400), var(--brand-700));
  border-radius: 46% 54% 42% 58% / 52% 44% 56% 48%;
  opacity: .95;
}
/* The hero photograph is a landscape team shot, so the frame is landscape,
   a portrait crop would slice most of the team out of the picture. */
.hero__photo {
  position: relative;
  z-index: 2;
  display: block;
  width: 100%;
  max-width: 540px;
  height: auto;
  margin: 0 auto;
  border-radius: var(--radius-xl);
  /* Matches the product mockup (1400x933), so no phone is clipped */
  aspect-ratio: 3 / 2;
  object-fit: cover;
  object-position: center;
  box-shadow: 0 24px 60px rgba(20, 8, 43, .18);
}

.float-card {
  position: absolute;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 18px 22px;
  background: #fff;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
}
/* Cards overhang the photo's corners so they never sit over people's faces */
.float-card--stat { top: -26px; right: -18px; max-width: 244px; }
.float-card--team { bottom: -30px; left: -26px; max-width: 310px; }
.float-card__icon {
  width: 46px; height: 46px;
  flex: 0 0 46px;
  display: grid; place-items: center;
  background: var(--brand-tint);
  color: var(--brand);
  border-radius: 13px;
}
.float-card__value { font-size: 1.375rem; font-weight: 800; color: var(--ink); line-height: 1.15; }
.float-card__label {
  display: block;
  margin-top: 3px;
  font-size: .78125rem;
  color: var(--muted);
  font-weight: 600;
  line-height: 1.4;
}
.float-card__note {
  font-size: .8125rem;
  font-weight: 600;
  color: var(--ink-2);
  line-height: 1.6;
  letter-spacing: .002em;
}

.avatars { display: flex; }
.avatars img,
.avatars span {
  width: 34px; height: 34px;
  border-radius: 50%;
  border: 2px solid #fff;
  object-fit: cover;
  margin-left: -10px;
}
.avatars img:first-child, .avatars span:first-child { margin-left: 0; }
.avatars span {
  display: grid; place-items: center;
  background: var(--brand);
  color: #fff;
  font-size: .625rem;
  font-weight: 800;
}

/* --------------------------------------------------------------------------
   8. Feature cards ("Why you should choose us")
   -------------------------------------------------------------------------- */
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 26px; }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; }
.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 26px; }

.feature {
  padding: 38px 32px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  text-align: center;
  transition: transform .3s var(--ease), box-shadow .3s var(--ease), border-color .3s var(--ease);
}
.feature:hover { transform: translateY(-6px); box-shadow: var(--shadow); border-color: transparent; }
.feature__icon {
  width: 76px; height: 76px;
  display: grid; place-items: center;
  margin: 0 auto 22px;
  background: var(--brand-tint);
  color: var(--brand);
  border-radius: 20px;
  transition: background .3s var(--ease), color .3s var(--ease);
}
.feature:hover .feature__icon { background: var(--brand); color: #fff; }
.feature h3 { margin-bottom: 12px; }
.feature p { font-size: .9375rem; margin-bottom: 18px; }

/* --------------------------------------------------------------------------
   9. About / split section
   -------------------------------------------------------------------------- */
.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 64px;
  align-items: center;
}
.split__media { position: relative; }
.split__media img {
  width: 100%;
  height: auto;
  border-radius: var(--radius-lg);
  aspect-ratio: 4 / 3.1;
  object-fit: cover;
}
.stat-card {
  position: absolute;
  left: -22px;
  bottom: -26px;
  padding: 20px 24px;
  background: #fff;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  min-width: 172px;
}
.stat-card__value { font-size: 2rem; font-weight: 800; color: var(--brand); line-height: 1; }
.stat-card__label { font-size: .8125rem; font-weight: 600; color: var(--ink-2); margin: 6px 0 6px; }
.stars { display: flex; gap: 3px; color: #f9a825; }

.split__body h2 { margin-bottom: 18px; }
.split__body p { margin-bottom: 16px; }
.check-list { display: grid; gap: 12px; margin: 0 0 28px; }
.check-list li { display: flex; gap: 11px; align-items: flex-start; font-size: .9375rem; font-weight: 600; color: var(--ink-2); }
.check-list svg { color: var(--brand); margin-top: 3px; }

/* --------------------------------------------------------------------------
   10. Services carousel
   -------------------------------------------------------------------------- */
.carousel { position: relative; }

/* The row scrolls natively: mouse wheel, trackpad, touch swipe, click-and-drag
   and keyboard all work, and the arrows simply scroll it. Native scrolling is
   used instead of a transform so the browser handles momentum and snapping. */
.carousel__viewport {
  overflow-x: auto;
  overflow-y: hidden;
  /* "proximity", not "mandatory": free scrolling stays smooth and can rest
     between cards, but a release near a card edge still settles onto it. */
  scroll-snap-type: x proximity;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: rgba(123, 44, 191, .5) transparent;
  /* Room for the hover lift on the cards, cancelled again by the negative
     margin so the section spacing is unchanged. */
  padding: 14px 0;
  margin-top: -14px;
}
.carousel__viewport::-webkit-scrollbar { height: 7px; }
.carousel__viewport::-webkit-scrollbar-track { background: transparent; }
.carousel__viewport::-webkit-scrollbar-thumb {
  background: rgba(123, 44, 191, .45);
  border-radius: 99px;
}
.carousel__viewport::-webkit-scrollbar-thumb:hover { background: rgba(123, 44, 191, .75); }
.section--dark .carousel__viewport { scrollbar-color: rgba(199, 125, 255, .55) transparent; }
.section--dark .carousel__viewport::-webkit-scrollbar-thumb { background: rgba(199, 125, 255, .45); }
.section--dark .carousel__viewport::-webkit-scrollbar-thumb:hover { background: rgba(199, 125, 255, .8); }

/* While the user is dragging the row, suppress the snap so it tracks the
   pointer exactly, and stop clicks landing on whatever was under the cursor. */
.carousel__viewport.is-dragging {
  scroll-snap-type: none;
  scroll-behavior: auto;
  cursor: grabbing;
}
.carousel__viewport.is-dragging a { pointer-events: none; }

.carousel__track { display: flex; }
.carousel__slide { flex: 0 0 25%; padding: 0 12px; scroll-snap-align: start; }
.carousel--projects .carousel__slide { flex: 0 0 33.3333%; }

.service {
  position: relative;
  display: block;
  border-radius: var(--radius-lg);
  overflow: hidden;
  aspect-ratio: 1 / 1.06;
  isolation: isolate;
}
.service img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform .6s var(--ease);
}
.service::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(20, 8, 43, .12) 0%, rgba(20, 8, 43, .82) 100%);
  transition: background .35s var(--ease);
}
.service:hover img { transform: scale(1.07); }
.service:hover::after { background: linear-gradient(180deg, rgba(90, 24, 154, .38) 0%, rgba(60, 12, 110, .9) 100%); }
.service__body {
  position: absolute;
  z-index: 2;
  left: 0; right: 0; bottom: 0;
  padding: 24px 22px;
  color: #fff;
}
.service__icon {
  width: 44px; height: 44px;
  display: grid; place-items: center;
  margin-bottom: 14px;
  background: rgba(255, 255, 255, .16);
  backdrop-filter: blur(4px);
  border-radius: 12px;
}
.service__title { font-size: 1.0625rem; font-weight: 700; color: #fff; margin: 0; letter-spacing: -.01em; }
.service__desc {
  font-size: .8125rem;
  color: rgba(255, 255, 255, .82);
  margin: 6px 0 0;
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-height .4s var(--ease), opacity .3s var(--ease), margin .4s var(--ease);
}
.service:hover .service__desc { max-height: 90px; opacity: 1; }

.dots { display: flex; justify-content: center; gap: 8px; margin-top: 40px; }
.dots button {
  width: 9px; height: 9px;
  padding: 0;
  background: #d5d0e0;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  transition: all .3s var(--ease);
}
.dots button.is-active { width: 26px; border-radius: 6px; background: var(--brand); }
.section--dark .dots button { background: rgba(255, 255, 255, .28); }
.section--dark .dots button.is-active { background: var(--brand-300); }

.carousel__nav {
  position: absolute;
  top: 50%;
  z-index: 4;
  width: 46px; height: 46px;
  display: grid; place-items: center;
  transform: translateY(-50%);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 50%;
  color: var(--ink);
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: all .25s var(--ease);
}
.carousel__nav:hover { background: var(--brand); border-color: var(--brand); color: #fff; }
.carousel__nav--prev { left: -22px; }
.carousel__nav--next { right: -22px; }
.section--dark .carousel__nav { background: rgba(255, 255, 255, .1); border-color: rgba(255, 255, 255, .2); color: #fff; }
.section--dark .carousel__nav:hover { background: var(--brand); border-color: var(--brand); }

/* --------------------------------------------------------------------------
   11. Progress / growth section
   -------------------------------------------------------------------------- */
.bars { display: grid; gap: 26px; margin: 30px 0 0; }
.bar__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  font-size: .875rem;
  font-weight: 700;
  color: var(--ink);
  margin-bottom: 11px;
}
/* The live figure counts up in step with the fill, so the number reads as
   the current progress level rather than a static caption. */
.bar__value {
  font-size: 1rem;
  font-weight: 800;
  color: var(--brand);
  font-variant-numeric: tabular-nums;
}
.bar__track {
  position: relative;
  height: 9px;
  background: var(--line);
  border-radius: 9px;
}
.bar__fill {
  position: relative;
  display: block;
  height: 100%;
  width: 0;
  background: linear-gradient(90deg, var(--brand-400), var(--brand-700));
  border-radius: 9px;
  transition: width 1.5s var(--ease);
}
/* Knob marking the point the bar has reached */
.bar__fill::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 0;
  width: 15px;
  height: 15px;
  transform: translate(50%, -50%);
  background: #fff;
  border: 4px solid var(--brand-700);
  border-radius: 50%;
  box-shadow: 0 2px 8px rgba(90, 24, 154, .35);
}

.collage { position: relative; padding: 0 0 46px 46px; }
.collage__main {
  width: 100%;
  border-radius: var(--radius-lg);
  aspect-ratio: 1 / 1;
  object-fit: cover;
}
.collage__sub {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 46%;
  border: 6px solid #fff;
  border-radius: var(--radius);
  aspect-ratio: 4 / 3.4;
  object-fit: cover;
  box-shadow: var(--shadow);
}
.badge-card {
  position: absolute;
  right: 22px;
  bottom: 24px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 18px;
  background: #fff;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  max-width: 216px;
}
.badge-card__icon {
  width: 40px; height: 40px;
  display: grid; place-items: center;
  background: var(--brand);
  color: #fff;
  border-radius: 10px;
}
.badge-card strong { display: block; font-size: 1rem; color: var(--ink); line-height: 1.2; }
.badge-card span { font-size: .75rem; color: var(--muted); font-weight: 600; }

/* --------------------------------------------------------------------------
   12. Product cards
   A full-bleed picture fading into the card's own accent colour, with the
   title, a pill, the description, chips and a solid button stacked over it.
   `--card-accent` (set per card in section 23) drives the wash, so changing a
   card's accent in the dashboard restyles the whole thing.
   -------------------------------------------------------------------------- */
.section--dark .sec-head h2 { color: #fff; }
.section--dark .sec-head p { color: rgba(255, 255, 255, .66); }
.section--dark .eyebrow { color: var(--brand-300); }

.product {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;   /* content sits at the bottom, picture above */
  isolation: isolate;
  overflow: hidden;
  /* A fixed height, not an aspect ratio: the slide is full width on a phone,
     and a ratio there produced an 800px card whose text fell on top of the
     logo panel. Height keeps the picture and the body in a known proportion
     at every width.

     400px is the blog card's height, so the two rows sit on the same grid. */
  height: 400px;
  border-radius: var(--radius-lg);
  background: #171a21;
  box-shadow: 0 18px 42px rgba(8, 4, 20, .45);
  cursor: pointer;
  transition: transform .4s var(--ease), box-shadow .4s var(--ease);
}
.product:hover {
  transform: translateY(-8px);
  box-shadow: 0 30px 64px rgba(8, 4, 20, .55);
}

/* --- the picture fills the card ----------------------------------------- */
.product__photo {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  border-radius: inherit;
}
.product__photo img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .8s var(--ease);
}
.product:hover .product__photo img { transform: scale(1.05); }

/* Logos are artwork, not photography. Cropping one to fill the frame would
   slice it in half, so a logo card shows it whole on a light panel across the
   top instead, and the wash below still carries the accent. */
.product__photo--logo {
  /* A flex item, not a percentage: it takes exactly the space the body does
     not use, so the text can never land on the white panel however long the
     title runs or however narrow the card gets. */
  position: relative;
  inset: auto;
  flex: 1;
  min-height: 0;
  display: grid;
  place-items: center;
  padding: 18px 22px 22px;
  background: radial-gradient(circle at 50% 38%, #ffffff 0%, #ece5f7 100%);
}
.product__photo--logo img {
  width: 78%; height: auto;
  max-height: 76%;
  object-fit: contain;
}
.product:hover .product__photo--logo img { transform: scale(1.04); }

/* A card with no picture yet still needs a ground for the text to sit on. */
.product__photo--empty {
  background: linear-gradient(160deg, rgba(255, 255, 255, .10), rgba(255, 255, 255, .02));
}

/* --- the wash that turns the picture into the card's colour -------------- */
.product__veil {
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
  /* Plain fallback first; the accent-tinted version follows for browsers
     that support color-mix(). */
  background: linear-gradient(180deg,
    rgba(15, 17, 22, 0) 0%,
    rgba(15, 17, 22, .36) 34%,
    rgba(15, 17, 22, .88) 60%,
    #0f1116 100%);
}
@supports (background: color-mix(in srgb, red 50%, blue)) {
  .product__veil {
    background: linear-gradient(180deg,
      rgba(15, 17, 22, 0) 0%,
      color-mix(in srgb, var(--card-accent) 24%, rgba(15, 17, 22, .30)) 32%,
      color-mix(in srgb, var(--card-accent) 40%, rgba(13, 15, 20, .88)) 58%,
      color-mix(in srgb, var(--card-accent) 50%, #0d0f14) 100%);
  }
}

/* --- content ------------------------------------------------------------- */
.product__body {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  padding: 0 18px 18px;
}
.product__head {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin-bottom: 7px;
}
.product h3 {
  flex: 1;
  min-width: 0;
  margin: 0;
  font-size: 1.0625rem;      /* matches the blog card's title */
  line-height: 1.3;
  letter-spacing: -.01em;
  color: #fff;
  /* Two lines, so a long product name cannot push the body over the picture. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}
.product__tag {
  flex-shrink: 0;
  padding: 5px 11px;
  background: rgba(255, 255, 255, .17);
  backdrop-filter: blur(8px);
  border-radius: 999px;
  font-size: .6875rem;
  font-weight: 700;
  color: #fff;
  white-space: nowrap;
}
.product p {
  margin: 0 0 11px;
  font-size: .78125rem;
  line-height: 1.55;
  color: rgba(255, 255, 255, .68);
  /* Two lines at this height; three would push the body onto the picture. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}
.product__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 12px;
  /* One row only — a second row of chips is what tipped the card over height. */
  max-height: 26px;
  overflow: hidden;
}
.product__meta span {
  padding: 5px 10px;
  background: rgba(255, 255, 255, .14);
  backdrop-filter: blur(6px);
  border-radius: 999px;
  font-size: .6875rem;
  font-weight: 600;
  color: rgba(255, 255, 255, .9);
  white-space: nowrap;
}

/* --- the button ---------------------------------------------------------- */
.product__cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  padding: 12px 16px;
  background: #fff;
  color: #10131a;
  border-radius: 999px;
  font-size: .875rem;
  font-weight: 700;
  line-height: 1;
  text-align: center;
  transition: background .25s var(--ease);
}
.product__cta:hover { background: #eeeef2; }

/* The button is the card's single real link, stretched over the whole card so
   the entire tile is clickable while screen readers still see one link with a
   proper accessible name. */
.product__cta::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  border-radius: inherit;
}
.product:focus-within { outline: 3px solid var(--card-accent); outline-offset: 4px; }
.product__cta:focus-visible { outline: none; }

/* --------------------------------------------------------------------------
      13. Partners strip
   -------------------------------------------------------------------------- */
.partners { padding: 62px 0; border-bottom: 1px solid var(--line-2); background: #fff; }
.partners__title {
  text-align: center;
  font-size: .9375rem;
  font-weight: 600;
  color: var(--muted);
  margin-bottom: 32px;
}
.partners__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 30px 40px;
}
.partner {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 1.0625rem;
  font-weight: 800;
  letter-spacing: -.02em;
  color: var(--ink);
  opacity: .55;
  transition: opacity .3s var(--ease), color .3s var(--ease);
}
.partner:hover { opacity: 1; color: var(--brand); }
.partner svg { color: var(--brand); }

/* --------------------------------------------------------------------------
   14. Contact
   -------------------------------------------------------------------------- */
.contact__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 60px; align-items: start; }
.contact__info { padding-top: 6px; }
.contact__info h2 { margin-bottom: 16px; }

.info-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 26px; margin-top: 34px; }
.info-item__icon {
  width: 44px; height: 44px;
  display: grid; place-items: center;
  margin-bottom: 14px;
  background: var(--brand-tint);
  color: var(--brand);
  border-radius: 12px;
}
.info-item h4 { margin-bottom: 8px; font-size: .9375rem; }
.info-item p { font-size: .9375rem; margin: 0; line-height: 1.7; }
.info-item a:hover { color: var(--brand); }

.form-card {
  padding: 38px 34px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
}
.form-card h3 { margin-bottom: 6px; }
.form-card > p { font-size: .9rem; margin-bottom: 24px; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.field { margin-bottom: 16px; }
.field label {
  display: block;
  margin-bottom: 7px;
  font-size: .8125rem;
  font-weight: 700;
  color: var(--ink);
}
.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 13px 15px;
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: 10px;
  font-size: .9375rem;
  transition: border-color .25s var(--ease), box-shadow .25s var(--ease), background .25s var(--ease);
}
.field textarea { min-height: 122px; resize: vertical; }
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: 0;
  background: #fff;
  border-color: var(--brand-400);
  box-shadow: 0 0 0 4px rgba(157, 78, 221, .12);
}
.field input::placeholder, .field textarea::placeholder { color: #a9a4b8; }
.form-note { font-size: .75rem; color: var(--muted); margin: 14px 0 0; text-align: center; }
.form-alert {
  display: none;
  margin-bottom: 18px;
  padding: 13px 16px;
  border-radius: 10px;
  font-size: .875rem;
  font-weight: 600;
}
.form-alert.is-visible { display: block; }
.form-alert--ok { background: #e8f7ee; color: #1c7a44; }

/* --------------------------------------------------------------------------
   15. Blog
   -------------------------------------------------------------------------- */
.post {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: transform .3s var(--ease), box-shadow .3s var(--ease), border-color .3s var(--ease);
}
.post:hover { transform: translateY(-6px); box-shadow: var(--shadow); border-color: transparent; }
.post__media { overflow: hidden; aspect-ratio: 16 / 10; }
.post__media img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--ease); }
.post:hover .post__media img { transform: scale(1.06); }
.post__body { padding: 24px 24px 26px; display: flex; flex-direction: column; flex: 1; }
.post__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
  margin-bottom: 12px;
  font-size: .75rem;
  font-weight: 600;
  color: var(--muted);
}
.post__meta .cat { color: var(--brand); }
.post__meta .dot { width: 4px; height: 4px; background: var(--line); border-radius: 50%; }
.post h3 { font-size: 1.0625rem; line-height: 1.45; margin-bottom: 14px; }
.post h3 a:hover { color: var(--brand); }
.post .link-more { margin-top: auto; }

/* --------------------------------------------------------------------------
   16. CTA band
   -------------------------------------------------------------------------- */
.cta {
  position: relative;
  padding: 62px 56px;
  background: linear-gradient(120deg, var(--brand-700), var(--brand) 55%, var(--brand-400));
  border-radius: var(--radius-xl);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 34px;
  flex-wrap: wrap;
}
.cta::before {
  content: "";
  position: absolute;
  width: 380px; height: 380px;
  top: -160px; right: -60px;
  background: rgba(255, 255, 255, .1);
  border-radius: 50%;
}
.cta::after {
  content: "";
  position: absolute;
  width: 260px; height: 260px;
  bottom: -150px; left: 12%;
  background: rgba(255, 255, 255, .08);
  border-radius: 50%;
}
.cta > * { position: relative; z-index: 2; }
.cta h2 { color: #fff; margin-bottom: 8px; max-width: 640px; }
.cta p { color: rgba(255, 255, 255, .82); margin: 0; max-width: 560px; }
.cta__actions { display: flex; gap: 12px; flex-wrap: wrap; }

/* --------------------------------------------------------------------------
   17. Footer
   -------------------------------------------------------------------------- */
.footer { background: var(--paper); border-top: 1px solid var(--line); padding: 76px 0 0; }
.footer__grid {
  display: grid;
  grid-template-columns: 1.5fr 1fr 1fr 1.6fr;
  gap: 44px;
  padding-bottom: 54px;
}
.footer__about p { font-size: .9375rem; margin: 20px 0 20px; max-width: 320px; }
.footer h4 {
  margin-bottom: 20px;
  font-size: .9375rem;
  font-weight: 800;
  letter-spacing: -.01em;
}
.footer__links { display: grid; gap: 12px; }
.footer__links a { font-size: .9375rem; font-weight: 500; color: var(--body); }
.footer__links a:hover { color: var(--brand); padding-left: 4px; }
.footer__links a { transition: color .25s var(--ease), padding-left .25s var(--ease); }

.subscribe { display: flex; gap: 8px; margin-top: 18px; }
.subscribe input {
  flex: 1;
  min-width: 0;
  padding: 13px 15px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 10px;
  font-size: .875rem;
}
.subscribe input:focus { outline: 0; border-color: var(--brand-400); box-shadow: 0 0 0 4px rgba(157, 78, 221, .12); }
.subscribe button {
  width: 48px;
  display: grid;
  place-items: center;
  background: var(--brand);
  border: 0;
  border-radius: 10px;
  color: #fff;
  cursor: pointer;
  transition: background .25s var(--ease);
}
.subscribe button:hover { background: var(--brand-700); }
.footer__note { font-size: .8125rem; color: var(--muted); margin-top: 12px; }

.socials { display: flex; gap: 10px; margin-top: 6px; }
.socials a {
  width: 38px; height: 38px;
  display: grid; place-items: center;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--ink-2);
  transition: all .25s var(--ease);
}
.socials a:hover { background: var(--brand); border-color: var(--brand); color: #fff; transform: translateY(-3px); }

.footer__bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding: 24px 0;
  border-top: 1px solid var(--line);
  font-size: .8125rem;
  color: var(--muted);
}
.footer__bottom a:hover { color: var(--brand); }
.footer__legal { display: flex; gap: 22px; }

/* Back to top */
.to-top {
  position: fixed;
  right: 22px;
  bottom: 22px;
  z-index: 800;
  width: 46px; height: 46px;
  display: grid; place-items: center;
  background: var(--brand);
  border: 0;
  border-radius: 12px;
  color: #fff;
  cursor: pointer;
  box-shadow: var(--shadow-brand);
  opacity: 0;
  visibility: hidden;
  transform: translateY(12px);
  transition: all .3s var(--ease);
}
.to-top.is-visible { opacity: 1; visibility: visible; transform: translateY(0); }
.to-top:hover { background: var(--brand-700); }

/* --------------------------------------------------------------------------
   18. Scroll reveal
   -------------------------------------------------------------------------- */
/* Only hide-then-reveal when JS is running, so content is never lost
   if scripts fail to load. The `js` class is set by the inline head script. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}
.js [data-reveal].is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  /* The smooth scroll on <html> is a separate property from transitions and
     has to be cancelled by name, or anchor jumps still glide. */
  html { scroll-behavior: auto; }
  .js [data-reveal] { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   19. Responsive
   -------------------------------------------------------------------------- */
@media (max-width: 1180px) {
  .carousel__nav--prev { left: 6px; }
  .carousel__nav--next { right: 6px; }
  .footer__grid { grid-template-columns: 1.4fr 1fr 1fr; }
  .footer__news { grid-column: 1 / -1; }
}

/* The container caps usable width at 1152px, and the full nav needs 1136px of
 that. Below 1200px viewport there is less than that available, so the drawer
 takes over rather than letting the labels wrap onto two lines. */
@media (max-width: 1200px) {
  .nav, .header__actions .btn { display: none; }
  .hero__grid { gap: 40px; }
  .split { gap: 44px; }
  .contact__grid { gap: 40px; }
}

@media (max-width: 991px) {
  .section { padding: 74px 0; }
  .hero { padding: 56px 0 74px; }
  .hero__grid { grid-template-columns: 1fr; text-align: center; }
  .hero__text { margin-left: auto; margin-right: auto; }
  .hero__actions { justify-content: center; }
  .hero__visual { max-width: 500px; margin: 26px auto 34px; }
  .float-card--stat { top: -22px; right: 0; }
  .float-card--team { bottom: -26px; left: 0; }

  .grid-3 { grid-template-columns: repeat(2, 1fr); }
  .grid-4 { grid-template-columns: repeat(2, 1fr); }
  .split { grid-template-columns: 1fr; }
  .split--reverse .split__media { order: -1; }
  .stat-card { left: 12px; bottom: -22px; }
  .split__body { text-align: left; }
  .contact__grid { grid-template-columns: 1fr; }
  .carousel__slide { flex: 0 0 50%; }
  .carousel--projects .carousel__slide { flex: 0 0 50%; }
  .cta { padding: 46px 34px; text-align: center; justify-content: center; }
  .cta__actions { justify-content: center; width: 100%; }
  .footer__grid { grid-template-columns: 1fr 1fr; gap: 36px; }
}

@media (max-width: 767px) {
  body { font-size: 15px; }
  .section { padding: 62px 0; }
  .topbar__inner { justify-content: center; }
  .topbar__list--right { display: none; }
  .topbar__list { gap: 16px; justify-content: center; font-size: .75rem; }

  .grid-3, .grid-4, .grid-2 { grid-template-columns: 1fr; gap: 18px; }
  .carousel__slide { flex: 0 0 100%; }
  .carousel--projects .carousel__slide { flex: 0 0 100%; }
  .carousel__nav { display: none; }
  .sec-head { margin-bottom: 36px; }

  .feature { padding: 30px 24px; }
  .form-card { padding: 28px 22px; }
  .form-row { grid-template-columns: 1fr; }
  .info-grid { grid-template-columns: 1fr; gap: 22px; }
  .collage { padding: 0 0 40px 0; }
  .collage__sub { width: 52%; }
  .badge-card { right: 10px; bottom: 16px; padding: 11px 14px; max-width: 190px; }
  .badge-card strong { font-size: .875rem; }

  .float-card { gap: 12px; padding: 14px 16px; }
  .float-card--stat { top: -18px; right: -4px; max-width: 200px; }
  .float-card--team { bottom: -20px; left: -6px; max-width: 250px; }
  .float-card__icon { width: 38px; height: 38px; flex-basis: 38px; }
  .float-card__value { font-size: 1.125rem; }
  .float-card__label { font-size: .6875rem; }
  .float-card__note { font-size: .75rem; line-height: 1.55; }

  .footer { padding-top: 58px; }
  .footer__grid { grid-template-columns: 1fr; gap: 32px; padding-bottom: 40px; }
  .footer__bottom { justify-content: center; text-align: center; }
  .partners__list { justify-content: center; gap: 22px 30px; }
  .partner { font-size: .9375rem; }
  .cta { padding: 38px 24px; border-radius: var(--radius-lg); }
}

@media (max-width: 420px) {
  .container { padding: 0 18px; }
  .btn { padding: 13px 20px; font-size: .875rem; }
  .hero__actions { gap: 10px; }
  .logo__mark { width: 36px; height: 36px; flex-basis: 36px; }
  .logo__name { font-size: 1.125rem; }
}

/* --------------------------------------------------------------------------
   20. Install-the-app banner (PWA)
   -------------------------------------------------------------------------- */
.pwa-banner {
  position: fixed;
  z-index: 950;
  left: 50%;
  bottom: 18px;
  width: min(430px, calc(100vw - 28px));
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: 0 18px 50px rgba(20, 8, 43, .22);
  transform: translate(-50%, 140%);
  opacity: 0;
  transition: transform .38s var(--ease), opacity .38s var(--ease);
}
.pwa-banner.is-in { transform: translate(-50%, 0); opacity: 1; }

.pwa-banner__icon { width: 44px; height: 44px; border-radius: 11px; flex-shrink: 0; }
.pwa-banner__text { flex: 1; min-width: 0; line-height: 1.35; }
.pwa-banner__text b { display: block; font-size: .875rem; color: var(--ink); font-weight: 800; }
.pwa-banner__text span { font-size: .75rem; color: var(--muted); }

.pwa-banner__cta {
  flex-shrink: 0;
  padding: 10px 18px;
  background: var(--brand);
  color: #fff;
  border: 0;
  border-radius: 10px;
  font-size: .8125rem;
  font-weight: 700;
  cursor: pointer;
  transition: background .25s var(--ease);
}
.pwa-banner__cta:hover { background: var(--brand-700); }

.pwa-banner__close {
  flex-shrink: 0;
  width: 30px; height: 30px;
  display: grid; place-items: center;
  background: none;
  border: 0;
  border-radius: 8px;
  color: var(--muted);
  cursor: pointer;
}
.pwa-banner__close:hover { background: var(--paper); color: var(--ink); }

/* ---- iOS "Add to Home Screen" sheet ---- */
.pwa-sheet {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 14px;
  background: rgba(20, 8, 43, .55);
  backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity .3s var(--ease);
}
.pwa-sheet.is-in { opacity: 1; }

.pwa-sheet__panel {
  position: relative;
  width: min(430px, 100%);
  max-height: 88vh;
  overflow-y: auto;
  padding: 26px 22px 22px;
  background: #fff;
  border-radius: 22px;
  text-align: center;
  transform: translateY(24px);
  transition: transform .34s var(--ease);
}
.pwa-sheet.is-in .pwa-sheet__panel { transform: none; }

.pwa-sheet__close {
  position: absolute;
  top: 12px; right: 12px;
  width: 34px; height: 34px;
  display: grid; place-items: center;
  background: var(--paper);
  border: 0;
  border-radius: 10px;
  color: var(--ink-2);
  cursor: pointer;
}
.pwa-sheet__icon { width: 56px; height: 56px; border-radius: 14px; margin: 0 auto 12px; }
.pwa-sheet__panel h3 { font-size: 1.0625rem; margin-bottom: 6px; }
.pwa-sheet__panel > p { font-size: .8125rem; color: var(--muted); margin-bottom: 20px; }

.pwa-steps { display: grid; gap: 14px; text-align: left; margin-bottom: 22px; }
.pwa-steps li { display: flex; gap: 12px; align-items: flex-start; font-size: .875rem; color: var(--ink-2); }
.pwa-steps__n {
  flex-shrink: 0;
  width: 24px; height: 24px;
  display: grid; place-items: center;
  background: var(--brand-tint);
  color: var(--brand-700);
  border-radius: 50%;
  font-size: .75rem;
  font-weight: 800;
}
.pwa-steps b { color: var(--ink); }
.pwa-steps__share { vertical-align: -2px; color: var(--brand); }

.pwa-sheet__done {
  width: 100%;
  padding: 13px;
  background: var(--brand);
  color: #fff;
  border: 0;
  border-radius: 12px;
  font-size: .9375rem;
  font-weight: 700;
  cursor: pointer;
}
.pwa-sheet__done:hover { background: var(--brand-700); }

@media (max-width: 480px) {
  .pwa-banner { bottom: 12px; padding: 11px 12px; gap: 10px; border-radius: 14px; }
  .pwa-banner__icon { width: 38px; height: 38px; }
  .pwa-banner__cta { padding: 9px 14px; font-size: .78125rem; }
  .pwa-banner__text b { font-size: .8125rem; }
  .pwa-banner__text span { font-size: .6875rem; }
}

/* An installed app has no browser chrome, so the top strip is redundant */
@media (display-mode: standalone) {
  .topbar { display: none; }
}

/* --------------------------------------------------------------------------
   21. Partners page
   -------------------------------------------------------------------------- */

/* ---- hero: full-bleed monochrome photo with centred text over it ---- */
.phero {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 300px;
  padding: 72px 0;
  overflow: hidden;
  background: #16121a;
  text-align: center;
}
.phero__media { position: absolute; inset: 0; }
.phero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  opacity: .88;
}
/* Darkens the photo so the heading keeps its contrast on any crop */
.phero__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(12, 8, 18, .38), rgba(12, 8, 18, .58));
}
.phero__inner { position: relative; z-index: 2; }
.phero h1 {
  color: #fff;
  font-size: clamp(1.85rem, 4vw, 2.75rem);
  font-weight: 700;
  letter-spacing: -.01em;
  margin-bottom: 12px;
  text-shadow: 0 2px 18px rgba(0, 0, 0, .5);
}
.phero p {
  color: rgba(255, 255, 255, .78);
  font-size: clamp(.875rem, 1.4vw, 1rem);
  max-width: 620px;
  margin: 0 auto;
  text-shadow: 0 1px 12px rgba(0, 0, 0, .5);
}

/* ---- the grid of logo cards ---- */
.partner-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 16px;
}

.partner-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 116px;
  padding: 20px 16px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 12px;
  text-align: center;
  opacity: 0;
  transform: translateY(12px);
  transition: opacity .45s var(--ease), transform .45s var(--ease),
              border-color .25s var(--ease), box-shadow .25s var(--ease);
}
.partner-card.is-in { opacity: 1; transform: none; }

a.partner-card:hover {
  border-color: var(--brand-tint-2);
  box-shadow: 0 10px 26px rgba(20, 8, 43, .09);
  transform: translateY(-3px);
}

.partner-card__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
}
.partner-card__logo {
  max-width: 78%;
  max-height: 46px;
  width: auto;
  height: auto;
  object-fit: contain;
  /* Mixed-quality logos sit together better slightly muted, lifting on hover */
  filter: grayscale(.15);
  transition: filter .25s var(--ease);
}
a.partner-card:hover .partner-card__logo { filter: none; }

/* Shown until a logo has been uploaded for that partner */
.partner-card__fallback {
  display: grid;
  place-items: center;
  width: 42px; height: 42px;
  background: var(--brand-tint);
  color: var(--brand-700);
  border-radius: 11px;
  font-size: .9375rem;
  font-weight: 800;
}
.partner-card__name {
  font-size: .8125rem;
  font-weight: 700;
  color: var(--ink);
  line-height: 1.3;
}
.partner-card__tagline {
  font-size: .6875rem;
  color: var(--muted);
  line-height: 1.4;
}
.partner-card__badge {
  position: absolute;
  top: 8px; right: 8px;
  padding: 2px 8px;
  background: var(--brand);
  color: #fff;
  border-radius: 999px;
  font-size: .5625rem;
  font-weight: 800;
  letter-spacing: .04em;
  text-transform: uppercase;
}

/* ---- loading / empty states ---- */
.partner-grid__loading,
.partner-grid--empty {
  grid-column: 1 / -1;
  display: grid;
  place-items: center;
  gap: 12px;
  padding: 54px 20px;
  color: var(--muted);
  font-size: .875rem;
  text-align: center;
}
.partner-grid--empty { border: 1px dashed var(--line); border-radius: 14px; }
.partner-spinner {
  width: 26px; height: 26px;
  border: 2px solid var(--brand-tint-2);
  border-top-color: var(--brand);
  border-radius: 50%;
  animation: partner-spin .8s linear infinite;
}
@keyframes partner-spin { to { transform: rotate(360deg); } }

/* ---- closing call to action ---- */
.partner-cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 22px;
  flex-wrap: wrap;
  margin-top: 42px;
  padding: 26px 30px;
  background: var(--brand-tint);
  border-radius: var(--radius-lg);
}
.partner-cta h3 { margin-bottom: 4px; }
.partner-cta p { margin: 0; font-size: .875rem; color: var(--body); }

@media (max-width: 1080px) { .partner-grid { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 860px)  { .partner-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 560px) {
  .partner-grid { grid-template-columns: repeat(2, 1fr); gap: 12px; }
  .partner-card { min-height: 100px; padding: 16px 12px; }
  .partner-card__logo { max-height: 38px; }
  .phero { min-height: 240px; padding: 56px 0; }
  .partner-cta { padding: 22px; text-align: center; justify-content: center; }
  .partner-cta .btn { width: 100%; }
}

/* A partner whose logo is white needs a dark tile, or it shows as an empty box */
.partner-card--dark {
  background: #1b1526;
  border-color: #2b2338;
}
.partner-card--dark .partner-card__logo { filter: none; }
.partner-card--dark .partner-card__name { color: #fff; }
.partner-card--dark .partner-card__tagline { color: rgba(255, 255, 255, .6); }
.partner-card--dark .partner-card__fallback { background: rgba(255, 255, 255, .12); color: #fff; }
a.partner-card--dark:hover { border-color: var(--brand-400); }

/* --------------------------------------------------------------------------
   22. Keyboard focus
   Every interactive control gets a visible ring when reached by keyboard.
   `:where()` holds the specificity at zero, so the richer per-component focus
   styles further up the file (form fields, product cards) still win.
   -------------------------------------------------------------------------- */
:where(a[href], button, .btn, [tabindex]:not([tabindex="-1"])):focus-visible {
  outline: 3px solid var(--brand-400);
  outline-offset: 3px;
  border-radius: 6px;
}
/* On dark bands the mid purple sits too close to the background. */
.section--dark :where(a[href], button, .btn):focus-visible,
.footer :where(a[href], button, .btn):focus-visible,
.cta :where(a[href], button, .btn):focus-visible {
  outline-color: var(--brand-300);
}

/* Skip link: parked off-screen until focused, then drops in. */
.skip-link {
  position: fixed;
  left: 12px;
  top: -80px;
  z-index: 1000;
  padding: 12px 22px;
  background: var(--brand);
  color: #fff;
  font-size: .9375rem;
  font-weight: 700;
  border-radius: 0 0 10px 10px;
  box-shadow: var(--shadow-brand);
  transition: top .2s var(--ease);
}
.skip-link:focus { top: 0; }

/* The skip target is focusable so the ring is never painted around it. */
main:focus { outline: none; }

/* --------------------------------------------------------------------------
   23. Product card accents
   Each card carries one accent, chosen in the dashboard. Everything tinted by
   that choice reads from `--card-accent`, so a new preset needs one line here
   and one entry in ProductCard::ACCENTS.
   -------------------------------------------------------------------------- */
.product { --card-accent: var(--brand-300); }

.product--purple { --card-accent: #c77dff; }
.product--violet { --card-accent: #a78bfa; }
.product--blue   { --card-accent: #60a5fa; }
.product--teal   { --card-accent: #2dd4bf; }
.product--green  { --card-accent: #4ade80; }
.product--amber  { --card-accent: #fbbf24; }
.product--rose   { --card-accent: #fb7185; }
.product--slate  { --card-accent: #94a3b8; }

/* Featured is a ribbon plus a rim in the accent, not a different layout, so
   the row still reads as one set of cards. */
.product--featured {
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--card-accent) 60%, transparent),
              0 22px 52px rgba(8, 4, 20, .5);
}
.product__ribbon {
  position: absolute;
  top: 16px; right: 16px;
  z-index: 3;
  padding: 6px 12px;
  background: var(--card-accent);
  border-radius: 999px;
  font-size: .625rem;
  font-weight: 800;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: #10131a;
}

/* A card an admin left without a link is not clickable, so it must not offer
   the pointer cursor that promises it is. */
.product--static { cursor: default; }
.product--static:hover { transform: none; }

/* --------------------------------------------------------------------------
      24. Hero "Read more" (small screens only)
   The hero paragraph runs to a dozen lines on a phone, pushing the buttons
   below the fold. It is clamped to four lines there and expanded on demand.

   `.js` gates the whole thing: with scripting off the full text stays
   visible rather than being permanently truncated with no way to open it.
   -------------------------------------------------------------------------- */
.hero__more { display: none; }

@media (max-width: 767px) {
  .js .hero__text.is-clamped {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 4;
    line-clamp: 4;
    overflow: hidden;
    /* The clamp cuts mid-line, so trim the paragraph's own gap to the button
       and let the button supply the spacing instead. */
    margin-bottom: 12px;
  }

  /* Only shown once main.js has confirmed the text really is clipped. */
  .js .hero__more.is-available {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 0 0 26px;
    padding: 0;
    background: none;
    border: 0;
    font-size: .9375rem;
    font-weight: 700;
    color: var(--brand);
    cursor: pointer;
  }
  .hero__more svg {
    transition: transform .25s var(--ease);
  }
  .hero__more[aria-expanded="true"] svg { transform: rotate(180deg); }

  /* .hero__grid already centres everything below 991px; the button only
     needs its own auto margins to sit centred as a block-level flex item. */
  .js .hero__more.is-available { margin-left: auto; margin-right: auto; }
}

/* --------------------------------------------------------------------------
   25. Product orbit
   The product logos travel an ellipse in the gap under the hero.

   This is a port of the React Bits <OrbitImages /> component. That component
   wraps CSS `offset-path` in a motion/react animation; this site has no build
   step, so the same effect is done with `offset-path` plus one @keyframes and
   no JavaScript driving the frames at all.

   Items are spread around the path with a NEGATIVE animation-delay: an item
   started `i/n` of a lap ago is already `i/n` of the way round. That is the
   whole trick, and it means the browser owns the animation on the compositor.
   -------------------------------------------------------------------------- */
/* No heading: the band is the orbit and nothing else, so it carries its own
   breathing room rather than inheriting a section head's margins. */
.orbit-band { padding: 26px 0 30px; }

/* The design space is 900 x 300; the stage is scaled to whatever width the
   container actually has, so the path coordinates never need recalculating. */
.orbit {
  position: relative;
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
  aspect-ratio: 900 / 340;
}
.orbit__stage {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 900px;
  height: 340px;
  transform: translate(-50%, -50%) scale(var(--orbit-scale, 1));
  transform-origin: center center;
}
.orbit__ring {
  position: absolute;
  inset: 0;
  /* Tilts the whole ellipse. Each logo is counter-rotated so it stays upright. */
  transform: rotate(-8deg);
  transform-origin: center center;
}

/* The orbit path itself. It sits in the same rotated frame as the logos and
   uses the identical `d`, so the line and the travel are guaranteed to agree.
   `vector-effect: non-scaling-stroke` keeps it a hairline at every screen size
   instead of thinning out as the stage scales down. */
.orbit__path {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
  transform: rotate(-8deg);
  transform-origin: center center;
}
.orbit__path path {
  fill: none;
  stroke: rgba(123, 44, 191, .22);
  stroke-width: 1.5;
  stroke-dasharray: 5 7;
  stroke-linecap: round;
}

.orbit__item {
  position: absolute;
  width: 84px;
  height: 84px;
  /* The ellipse: centre 450,170 with radii 340 x 104. */
  offset-path: path("M 110 170 A 340 104 0 1 0 790 170 A 340 104 0 1 0 110 170");
  offset-rotate: 0deg;
  offset-anchor: center center;
  animation: orbit-travel 34s linear infinite;
  animation-delay: calc(var(--i) / var(--n) * -34s);
  will-change: offset-distance;
}
@keyframes orbit-travel {
  from { offset-distance: 0%; }
  to   { offset-distance: 100%; }
}

.orbit__item img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  border-radius: 18px;
  background: #fff;
  padding: 9px;
  box-shadow: 0 10px 26px rgba(20, 8, 43, .14);
  transform: rotate(8deg);        /* cancels the ring tilt */
}

.orbit__center {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  pointer-events: none;
}
.orbit__center img {
  /* Sized in the 900 x 340 design space, like the orbiting logos, so the stage
     transform scales the hub by exactly the same factor. Smaller than an
     orbiting logo and on its own plate, so it reads as the centre of the
     system rather than one more thing going round. */
  width: 44px;
  height: auto;
  padding: 16px;   /* 76px plate, against the 84px orbiting logos */
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 14px 34px rgba(123, 44, 191, .22);
  box-sizing: content-box;
}

/* A paused animation still honours its negative delay, so the logos stay
   spread around the ellipse rather than piling up at the start. */
@media (prefers-reduced-motion: reduce) {
  .orbit__item { animation-play-state: paused; }
}

/* Safari before 16 has no offset-path: fall back to a plain centred row so the
   logos are still shown rather than stacked on top of each other. */
@supports not (offset-path: path("M 0 0")) {
  .orbit { aspect-ratio: auto; height: auto; }
  .orbit__stage {
    position: static;
    width: 100%;
    height: auto;
    transform: none;
  }
  .orbit__ring {
    position: static;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 18px;
    transform: none;
  }
  .orbit__item {
    position: static;
    animation: none;
    offset-path: none;
  }
  .orbit__item img { transform: none; }
  .orbit__center { display: none; }
}

@media (max-width: 767px) {
  .orbit-band { padding: 14px 0 22px; }
  /* Design-space size, so it is multiplied by --orbit-scale like everything
     else. 105px here lands at roughly 40px on a 375px phone, where 84 would
     have shrunk to 28 and the logos stopped being readable. */
  .orbit__item { width: 105px; height: 105px; }
  .orbit__item img { border-radius: 22px; padding: 11px; }
}
