/* ============================================================
   EZPal product showcase — scoped styles for products.html only.
   Not imported by style.css / index.html. Uses EZPal's own brand
   tokens (Teal / Ivory / Ink), intentionally distinct from
   Avenor's dark/orange system in style.css.
   ============================================================ */

/* Page-specific top spacing fix: this page's first section sits
   directly under the fixed nav with no hero to push it down. */
#products-intro {
  padding-top: 168px;
}

/* ======================================================
   EZPAL SECTION — scoped brand tokens
   ====================================================== */
.ezpal {
  --ezpal-teal:      #14A38C;
  --ezpal-teal-dark: #0F7F6D;
  --ezpal-ivory:     #FFF8F0;
  --ezpal-ink:       #12131B;
  --ezpal-tint:      #E4F5F1;

  background: var(--ezpal-ivory);
  color: var(--ezpal-ink);
  border-top: 6px solid var(--ezpal-teal);
  padding: 88px 0 96px;
}

.ezpal__inner {
  max-width: 1080px;
}

.ezpal__top {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 28px;
}

.ezpal__chip {
  display: inline-block;
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ezpal-teal-dark);
  background: var(--ezpal-tint);
  border: 1px solid rgba(20,163,140,.35);
  border-radius: 999px;
  padding: 5px 14px;
}

/* ── Hero: copy column + floating phone-mockup visual ── */
.ezpal__hero {
  display: grid;
  grid-template-columns: 1.05fr .95fr;
  align-items: center;
  gap: 48px;
  margin-bottom: 32px;
}
/* Grid items default to `min-width: auto`, which floors their shrinkage
   at their content's min-content size rather than letting it wrap down
   to the track width. For a heading that's a real, pre-existing bug (not
   new here): at narrow viewports the hero title was silently clipped —
   body has `overflow-x: hidden` (style.css) so it never showed a
   scrollbar, it just cut the text off past the viewport edge. Explicit
   `min-width: 0` lets both columns actually shrink to fit and wrap. */
.ezpal__hero-copy,
.ezpal__hero-visual {
  min-width: 0;
}
.ezpal__hero-title {
  font-size: clamp(2rem, 4.1vw, 3.05rem);
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1.15;
  color: var(--ezpal-ink);
}
.ezpal__hero-title-accent {
  color: var(--ezpal-teal-dark);
}
.ezpal__tagline {
  display: block;
  font-size: 1.0625rem;
  font-weight: 500;
  font-style: italic;
  color: var(--ezpal-teal-dark);
  margin: 10px 0 28px;
}
.ezpal__hero-ctas {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
}
.ezpal__hero-visual {
  display: flex;
  justify-content: center;
}

/* ── Icon frame (nav logo mark; also used inline at smaller
   sizes on privacy/terms nav). Kept for those call sites. ── */
.ezpal__icon-frame {
  width: 76px;
  height: 76px;
  flex-shrink: 0;
  border-radius: 20px;
  overflow: hidden;
  box-shadow: 0 6px 20px rgba(18,19,27,.18);
}
.ezpal__icon-frame svg {
  display: block;
  width: 100%;
  height: 100%;
}

.ezpal__lede {
  font-size: 1.0625rem;
  line-height: 1.75;
  color: rgba(18,19,27,.82);
  margin-bottom: 48px;
  max-width: 760px;
}

/* ======================================================
   PHONE MOCKUP — reusable device frame for screenshots.
   Screenshots are full-bleed simulator captures (no bezel
   baked in) at native 1206×2622 (iPhone 15/16 Pro), so the
   frame's aspect-ratio is locked to that and a decorative
   Dynamic Island pill is overlaid at the real device's
   position (HIG: ~126×37pt island, 11pt top inset, centered
   → top 1.6% / width 30% / height 4.3% of frame here).
   ====================================================== */
.ezpal-phone {
  position: relative;
  width: 100%;
  aspect-ratio: 1206 / 2622;
  border-radius: 28px;
  overflow: hidden;
  background: var(--ezpal-tint);
  border: 1px solid rgba(18,19,27,.08);
  box-shadow:
    0 24px 48px -14px rgba(18,19,27,.35),
    0 0 0 1px rgba(18,19,27,.05),
    inset 0 0 0 1px rgba(255,255,255,.5);
}
.ezpal-phone img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.ezpal-phone__island {
  position: absolute;
  top: 1.6%;
  left: 50%;
  transform: translateX(-50%);
  width: 30%;
  height: 4.3%;
  min-height: 10px;
  background: rgba(18,19,27,.94);
  border-radius: 999px;
  z-index: 2;
}

.ezpal-phone--hero {
  width: min(300px, 72vw);
  border-radius: 40px;
  animation: ezpalFloat 6s ease-in-out infinite;
}
@keyframes ezpalFloat {
  0%, 100% { transform: translateY(0)     rotate(-3deg); }
  50%      { transform: translateY(-14px) rotate(-3deg); }
}
@media (prefers-reduced-motion: reduce) {
  .ezpal-phone--hero { animation: none; }
}

.ezpal-phone--tile {
  border-radius: 26px;
}

/* ======================================================
   SCREENSHOT SHOWCASE
   A compact tiled grid — the base layout IS the only layout, always on,
   no viewport-width gate and no motion-preference gate. See the HTML
   comment above .ezpal__showcase-grid for why (a prior pinned-scroll
   version gated the good layout behind min-width:860px plus
   no-preference and fell through to a plain stacked column outside that
   band, which is worse than what it replaced).

   Motion here is layered on top of this one layout, not swapped in for
   it: tiles fade/lift/scale into place as they enter the viewport
   (`.reveal`, same IntersectionObserver as the rest of the page) and
   lift further on hover. The prefers-reduced-motion block right below
   keeps the identical grid and drops only the movement.
   ====================================================== */
.ezpal__showcase {
  margin-bottom: 56px;
}
.ezpal__showcase-heading {
  font-size: 1.375rem;
  font-weight: 700;
  color: var(--ezpal-ink);
  margin-bottom: 26px;
}
.ezpal__showcase-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 22px;
}
.ezpal__showcase-item {
  background: #fff;
  border: 1px solid rgba(20,163,140,.18);
  border-radius: 22px;
  padding: 16px 16px 22px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  cursor: default;
  transition: opacity .6s ease, transform .55s cubic-bezier(.4,0,.2,1),
              border-color .25s ease, box-shadow .25s ease;
}
/* Extends `.reveal`'s entrance (style.css) with a touch of scale, and owns
   the hover lift. `.reveal` in style.css is now gated as `.js .reveal` /
   `.js .reveal.in-view` (specificity 0,2,0 / 0,3,0 — see that file's
   comment) to fix a no-JS blank-page hazard, which put it ABOVE this
   class's own 0,1,0. Compounding with `.reveal` here (present on the same
   element in the HTML) reliably clears that bar instead of depending on a
   same-specificity source-order tiebreak, which is what the pre-existing
   opacity note below already warns is fragile. Opacity itself stays owned
   by `.reveal`/`.js .reveal.in-view` — only `transform` is redeclared. */
.ezpal__showcase-item.reveal {
  transform: translateY(28px) scale(.97);
}
.ezpal__showcase-item.reveal.in-view {
  transform: none;
}
.ezpal__showcase-item.reveal:hover {
  border-color: var(--ezpal-teal);
  transform: translateY(-6px);
  box-shadow: 0 20px 40px rgba(18,19,27,.16);
}
.ezpal__showcase-item:nth-child(1) { transition-delay: 0s; }
.ezpal__showcase-item:nth-child(2) { transition-delay: .1s; }
.ezpal__showcase-item:nth-child(3) { transition-delay: .2s; }
.ezpal__showcase-item:nth-child(4) { transition-delay: .3s; }
.ezpal__showcase-item.reveal:hover { transition-delay: 0s; }

.ezpal__showcase-caption h3 {
  font-size: 1rem;
  font-weight: 700;
  color: var(--ezpal-ink);
  line-height: 1.35;
  margin-bottom: 6px;
}
.ezpal__showcase-caption p {
  font-size: .85rem;
  line-height: 1.6;
  color: rgba(18,19,27,.68);
}

/* Same grid, no movement: the entrance settle and the hover lift both
   drop their transform, leaving only the opacity fade (handled by
   .reveal in style.css) and the border/shadow hover cues. Same
   specificity reasoning as above — compound with `.reveal` so this
   reliably wins rather than tying with `.js .reveal`. */
@media (prefers-reduced-motion: reduce) {
  .ezpal__showcase-item.reveal,
  .ezpal__showcase-item.reveal.in-view,
  .ezpal__showcase-item.reveal:hover {
    transform: none;
    transition: opacity .3s ease, border-color .25s ease, box-shadow .25s ease;
  }
}

/* ── Feature grid ── */
.ezpal__features {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 18px;
  margin-bottom: 56px;
}
.ezpal__feature {
  background: #fff;
  border: 1px solid rgba(20,163,140,.18);
  border-radius: 16px;
  padding: 24px;
  position: relative;
  /* opacity must stay in this transition list, or `.reveal`'s
     (style.css) fade-in breaks. */
  transition: opacity .6s ease, transform .45s cubic-bezier(.4,0,.2,1),
              border-color .25s ease, box-shadow .25s ease;
}
/* `.reveal` in style.css is gated as `.js .reveal.in-view` (specificity
   0,3,0) to fix a no-JS blank-page hazard, which sits above this
   element's own hover rule at plain `.ezpal__feature:hover` (0,2,0) — the
   hover lift would silently lose to `.js .reveal.in-view`'s `transform:
   none` once an element is revealed (i.e. almost always, by the time a
   visitor can hover it). Compounding with `.reveal` (present on the same
   element) reliably clears that bar. */
.ezpal__feature.reveal:hover {
  border-color: var(--ezpal-teal);
  transform: translateY(-4px);
  box-shadow: 0 16px 32px rgba(18,19,27,.12);
}
@media (prefers-reduced-motion: reduce) {
  .ezpal__feature.reveal:hover {
    transform: none;
  }
}
.ezpal__feature--flagship {
  background: var(--ezpal-teal);
  border-color: var(--ezpal-teal);
  color: var(--ezpal-ivory);
  grid-column: 1 / -1;
  padding: 28px 28px 26px;
}
.ezpal__feature--flagship:hover {
  border-color: var(--ezpal-teal);
  box-shadow: 0 20px 44px rgba(15,127,109,.35);
}
.ezpal__feature:nth-child(1) { transition-delay: 0s; }
.ezpal__feature:nth-child(2) { transition-delay: .05s; }
.ezpal__feature:nth-child(3) { transition-delay: .1s; }
.ezpal__feature:nth-child(4) { transition-delay: .15s; }
.ezpal__feature:nth-child(5) { transition-delay: .2s; }
.ezpal__feature:nth-child(6) { transition-delay: .25s; }
.ezpal__feature:hover { transition-delay: 0s; }
.ezpal__feature-tag {
  display: inline-block;
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ezpal-ivory);
  background: rgba(255,248,240,.16);
  border-radius: 999px;
  padding: 3px 10px;
  margin-bottom: 12px;
}
.ezpal__feature h3 {
  font-size: 1.0625rem;
  font-weight: 700;
  margin-bottom: 8px;
  line-height: 1.3;
}
.ezpal__feature--flagship h3 { font-size: 1.25rem; }
.ezpal__feature p {
  font-size: .9rem;
  line-height: 1.6;
  color: rgba(18,19,27,.72);
}
.ezpal__feature--flagship p {
  color: rgba(255,248,240,.92);
  font-size: .95rem;
}

/* ── Who it's for ── */
.ezpal__for {
  max-width: 760px;
  background: var(--ezpal-tint);
  border-radius: 20px;
  padding: 36px;
  margin-bottom: 48px;
}
.ezpal__for h3 {
  font-size: 1.375rem;
  font-weight: 700;
  margin-bottom: 14px;
  color: var(--ezpal-ink);
}
.ezpal__for p {
  font-size: .9375rem;
  line-height: 1.75;
  color: rgba(18,19,27,.8);
}
.ezpal__for p + p { margin-top: 14px; }

/* ── Status / CTA ── */
.ezpal__status {
  border-top: 1px solid rgba(20,163,140,.25);
  padding-top: 40px;
}
.ezpal__status h3 {
  font-size: 1.375rem;
  font-weight: 700;
  margin-bottom: 10px;
  color: var(--ezpal-ink);
}
.ezpal__status p {
  font-size: .9375rem;
  line-height: 1.7;
  color: rgba(18,19,27,.78);
  max-width: 560px;
  margin-bottom: 22px;
}

.ezpal__status-ctas {
  display: flex;
  align-items: center;
  gap: 28px;
  flex-wrap: wrap;
}

/* ── Official "Download on the App Store" badge, plus a QR code ──
   Badge artwork is Apple's unmodified SVG (assets/app-store-badge.svg),
   never redrawn. Apple's marketing guidelines require: only the
   provided artwork, unaltered; clear space around it so nothing
   crowds the mark; and a minimum height of 40pt. The link's own
   padding acts as that clear space, and the image is set well above
   the 40pt floor.

   Both images live inside this one <a> (see the HTML comment above
   .ezpal__store-cta) so there is exactly one URL driving both — they
   cannot point to two different places. */
.ezpal__badge-link {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 10px;
  border-radius: 12px;
  transition: opacity .2s ease, transform .2s ease;
}
.ezpal__badge-link:hover,
.ezpal__badge-link:focus-visible {
  opacity: .8;
  transform: translateY(-2px);
}
@media (prefers-reduced-motion: reduce) {
  .ezpal__badge-link:hover,
  .ezpal__badge-link:focus-visible {
    transform: none;
  }
}
.ezpal__badge-label {
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ezpal-teal-dark);
}

/* The closing CTA: centered, at the bottom of the page's content, badge
   and QR side by side (stacked under 560px — see the media query below). */
.ezpal__store-cta {
  display: flex;
  justify-content: center;
  margin-top: 28px;
  text-align: center;
}
.ezpal__store-row {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}
.ezpal__store-badge {
  display: block;
  height: 54px;
  width: auto;
}
.ezpal__store-or {
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: rgba(18,19,27,.4);
}
.ezpal__store-qr {
  display: block;
  width: 128px;
  height: 128px;
  border-radius: 10px;
  border: 1px solid rgba(18,19,27,.08);
  /* The QR's own quiet zone (4 modules, baked into
     assets/app-store-qr.svg) already gives it breathing room — this
     border just draws the card edge, it isn't a second quiet zone. */
}
@media (min-width: 560px) {
  .ezpal__store-row {
    flex-direction: row;
  }
}

/* Reuse global .btn/.btn--primary structure, recolor for the
   teal brand scope (higher specificity than .btn--primary alone). */
.ezpal .btn--primary {
  background: var(--ezpal-teal);
  border-color: var(--ezpal-teal);
  color: var(--ezpal-ivory);
}
.ezpal .btn--primary:hover {
  background: var(--ezpal-teal-dark);
  border-color: var(--ezpal-teal-dark);
  box-shadow: 0 0 32px rgba(20,163,140,.28);
}

@media (max-width: 980px) {
  .ezpal__hero {
    grid-template-columns: 1fr;
    gap: 36px;
  }
  .ezpal__hero-copy { text-align: left; }
  .ezpal-phone--hero { width: min(280px, 62vw); }
}

@media (max-width: 600px) {
  #products-intro { padding-top: 140px; }
  .ezpal { padding: 64px 0 72px; }
  .ezpal__icon-frame { width: 64px; height: 64px; border-radius: 16px; }
  .ezpal__for, .ezpal__feature--flagship { padding: 24px; }
  .ezpal-phone--hero { width: min(240px, 58vw); border-radius: 32px; }
  .ezpal-phone--tile { border-radius: 22px; }
  .ezpal__store-qr { width: 112px; height: 112px; }
}
