/* =========================================================
   Zapp case study — iPhone mockups, order tracking, Zapp+
   Loads alongside case.css. Namespaced .zp-*
   ========================================================= */

/* Zapp brand colour. #002533 is the true primary (deep navy-teal) and is used
   in light mode. On dark backgrounds it would be invisible as text, so the
   default/dark accent is a lighter sibling from the same teal family. */
:root { --zp: #2f8aa6; --zp-deep: #002533; }
:root[data-theme="light"] { --zp: #002533; }

.zp-lead {
  /* override the global `p { display:flex }` from case.css so the leading
     <strong> label stays inline and the copy runs full width */
  display: block;
  font-size: 1.05rem;
  color: rgba(255, 255, 255, 0.82);
  line-height: 1.7;
  max-width: none;
}
[data-theme="light"] .zp-lead { color: rgba(0, 0, 0, 0.75); }

/* ---------- Brand banner ---------- */
.zp-banner {
  border-radius: 18px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: 0 24px 60px -30px rgba(0, 0, 0, 0.6);
}
.zp-banner img { width: 100%; display: block; }
[data-theme="light"] .zp-banner { border-color: rgba(0, 0, 0, 0.08); }

/* ---------- Design principles ---------- */
.zp-principles {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.1rem;
  margin-top: 1.5rem;
}
.zp-principle {
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 14px;
  padding: 1.35rem;
  background: rgba(255, 255, 255, 0.02);
}
.zp-principle-n {
  font-family: 'Playfair Display', serif;
  font-size: 1.4rem; font-weight: 700; color: var(--zp);
  display: block; margin-bottom: 0.35rem; line-height: 1;
}
.zp-principle h4 { margin: 0 0 0.4rem; font-size: 1.02rem; font-weight: 600; }
.zp-principle p { margin: 0; font-size: 0.9rem; color: rgba(255, 255, 255, 0.6); line-height: 1.55; }
[data-theme="light"] .zp-principle { border-color: rgba(0, 0, 0, 0.1); background: rgba(0, 0, 0, 0.02); }
[data-theme="light"] .zp-principle p { color: rgba(0, 0, 0, 0.6); }

/* ---------- Impact ---------- */
.zp-impact {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.1rem;
  margin-top: 1.5rem;
}
.zp-impact-card {
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 14px;
  padding: 1.4rem 1.3rem;
  background: rgba(255, 255, 255, 0.02);
}
.zp-impact-card b {
  font-family: 'Playfair Display', serif;
  font-size: 1.5rem; font-weight: 700; color: var(--zp);
  display: block; margin-bottom: 0.4rem;
}
.zp-impact-card span { font-size: 0.88rem; color: rgba(255, 255, 255, 0.62); line-height: 1.5; }
[data-theme="light"] .zp-impact-card { border-color: rgba(0, 0, 0, 0.1); background: rgba(0, 0, 0, 0.02); }
[data-theme="light"] .zp-impact-card span { color: rgba(0, 0, 0, 0.62); }

/* ---------- Context / challenge bullets ---------- */
.zp-challenge { list-style: none; padding: 0; margin: 1rem 0 0; }
.zp-challenge li {
  position: relative; padding-left: 1.4rem; margin-bottom: 0.7rem;
  color: rgba(255, 255, 255, 0.72); line-height: 1.55;
}
.zp-challenge li::before {
  content: ""; position: absolute; left: 0; top: 0.55em;
  width: 6px; height: 6px; border-radius: 50%; background: var(--zp);
}
[data-theme="light"] .zp-challenge li { color: rgba(0, 0, 0, 0.72); }

@media (max-width: 768px) {
  .zp-principles, .zp-impact { grid-template-columns: 1fr; }
}

/* ---------- iPhone mockup ---------- */
.zp-phones {
  display: flex;
  gap: 2.5rem 3rem;
  justify-content: center;
  align-items: flex-start;
  flex-wrap: wrap;
  margin: 0.5rem 0 0;
}
.zp-phone-wrap { display: flex; flex-direction: column; align-items: center; }
.zp-phone {
  position: relative;
  width: 268px;
  max-width: 74vw;
  border-radius: 42px;
  background: #0a0a0a;
  padding: 10px;
  box-shadow: 0 34px 70px -26px rgba(0, 0, 0, 0.65), inset 0 0 0 1.5px rgba(255, 255, 255, 0.07);
}
.zp-phone::before {
  content: "";
  position: absolute;
  top: 19px; left: 50%; transform: translateX(-50%);
  width: 84px; height: 24px;
  background: #0a0a0a; border-radius: 99px; z-index: 3;
}
.zp-phone img { width: 100%; display: block; border-radius: 33px; cursor: zoom-in; }
.zp-phone-label {
  font-size: 0.84rem;
  color: rgba(255, 255, 255, 0.55);
  margin-top: 1.1rem;
  text-align: center;
  max-width: 24ch;
}
[data-theme="light"] .zp-phone-label { color: rgba(0, 0, 0, 0.55); }

/* Placeholder when a screen is still pending */
.zp-phone-pending {
  width: 268px; max-width: 74vw;
  aspect-ratio: 9 / 19.5;
  border-radius: 42px;
  border: 1.5px dashed rgba(255, 255, 255, 0.18);
  display: flex; align-items: center; justify-content: center;
  text-align: center; padding: 1.5rem;
  font-size: 0.82rem; color: rgba(255, 255, 255, 0.4);
}
[data-theme="light"] .zp-phone-pending { border-color: rgba(0,0,0,0.18); color: rgba(0,0,0,0.4); }

/* ---------- Zapp+ section ---------- */
.zp-plus-hero {
  border-radius: 18px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.08);
}
.zp-plus-hero img { width: 100%; display: block; }
[data-theme="light"] .zp-plus-hero { border-color: rgba(0, 0, 0, 0.08); }

.zp-feats {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.1rem;
  margin: 2rem 0 0;
  padding: 0;
  list-style: none;
}
/* ---------- Card tokens: every boxed card on the page shares these ---------- */
:root {
  --zpx-card-bg: rgba(255, 255, 255, 0.02);
  --zpx-card-line: rgba(255, 255, 255, 0.1);
  --zpx-card-radius: 14px;
}
[data-theme="light"] {
  --zpx-card-bg: rgba(0, 0, 0, 0.02);
  --zpx-card-line: rgba(0, 0, 0, 0.1);
}

.zp-feat {
  display: flex;
  gap: 0.9rem;
  align-items: flex-start;
  border: 1px solid var(--zpx-card-line);
  border-radius: var(--zpx-card-radius);
  padding: 1.1rem 1.15rem;
  background: var(--zpx-card-bg);
}
.zp-feat-ic {
  /* Bare icon, no chip: twice the size, and it draws itself in on reveal. */
  flex: none; display: grid; place-items: center;
  width: 64px; height: 64px;
  color: var(--zp);
}
.zp-feat-ic svg {
  width: 44px; height: 44px; display: block;
  stroke-width: 1.75;
}
/* Reveal: each icon pops and settles, staggered down the list. Hidden state
   only when the motion layer is on, so no-JS still shows them. */
.js-motion .zp-feat-ic svg {
  opacity: 0; transform: scale(0.35) rotate(-18deg);
  transition: opacity 0.45s ease calc(var(--i, 0) * 110ms),
              transform 0.75s cubic-bezier(0.34, 1.56, 0.64, 1) calc(var(--i, 0) * 110ms);
}
.js-motion .is-in .zp-feat-ic svg { opacity: 1; transform: none; }
.zp-feat:nth-child(1) .zp-feat-ic { --i: 0; }
.zp-feat:nth-child(2) .zp-feat-ic { --i: 1; }
.zp-feat:nth-child(3) .zp-feat-ic { --i: 2; }
.zp-feat:nth-child(4) .zp-feat-ic { --i: 3; }
@media (prefers-reduced-motion: reduce) {
  .js-motion .zp-feat-ic svg { opacity: 1; transform: none; transition: none; }
}

.zp-feat b { display: block; font-size: 0.98rem; margin-bottom: 0.15rem; }
.zp-feat span { font-size: 0.88rem; color: rgba(255, 255, 255, 0.6); line-height: 1.5; }
[data-theme="light"] .zp-feat span { color: rgba(0, 0, 0, 0.6); }

.zp-price {
  display: inline-flex;
  align-items: baseline;
  gap: 0.6rem;
  margin-top: 2rem;
  padding: 0.7rem 1.1rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--zp) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--zp) 35%, transparent);
}
.zp-price b { font-size: 1.15rem; color: var(--zp); }
.zp-price span { font-size: 0.88rem; color: rgba(255, 255, 255, 0.6); }
[data-theme="light"] .zp-price span { color: rgba(0, 0, 0, 0.6); }
[data-theme="light"] .zp-price b { color: var(--zp); }

/* ---------- Placeholder slots (visuals added later) ---------- */
.zp-ph {
  border: 1.5px dashed rgba(255, 255, 255, 0.18);
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.015);
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  text-align: center; gap: 0.55rem;
  padding: 2.75rem 1.5rem; min-height: 220px;
  color: rgba(255, 255, 255, 0.42);
  margin-top: 1.75rem;
}
.zp-ph svg { width: 30px; height: 30px; opacity: 0.55; }
.zp-ph b { font-size: 0.92rem; font-weight: 600; color: rgba(255, 255, 255, 0.62); }
.zp-ph span { font-size: 0.82rem; max-width: 46ch; line-height: 1.55; }
[data-theme="light"] .zp-ph { border-color: rgba(0, 0, 0, 0.18); background: rgba(0, 0, 0, 0.015); color: rgba(0, 0, 0, 0.42); }
[data-theme="light"] .zp-ph b { color: rgba(0, 0, 0, 0.62); }

/* Two-up placeholder grid (e.g. ops tools, rebrand before/after) */
.zp-ph-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.1rem;
  margin-top: 1.75rem;
}
.zp-ph-grid .zp-ph { margin-top: 0; }
@media (max-width: 768px) { .zp-ph-grid { grid-template-columns: 1fr; } }

/* ---------- Real figures / screenshots ---------- */
.zp-shot {
  display: block;
  margin-top: 1.75rem;
  border-radius: 16px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: 0 24px 60px -34px rgba(0, 0, 0, 0.6);
}
.zp-shot img { width: 100%; display: block; cursor: zoom-in; }
[data-theme="light"] .zp-shot { border-color: rgba(0, 0, 0, 0.08); }

.zp-grid-2 {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.1rem;
  margin-top: 1.75rem;
}
.zp-grid-2 .zp-shot { margin-top: 0; }
@media (max-width: 768px) { .zp-grid-2 { grid-template-columns: 1fr; } }

.zp-grid-3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.1rem;
  margin-top: 1.75rem;
}
.zp-grid-3 .zp-shot { margin-top: 0; }
@media (max-width: 768px) { .zp-grid-3 { grid-template-columns: 1fr; } }

.zp-cap {
  font-size: 0.84rem;
  color: rgba(255, 255, 255, 0.55);
  margin: 0.7rem 0 0;
  text-align: center;
}
[data-theme="light"] .zp-cap { color: rgba(0, 0, 0, 0.55); }

/* ---------- Zync pipeline (cards with brand logos) ---------- */
.zp-flow {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.9rem;
  margin: 1.9rem 0 0;
}
.zp-flow-step {
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 14px;
  padding: 1.3rem 1.15rem;
  background: rgba(255, 255, 255, 0.02);
}
/* white logo chip — same look as the home toolchain */
.zp-flow-ic {
  width: 44px; height: 44px;
  border-radius: 12px;
  background: #fff;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 16px -5px rgba(0, 0, 0, 0.4);
  border: 1px solid rgba(0, 0, 0, 0.07);
  margin-bottom: 0.9rem;
}
.zp-flow-ic img { width: 24px; height: 24px; display: block; }
.zp-flow-step h4 { margin: 0 0 0.35rem; font-size: 0.96rem; font-weight: 600; }
.zp-flow-step p { margin: 0; font-size: 0.85rem; color: rgba(255, 255, 255, 0.6); line-height: 1.55; }
.zp-flow-step small {
  display: block; margin-top: 0.6rem;
  font-size: 0.74rem; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--zp); font-weight: 600;
}
[data-theme="light"] .zp-flow-step { border-color: rgba(0, 0, 0, 0.1); background: rgba(0, 0, 0, 0.02); }
[data-theme="light"] .zp-flow-step p { color: rgba(0, 0, 0, 0.6); }
@media (max-width: 768px) { .zp-flow { grid-template-columns: 1fr 1fr; } }
@media (max-width: 460px) { .zp-flow { grid-template-columns: 1fr; } }

/* ---------- Closing / CTA ---------- */
.zp-closing { max-width: none; }
.zp-cta {
  display: inline-flex; align-items: center; gap: 0.5rem;
  margin-top: 1.6rem; padding: 0.8rem 1.4rem;
  border-radius: 999px;
  background: var(--zp); color: #fff;
  font-weight: 600; font-size: 0.95rem;
  text-decoration: none;
  transition: opacity 0.2s, transform 0.2s;
}
.zp-cta:hover { opacity: 0.9; transform: translateY(-1px); }
.zp-cta svg { width: 17px; height: 17px; }

/* ---------- Lightbox (same pattern as yoobic-story) ---------- */
.zp-lightbox {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 9000;
  background: rgba(0, 0, 0, 0.94);
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 1.1rem;
  padding: 2rem;
  cursor: zoom-out;
}
.zp-lightbox.is-open { display: flex; animation: zp-lb-in 0.18s ease; }
@keyframes zp-lb-in { from { opacity: 0; } to { opacity: 1; } }

.zp-lightbox-img {
  max-width: min(92vw, 1200px);
  max-height: 84vh;
  width: auto;
  height: auto;
  border-radius: 10px;
  box-shadow: 0 48px 100px -20px rgba(0, 0, 0, 0.95);
  cursor: default;
  animation: zp-lb-scale 0.22s cubic-bezier(0.22, 1, 0.36, 1);
}
@keyframes zp-lb-scale {
  from { transform: scale(0.93); opacity: 0; }
  to   { transform: scale(1);    opacity: 1; }
}

.zp-lightbox-caption {
  font-size: 0.82rem;
  color: rgba(255, 255, 255, 0.5);
  text-align: center;
  max-width: 580px;
  line-height: 1.5;
  margin: 0;
  cursor: default;
}

.zp-lightbox-close {
  position: fixed;
  top: 1.25rem;
  right: 1.5rem;
  width: 2.4rem;
  height: 2.4rem;
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 50%;
  color: #fff;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.18s;
  flex-shrink: 0;
}
.zp-lightbox-close:hover { background: rgba(255, 255, 255, 0.2); }

/* ---------- Confidentiality note ---------- */
.zp-confidential {
  display: block;
  font-size: 0.92rem;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.6);
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 10px;
  padding: 1rem 1.25rem;
  max-width: none;
}
[data-theme="light"] .zp-confidential { color: rgba(0, 0, 0, 0.6); background: rgba(0, 0, 0, 0.02); }

@media (max-width: 768px) {
  .zp-feats { grid-template-columns: 1fr; }
}

/* ---------- Operational tooling diagram (DC & FC) ---------- */
.zp-ops-diagram { margin-top: 2.25rem; }
.zp-dia-title {
  font-size: 0.76rem; font-weight: 600; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--zp); margin: 0 0 1.1rem;
}

/* End-to-end operational spine */
.zp-spine {
  display: flex; align-items: stretch; flex-wrap: wrap; gap: 0.5rem;
  padding: 1rem 1.1rem; border-radius: 14px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(255, 255, 255, 0.02);
}
.zp-spine-node {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; gap: 0.08rem; min-width: 82px;
  padding: 0.55rem 0.7rem; border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(255, 255, 255, 0.03);
  font-size: 0.82rem; color: rgba(255, 255, 255, 0.72);
}
.zp-spine-node b { font-size: 0.98rem; color: #fff; line-height: 1.1; }
.zp-spine-node small { font-size: 0.66rem; color: rgba(255, 255, 255, 0.5); }
.zp-spine-node--key { background: var(--zp); border-color: var(--zp); }
.zp-spine-node--key b, .zp-spine-node--key small { color: #fff; }
.zp-spine-arrow { align-self: center; color: var(--zp); font-weight: 700; }
[data-theme="light"] .zp-spine { border-color: rgba(0, 0, 0, 0.1); background: rgba(0, 0, 0, 0.02); }
[data-theme="light"] .zp-spine-node { border-color: rgba(0, 0, 0, 0.12); background: #fff; color: rgba(0, 0, 0, 0.72); }
[data-theme="light"] .zp-spine-node b { color: #111; }
[data-theme="light"] .zp-spine-node small { color: rgba(0, 0, 0, 0.5); }
[data-theme="light"] .zp-spine-node--key b,
[data-theme="light"] .zp-spine-node--key small { color: #fff; }

/* DC | my role | FC */
.zp-dia-grid {
  display: grid;
  grid-template-columns: 1fr auto 1.25fr auto 1fr;
  align-items: stretch; gap: 0.6rem; margin-top: 1.1rem;
}
.zp-dia-link { align-self: center; justify-self: center; color: var(--zp); font-size: 1.25rem; }

.zp-dia-tool {
  border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 14px;
  padding: 1.1rem 1.15rem; background: rgba(255, 255, 255, 0.02);
}
.zp-dia-tool-head { font-size: 0.96rem; font-weight: 700; margin-bottom: 0.7rem; display: flex; flex-direction: column; }
.zp-dia-tool-head span {
  font-size: 0.68rem; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--zp); margin-top: 0.15rem;
}
.zp-dia-tool ul { list-style: none; margin: 0; padding: 0; }
.zp-dia-tool li {
  position: relative; padding-left: 1rem; margin-bottom: 0.45rem;
  font-size: 0.85rem; color: rgba(255, 255, 255, 0.7); line-height: 1.4;
}
.zp-dia-tool li::before {
  content: ""; position: absolute; left: 0; top: 0.5em;
  width: 5px; height: 5px; border-radius: 50%; background: var(--zp);
}
[data-theme="light"] .zp-dia-tool { border-color: rgba(0, 0, 0, 0.1); background: rgba(0, 0, 0, 0.02); }
[data-theme="light"] .zp-dia-tool li { color: rgba(0, 0, 0, 0.7); }

/* Central "my role" loop */
.zp-dia-core {
  border-radius: 14px; padding: 1.2rem 1.15rem;
  background: var(--zp); color: #fff; display: flex; flex-direction: column;
}
.zp-dia-core-label {
  font-size: 0.7rem; font-weight: 600; letter-spacing: 0.09em; text-transform: uppercase;
  color: rgba(255, 255, 255, 0.7); margin-bottom: 0.85rem;
}
.zp-dia-loop { counter-reset: loop; display: flex; flex-direction: column; gap: 0.5rem; }
.zp-dia-loop span {
  counter-increment: loop; position: relative;
  padding: 0.5rem 0.7rem 0.5rem 2.1rem; border-radius: 9px;
  background: rgba(255, 255, 255, 0.14); font-size: 0.84rem; line-height: 1.3;
}
.zp-dia-loop span::before {
  content: counter(loop); position: absolute; left: 0.55rem; top: 50%; transform: translateY(-50%);
  width: 1.2rem; height: 1.2rem; border-radius: 50%;
  background: #fff; color: var(--zp-deep);
  font-size: 0.7rem; font-weight: 700; display: flex; align-items: center; justify-content: center;
}
.zp-dia-loop-note {
  margin: 0.75rem 0 0; font-size: 0.72rem; color: rgba(255, 255, 255, 0.7);
  display: flex; align-items: center; gap: 0.35rem;
}
.zp-dia-loop-note svg { width: 13px; height: 13px; }

@media (max-width: 820px) {
  .zp-dia-grid { grid-template-columns: 1fr; }
  .zp-dia-link { transform: rotate(90deg); margin: 0.1rem 0; }
}

/* ---------- Order-tracking storyboard — all 5 in one row ---------- */
.zp-track-strip {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 0.8rem;
  margin-top: 1.75rem;
  align-items: start;
}
.zp-track-strip .zp-phone-wrap {
  display: flex; flex-direction: column; align-items: center; min-width: 0;
}
.zp-track-strip .zp-phone-step {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.3rem; height: 1.3rem; margin-bottom: 0.55rem;
  border-radius: 50%; background: var(--zp); color: #fff;
  font-size: 0.7rem; font-weight: 700;
}


.zp-track-strip .zp-phone-label {
  margin-top: 0.85rem; font-size: 0.78rem; max-width: 22ch;
}

@media (max-width: 720px) {
  .zp-track-strip { grid-template-columns: repeat(3, 1fr); gap: 1rem 0.8rem; }
}
@media (max-width: 440px) {
  .zp-track-strip { grid-template-columns: repeat(2, 1fr); }
}

/* Sub-heading inside a section (e.g. "What I learned") */
.zp-subhead {
  margin: 1.75rem 0 0;
  font-size: 1.05rem;
  font-weight: 700;
}

/* =========================================================
   ZAPP — Principal case study layer (zpx-*)
   Sits on top of case.css + the zp-* components above.
   ========================================================= */

/* ---------- Section rhythm ---------- */
.zpx-sec { padding: 4.5rem 0 0; }
.zpx-sec:first-of-type { padding-top: 2rem; }

.zpx-eyebrow {
  display: flex; align-items: center; gap: 0.7rem;
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--zp);
  margin: 0 0 1.1rem;
}
.zpx-eyebrow::after {
  content: ""; flex: 1; height: 1px;
  background: rgba(255, 255, 255, 0.12);
}
[data-theme="light"] .zpx-eyebrow::after { background: rgba(0, 0, 0, 0.12); }

.zpx-h2 {
  font-size: clamp(1.6rem, 3.4vw, 2.5rem);
  font-weight: 700; line-height: 1.15; letter-spacing: -0.02em;
  margin: 0 0 1rem; max-width: 24ch;
}
.zpx-sub {
  display: block; font-size: 1.02rem; font-weight: 400;
  color: rgba(255, 255, 255, 0.6); margin-top: 0.5rem; letter-spacing: 0;
}
[data-theme="light"] .zpx-sub { color: rgba(0, 0, 0, 0.55); }

.zpx-lead {
  display: block; max-width: 62ch;
  font-size: 1.06rem; line-height: 1.72;
  color: rgba(255, 255, 255, 0.78); margin: 0 0 1rem;
}
[data-theme="light"] .zpx-lead { color: rgba(0, 0, 0, 0.72); }
.zpx-lead + .zpx-lead { margin-top: 0.9rem; }

/* Pull-quote / thesis line */
.zpx-thesis {
  display: block;
  font-family: 'Playfair Display', serif;
  font-size: clamp(1.35rem, 2.8vw, 2rem);
  font-style: italic; line-height: 1.35;
  max-width: 26ch; margin: 2.6rem 0;
  padding-top: 1.5rem;
  border-top: 1px solid rgba(255, 255, 255, 0.16);
}

/* ---------- Hero ---------- */
.zpx-hero { padding: 1rem 0 0; }
.zpx-hero h1 {
  font-size: clamp(3rem, 9vw, 6rem);
  font-weight: 800; letter-spacing: -0.045em; line-height: 0.95;
  margin: 0 0 1.1rem;
}
.zpx-hero-claim {
  display: block;
  font-size: clamp(1.15rem, 2.6vw, 1.75rem);
  font-weight: 500; line-height: 1.35; letter-spacing: -0.01em;
  max-width: 30ch; margin: 0 0 1.9rem;
}
.zpx-meta {
  display: flex; flex-wrap: wrap; gap: 0.45rem;
  margin: 0 0 1.6rem; padding: 0; list-style: none;
}
.zpx-meta li {
  font-size: 0.78rem; font-weight: 600; letter-spacing: 0.02em;
  padding: 0.36rem 0.8rem; border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  color: rgba(255, 255, 255, 0.75);
}
.zpx-meta li.is-key { background: var(--zp); border-color: var(--zp); color: #fff; }
[data-theme="light"] .zpx-meta li { border-color: rgba(0, 0, 0, 0.14); color: rgba(0, 0, 0, 0.7); }
[data-theme="light"] .zpx-meta li.is-key { color: #fff; }

/* ---------- Figures & media ---------- */
.zpx-fig { margin: 1.75rem 0 0; }
.zpx-frame {
  display: block; border-radius: 16px; overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(255, 255, 255, 0.02);
  box-shadow: 0 24px 60px -34px rgba(0, 0, 0, 0.6);
}
.zpx-frame img { width: 100%; display: block; cursor: zoom-in; }
[data-theme="light"] .zpx-frame { border-color: rgba(0, 0, 0, 0.09); }
.zpx-cap {
  margin: 0.8rem 0 0; font-size: 0.82rem; line-height: 1.5;
  color: rgba(255, 255, 255, 0.5);
}
[data-theme="light"] .zpx-cap { color: rgba(0, 0, 0, 0.5); }

.zpx-grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1rem; margin-top: 1.75rem; }
.zpx-grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; margin-top: 1.75rem; }
.zpx-grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; margin-top: 1.75rem; }
.zpx-grid-2 .zpx-fig, .zpx-grid-3 .zpx-fig, .zpx-grid-4 .zpx-fig { margin-top: 0; }
@media (max-width: 860px) { .zpx-grid-3, .zpx-grid-4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .zpx-grid-2, .zpx-grid-3, .zpx-grid-4 { grid-template-columns: 1fr; } }

/* ---------- Annotated craft rail (image + numbered notes) ---------- */
.zpx-annot { display: grid; grid-template-columns: 1.35fr 1fr; gap: 1.6rem; align-items: start; margin-top: 1.75rem; }
.zpx-annot--flip { grid-template-columns: 1fr 1.35fr; }
.zpx-annot--flip .zpx-annot-media { order: 2; }
.zpx-notes { counter-reset: note; list-style: none; margin: 0; padding: 0; }
.zpx-notes li {
  counter-increment: note; position: relative;
  padding: 0 0 0 2.4rem; margin-bottom: 1.15rem;
  font-size: 0.9rem; line-height: 1.55;
  color: rgba(255, 255, 255, 0.66);
}
.zpx-notes li::before {
  content: counter(note, decimal-leading-zero);
  position: absolute; left: 0; top: 0.05em;
  font-size: 0.7rem; font-weight: 700; letter-spacing: 0.04em;
  color: var(--zp);
}
.zpx-notes b { display: block; color: #fff; font-size: 0.94rem; margin-bottom: 0.15rem; }
[data-theme="light"] .zpx-notes li { color: rgba(0, 0, 0, 0.66); }
[data-theme="light"] .zpx-notes b { color: #111; }
@media (max-width: 820px) {
  .zpx-annot, .zpx-annot--flip { grid-template-columns: 1fr; }
  .zpx-annot--flip .zpx-annot-media { order: 0; }
}

/* Label chips under a visual */
.zpx-chips { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0.9rem 0 0; padding: 0; list-style: none; }
.zpx-chips li {
  font-size: 0.7rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  padding: 0.3rem 0.65rem; border-radius: 999px;
  color: var(--zp);
  background: color-mix(in srgb, var(--zp) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--zp) 28%, transparent);
}

/* ---------- Numbered principle cards ---------- */
.zpx-principles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; margin-top: 1.9rem; }
.zpx-principle {
  border: 1px solid var(--zpx-card-line);
  border-radius: var(--zpx-card-radius); padding: 1.4rem 1.3rem;
  background: var(--zpx-card-bg);
}
.zpx-principle span {
  display: block; font-size: 0.72rem; font-weight: 700;
  letter-spacing: 0.1em; color: var(--zp); margin-bottom: 0.7rem;
}
.zpx-principle h4 { margin: 0 0 0.4rem; font-size: 1rem; font-weight: 700; line-height: 1.3; }
.zpx-principle p { margin: 0; font-size: 0.88rem; line-height: 1.55; color: rgba(255, 255, 255, 0.62); }
[data-theme="light"] .zpx-principle p { color: rgba(0, 0, 0, 0.62); }
@media (max-width: 780px) { .zpx-principles { grid-template-columns: 1fr; } }

/* ---------- Craft pillars (4 blocks) ---------- */
.zpx-pillars { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; margin-top: 1.9rem; }
.zpx-pillar {
  border-top: 2px solid var(--zp); padding: 1.1rem 0 0;
}
.zpx-pillar span { display: block; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.1em; color: var(--zp); margin-bottom: 0.5rem; }
.zpx-pillar h4 { margin: 0 0 0.7rem; font-size: 1rem; font-weight: 700; }
.zpx-pillar ul { list-style: none; margin: 0; padding: 0; }
.zpx-pillar li {
  font-size: 0.86rem; line-height: 1.5; padding: 0.32rem 0;
  color: rgba(255, 255, 255, 0.62);
  border-bottom: 1px solid rgba(255, 255, 255, 0.07);
}
[data-theme="light"] .zpx-pillar li { color: rgba(0, 0, 0, 0.62); border-bottom-color: rgba(0, 0, 0, 0.07); }
@media (max-width: 900px) { .zpx-pillars { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) { .zpx-pillars { grid-template-columns: 1fr; } }

/* ---------- Zync — dominant dark block ---------- */
.zpx-zync {
  margin: 4.5rem -2rem 0;
  padding: 4rem 2rem 4.25rem;
  background: var(--zp-deep);
  color: #fff;
  border-radius: 22px;
}
.zpx-zync .zpx-eyebrow { color: #7fc4d8; }
.zpx-zync .zpx-eyebrow::after { background: rgba(255, 255, 255, 0.18); }
.zpx-zync .zpx-lead { color: rgba(255, 255, 255, 0.75); }
.zpx-zync .zpx-sub { color: rgba(255, 255, 255, 0.6); }
.zpx-zync .zpx-cap { color: rgba(255, 255, 255, 0.5); }
.zpx-zync .zpx-frame { border-color: rgba(255, 255, 255, 0.14); background: rgba(255, 255, 255, 0.04); }
.zpx-zync .zpx-thesis { border-top-color: rgba(255, 255, 255, 0.22); }
.zpx-zync .zpx-notes li { color: rgba(255, 255, 255, 0.7); }
.zpx-zync .zpx-notes li::before { color: #7fc4d8; }
.zpx-zync .zpx-notes b { color: #fff; }
.zpx-zync .zpx-principle span { color: #7fc4d8; }
.zpx-zync .zpx-principle p { color: rgba(255, 255, 255, 0.68); }
.zpx-zync .zpx-chips li { color: #9ad4e5; background: rgba(127, 196, 216, 0.14); border-color: rgba(127, 196, 216, 0.32); }
.zpx-zync .zpx-subhead { color: #fff; }
@media (max-width: 720px) { .zpx-zync { margin-left: -1rem; margin-right: -1rem; padding: 3rem 1.25rem; border-radius: 16px; } }

.zpx-subhead {
  margin: 2.75rem 0 0.4rem;
  font-size: 1.15rem; font-weight: 700; letter-spacing: -0.01em;
}

/* Colour token scale */
.zpx-tokens { display: grid; grid-template-columns: repeat(11, 1fr); gap: 3px; margin-top: 1.4rem; border-radius: 10px; overflow: hidden; }
.zpx-token { padding: 1.5rem 0.4rem 0.5rem; text-align: center; }
.zpx-token b { display: block; font-size: 0.7rem; font-weight: 700; }
.zpx-token small { display: block; font-size: 0.55rem; letter-spacing: 0.04em; opacity: 0.75; margin-top: 0.1rem; }
@media (max-width: 700px) { .zpx-tokens { grid-template-columns: repeat(6, 1fr); } }

/* ---------- Pipeline (design → code) ---------- */
.zpx-pipe {
  display: flex; align-items: stretch; flex-wrap: wrap; gap: 0.55rem;
  margin-top: 1.9rem;
}
.zpx-pipe-step {
  flex: 1 1 130px;
  display: flex; flex-direction: column; align-items: center; gap: 0.6rem;
  padding: 1.15rem 0.7rem;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 13px; background: rgba(255, 255, 255, 0.04);
  text-align: center;
}
.zpx-pipe-chip {
  width: 44px; height: 44px; border-radius: 12px; background: #fff;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 16px -5px rgba(0, 0, 0, 0.4);
}
.zpx-pipe-chip img { width: 23px; height: 23px; display: block; }
.zpx-pipe-step b { font-size: 0.88rem; font-weight: 700; }
.zpx-pipe-step small { font-size: 0.74rem; line-height: 1.4; opacity: 0.7; }
.zpx-pipe-arrow { align-self: center; color: #7fc4d8; font-weight: 700; }
[data-theme="light"] .zpx-pipe-step { border-color: rgba(0, 0, 0, 0.12); background: rgba(0, 0, 0, 0.02); }
@media (max-width: 720px) { .zpx-pipe-arrow { display: none; } .zpx-pipe-step { flex-basis: 44%; } }

/* ---------- Synthesis stack ---------- */
/* ---------- Workflow (section 10): five steps across the full width, same
   card box as the Zapp+ stat cards so the two sections read as one family. ---------- */
.zpx-flow {
  list-style: none; margin: 2rem 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(5, 1fr); gap: 1.1rem;
}
.zpx-flow-step {
  position: relative; margin: 0; padding: 1.4rem 1.3rem 1.5rem;
  border-radius: var(--zpx-card-radius);
  background: var(--zpx-card-bg);
  border: 1px solid var(--zpx-card-line);
  transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.25s ease;
}
.zpx-flow-step:hover { transform: translateY(-3px); border-color: color-mix(in srgb, var(--zp) 45%, transparent); }
.zpx-flow-num {
  display: block; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.12em;
  color: var(--zp); margin-bottom: 0.9rem; font-variant-numeric: tabular-nums;
}
.zpx-flow-step b {
  display: block; font-size: 1.05rem; font-weight: 700; letter-spacing: -0.01em;
  line-height: 1.25; margin-bottom: 0.5rem; color: var(--zpx-stat-fg, #fff);
}
.zpx-flow-step > span:last-child { display: block; font-size: 0.9rem; line-height: 1.55; color: var(--zpx-stat-muted, rgba(255, 255, 255, 0.66)); }

[data-theme="light"] .zpx-flow-step { --zpx-stat-fg: #1a1c22; --zpx-stat-muted: rgba(0, 0, 0, 0.55); }

@media (max-width: 1000px) { .zpx-flow { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 620px)  { .zpx-flow { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) { .zpx-flow-step { transition: none; } .zpx-flow-step:hover { transform: none; } }

/* ---------- Expandable detail (research methodology) ---------- */
.zpx-more {
  margin-top: 1.75rem;
  border: 1px solid var(--zpx-card-line);
  border-radius: var(--zpx-card-radius); background: var(--zpx-card-bg);
}
.zpx-more > summary {
  cursor: pointer; list-style: none;
  padding: 0.95rem 1.2rem;
  font-size: 0.88rem; font-weight: 600;
  display: flex; align-items: center; gap: 0.55rem;
}
.zpx-more > summary::-webkit-details-marker { display: none; }
.zpx-more > summary::after {
  content: "+"; margin-left: auto; font-size: 1.05rem; color: var(--zp); font-weight: 700;
}
.zpx-more[open] > summary::after { content: "–"; }
.zpx-more-body { padding: 0 1.2rem 1.25rem; }
.zpx-more-body p, .zpx-more-body li { font-size: 0.88rem; line-height: 1.6; color: rgba(255, 255, 255, 0.65); }
.zpx-more-body ul { margin: 0.5rem 0 0; padding-left: 1.1rem; }
.zpx-more-body li { margin-bottom: 0.4rem; }
[data-theme="light"] .zpx-more-body p, [data-theme="light"] .zpx-more-body li { color: rgba(0, 0, 0, 0.65); }

/* ---------- Closing takeaway ---------- */
.zpx-takeaway { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; margin-top: 2rem; }
.zpx-take {
  padding: 1.5rem 1.35rem; border-radius: 14px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(255, 255, 255, 0.02);
}
.zpx-take b {
  display: block; font-size: 0.74rem; font-weight: 700;
  letter-spacing: 0.14em; color: var(--zp); margin-bottom: 0.55rem;
}
.zpx-take p { margin: 0; font-size: 0.92rem; line-height: 1.55; color: rgba(255, 255, 255, 0.7); }
[data-theme="light"] .zpx-take { border-color: rgba(0, 0, 0, 0.1); background: rgba(0, 0, 0, 0.02); }
[data-theme="light"] .zpx-take p { color: rgba(0, 0, 0, 0.7); }
@media (max-width: 780px) { .zpx-takeaway { grid-template-columns: 1fr; } }

/* ---------- Additional work (compact) ---------- */
.zpx-compact .zpx-frame { border-radius: 12px; }
.zpx-compact .zpx-cap { font-size: 0.76rem; }

/* Live-link button */
.zpx-livelink {
  display: inline-flex; align-items: center; gap: 0.5rem;
  margin-top: 1.4rem; padding: 0.7rem 1.2rem;
  border-radius: 999px; font-size: 0.9rem; font-weight: 600;
  text-decoration: none; color: #fff; background: var(--zp);
  transition: opacity 0.2s, transform 0.2s;
}
.zpx-livelink:hover { opacity: 0.9; transform: translateY(-1px); }
.zpx-livelink svg { width: 15px; height: 15px; }

/* Uniform crops inside multi-column grids — keeps rows optically aligned.
   Cropping from the top preserves the part of a UI that carries the hierarchy. */
.zpx-grid-2 .zpx-frame img,
.zpx-grid-3 .zpx-frame img,
.zpx-grid-4 .zpx-frame img {
  aspect-ratio: 4 / 3;
  object-fit: cover;
  object-position: top center;
}
.zpx-grid-4 .zpx-frame img { aspect-ratio: 3 / 2; }

/* Tall mobile capture — show the top of the page rather than the whole scroll. */
.zpx-mobile-shot img {
  max-height: 620px;
  object-fit: cover;
  object-position: top center;
}

/* ---------- Preview tiles (labelled, tagged) ---------- */
.zpx-previews {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.1rem;
  margin-top: 2rem;
}
.zpx-preview { display: flex; flex-direction: column; min-width: 0; }

.zpx-preview-media {
  position: relative;
  display: block;
  border-radius: 14px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(255, 255, 255, 0.03);
  box-shadow: 0 26px 55px -32px rgba(0, 0, 0, 0.75);
  transition: transform 0.25s ease, border-color 0.25s ease;
}
.zpx-preview-media:hover { transform: translateY(-3px); border-color: color-mix(in srgb, var(--zp) 55%, transparent); }
.zpx-preview-media img {
  width: 100%;
  display: block;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  object-position: top center;
  cursor: zoom-in;
}
[data-theme="light"] .zpx-preview-media {
  border-color: rgba(0, 0, 0, 0.1);
  box-shadow: 0 24px 50px -34px rgba(0, 0, 0, 0.45);
}

/* Pinned tag, top-left of the tile */
.zpx-tag {
  position: absolute;
  top: 0.7rem; left: 0.7rem; z-index: 2;
  display: inline-flex; align-items: center; gap: 0.35rem;
  padding: 0.28rem 0.6rem;
  border-radius: 6px;
  font-size: 0.63rem; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: #fff; background: var(--zp-deep);
  border: 1px solid rgba(255, 255, 255, 0.22);
  box-shadow: 0 4px 14px -4px rgba(0, 0, 0, 0.6);
}
.zpx-tag i {
  width: 5px; height: 5px; border-radius: 50%;
  background: #7fc4d8; display: inline-block;
}

.zpx-preview-body { padding: 0.9rem 0.1rem 0; }
.zpx-preview-body h4 {
  margin: 0 0 0.3rem;
  font-size: 0.98rem; font-weight: 700; letter-spacing: -0.01em;
}
.zpx-preview-body p {
  margin: 0;
  font-size: 0.85rem; line-height: 1.5;
  color: rgba(255, 255, 255, 0.58);
}
[data-theme="light"] .zpx-preview-body p { color: rgba(0, 0, 0, 0.58); }

@media (max-width: 900px) { .zpx-previews { grid-template-columns: 1fr 1fr; } }
@media (max-width: 600px) { .zpx-previews { grid-template-columns: 1fr; } }

/* Wide artwork (e.g. a system cover) — show it whole, letterboxed on brand navy. */
.zpx-preview-media--contain { background: var(--zp-deep); }
.zpx-preview-media--contain img { object-fit: contain; object-position: center; }

/* ---------- Real Zapp wordmark in the hero ---------- */
.zpx-hero-logo { margin: 0 0 1.4rem; line-height: 0; }
.zpx-logo { width: clamp(150px, 22vw, 240px); height: auto; display: none; }
.zpx-logo--dark { display: block; }                      /* dark theme (default) */
[data-theme="light"] .zpx-logo--dark { display: none; }
[data-theme="light"] .zpx-logo--light { display: block; }

/* ---------- Device-framed screenshot inside an annotation rail ---------- */

/* Section rhythm is owned by .zpx-sec padding — drop the inherited
   `section { margin-bottom: 4rem }` from case.css so gaps don't stack. */
main.case-study-content > .zpx-hero,
main.case-study-content > .zpx-sec,
main.case-study-content > .zpx-zync { margin-bottom: 0; }
main.case-study-content > .zpx-hero { padding-bottom: 0; }


/* Breathing room between storyboard frames */
.zp-track-strip { gap: 1.5rem 1.35rem; }
@media (max-width: 720px) { .zp-track-strip { gap: 1.6rem 1.1rem; } }

/* =========================================================
   MOTION
   Thesis: two authored moments, not an entrance on every section.
   1. The order-tracking storyboard arrives as the journey it depicts.
   2. The design-to-code pipeline connects one step at a time.
   Everything else is feedback: acknowledge, don't perform.
   Content is visible by default; motion only engages once JS adds
   `.js-motion`, so a failed script can never hide the page.
   ========================================================= */

/* The inherited site-wide entrance ran an identical 0.8s curtain on every
   section here. Neutralise it — this page authors its own motion. */
.case-study-content .fade-in { opacity: 1; transform: none; animation: none; }

/* ---------- Quiet section reveal ---------- */
.js-motion [data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity 0.55s cubic-bezier(0.16, 1, 0.3, 1),
    transform 0.55s cubic-bezier(0.16, 1, 0.3, 1);
}
.js-motion [data-reveal].is-in { opacity: 1; transform: none; }

/* ---------- Focal 1 — the delivery storyboard ---------- */
.js-motion .zp-track-strip .zp-phone-wrap {
  opacity: 0;
  transform: translateY(26px) scale(0.965);
  filter: blur(6px);
}
.js-motion .zp-track-strip.is-in .zp-phone-wrap {
  opacity: 1;
  transform: none;
  filter: blur(0);
  transition:
    opacity 0.5s cubic-bezier(0.16, 1, 0.3, 1),
    transform 0.62s cubic-bezier(0.16, 1, 0.3, 1),
    filter 0.5s cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: calc(var(--i, 0) * 85ms);
}
/* The step badge lands after its frame — the journey ticking forward. */
.js-motion .zp-track-strip .zp-phone-step { opacity: 0; transform: scale(0.6); }
.js-motion .zp-track-strip.is-in .zp-phone-step {
  opacity: 1; transform: none;
  transition: opacity 0.3s ease-out, transform 0.42s cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: calc(var(--i, 0) * 85ms + 220ms);
}

/* ---------- Focal 2 — the pipeline connecting ---------- */
.js-motion .zpx-pipe .zpx-pipe-step { opacity: 0; transform: translateY(16px); }
.js-motion .zpx-pipe.is-in .zpx-pipe-step {
  opacity: 1; transform: none;
  transition: opacity 0.45s ease-out, transform 0.55s cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: calc(var(--i, 0) * 110ms);
}
.js-motion .zpx-pipe .zpx-pipe-arrow {
  opacity: 0; transform: translateX(-6px);
}
.js-motion .zpx-pipe.is-in .zpx-pipe-arrow {
  opacity: 1; transform: none;
  transition: opacity 0.3s ease-out, transform 0.4s cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: calc(var(--i, 0) * 110ms + 60ms);
}

/* ---------- Supporting: annotation notes read in order ---------- */
.js-motion .zpx-notes li { opacity: 0; transform: translateY(10px); }
.js-motion .zpx-notes.is-in li {
  opacity: 1; transform: none;
  transition: opacity 0.4s ease-out, transform 0.48s cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: calc(var(--i, 0) * 70ms);
}

/* ---------- Feedback states ---------- */
.zpx-preview-media img { transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1); }
.zpx-preview-media:hover img { transform: scale(1.035); }
.zpx-preview-media .zpx-tag { transition: transform 0.28s cubic-bezier(0.16, 1, 0.3, 1); }
.zpx-preview-media:hover .zpx-tag { transform: translateY(-2px); }

.zpx-frame { transition: border-color 0.25s ease, transform 0.35s cubic-bezier(0.16, 1, 0.3, 1); }
.zpx-frame:hover { border-color: color-mix(in srgb, var(--zp) 50%, transparent); transform: translateY(-2px); }

.zpx-principle, .zpx-take {
  transition: border-color 0.25s ease, background-color 0.25s ease, transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}
.zpx-principle:hover, .zpx-take:hover {
  border-color: color-mix(in srgb, var(--zp) 45%, transparent);
  transform: translateY(-2px);
}

/* The colour scale reads as a scale on hover: the step you point at steps up. */
.zpx-token { transition: transform 0.28s cubic-bezier(0.16, 1, 0.3, 1); }
.zpx-tokens:hover .zpx-token { opacity: 0.55; transition: opacity 0.25s ease, transform 0.28s cubic-bezier(0.16,1,0.3,1); }
.zpx-tokens .zpx-token:hover { opacity: 1; transform: translateY(-6px); }

.zpx-chips li { transition: border-color 0.22s ease, background-color 0.22s ease; }

.zpx-livelink svg { transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1); }
.zpx-livelink:hover svg { transform: translate(2px, -2px); }
.zp-cta svg { transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1); }
.zp-cta:hover svg { transform: translateX(3px); }

/* Disclosure: the panel grows rather than snapping open. */
.zpx-more > summary { transition: background-color 0.2s ease; }
.zpx-more > summary:hover { background-color: color-mix(in srgb, var(--zp) 8%, transparent); }
.zpx-more > summary::after { transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1); }
.zpx-more[open] > summary::after { transform: rotate(180deg); }

/* ---------- Browser surfaces, themed from the palette ---------- */
.case-study-content ::selection { background: color-mix(in srgb, var(--zp) 30%, transparent); color: inherit; }
.zpx-zync ::selection { background: rgba(127, 196, 216, 0.35); }
.case-study-content { caret-color: var(--zp); }
.case-study-content a:focus-visible,
.case-study-content button:focus-visible,
.case-study-content summary:focus-visible {
  outline: 2px solid var(--zp);
  outline-offset: 3px;
  border-radius: 4px;
}
.zpx-zync a:focus-visible, .zpx-zync summary:focus-visible { outline-color: #7fc4d8; }

/* ---------- Reduced motion: keep meaning, drop travel ---------- */
@media (prefers-reduced-motion: reduce) {
  .js-motion [data-reveal],
  .js-motion .zp-track-strip .zp-phone-wrap,
  .js-motion .zp-track-strip .zp-phone-step,
  .js-motion .zpx-pipe .zpx-pipe-step,
  .js-motion .zpx-pipe .zpx-pipe-arrow,
  .js-motion .zpx-notes li {
    transform: none !important;
    filter: none !important;
    opacity: 0;
  }
  .js-motion [data-reveal].is-in,
  .js-motion .zp-track-strip.is-in .zp-phone-wrap,
  .js-motion .zp-track-strip.is-in .zp-phone-step,
  .js-motion .zpx-pipe.is-in .zpx-pipe-step,
  .js-motion .zpx-pipe.is-in .zpx-pipe-arrow,
  .js-motion .zpx-notes.is-in li {
    opacity: 1;
    transition: opacity 0.25s ease-out;
    transition-delay: 0ms;
  }
  .zpx-preview-media:hover img,
  .zpx-frame:hover,
  .zpx-principle:hover, .zpx-take:hover,
  .zpx-tokens .zpx-token:hover,
  .zpx-livelink:hover svg, .zp-cta:hover svg,
  .zpx-preview-media:hover .zpx-tag { transform: none; }
}

/* Body copy runs the full column width on this page, by request — the case
   study is walked through on a wide screen, not read like an article. */
.zpx-lead,
.zpx-hero-claim,
.zpx-h2,
.zpx-closing,
.zp-confidential { max-width: none; }
.zpx-notes li, .zpx-preview-body p { max-width: none; }

[data-theme="light"] .zpx-thesis { border-top-color: rgba(0, 0, 0, 0.16); }
[data-theme="light"] .zp-confidential { border-color: rgba(0, 0, 0, 0.12); }

/* Pull-quote runs full width, so its hairline divider spans the column too. */
.zpx-thesis { max-width: none; }

/* On narrow screens the annotated device sat at full column width, dwarfing the
   storyboard frames. Hold it to the same visual scale. */
@media (max-width: 720px) {
  }

/* =========================================================
   iPhone frame — one definition, used everywhere.
   Every dimension is a percentage of the frame's own width, so a 140px
   storyboard frame and a 290px annotated frame are the same device at
   two sizes. Proportions follow a real iPhone: titanium rail, ~3.4%
   bezel, 14%/6.4% corner radius, and a Dynamic Island sized and placed
   against the screen (125×36pt at 393pt wide), not against the shell.
   ========================================================= */
.iphone-case {
  position: relative;
  width: 100%;
  padding: 1.7%;
  border-radius: 13% / 6%;
  /* Brushed titanium rail: light catches the top-left and bottom-right. */
  background:
    linear-gradient(148deg,
      #8a8d94 0%, #4a4d53 6%, #17181b 16%,
      #0b0c0e 50%,
      #17181b 84%, #4a4d53 94%, #8a8d94 100%);
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.6),
    0 26px 52px -22px rgba(0, 0, 0, 0.6),
    0 4px 14px -6px rgba(0, 0, 0, 0.4);
}
[data-theme="light"] .iphone-case {
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.28),
    0 26px 52px -24px rgba(0, 0, 0, 0.38),
    0 4px 14px -8px rgba(0, 0, 0, 0.25);
}

/* The link is the screen: it clips the capture and hosts the island. */
.iphone-case > a {
  display: block;
  position: relative;
  overflow: hidden;
  margin: 0;
  border: 0;
  background: #000;
  border-radius: 11.6% / 5.35%;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.85) inset;
  line-height: 0;
}
.iphone-case > a > img {
  display: block;
  width: 100%;
  border-radius: inherit;
  cursor: zoom-in;
}

/* Dynamic Island, proportioned and positioned against the screen. */
.iphone-case > a::after {
  content: "";
  position: absolute;
  z-index: 3;
  top: 1.3%;
  left: 50%;
  transform: translateX(-50%);
  width: 30%;
  aspect-ratio: 125 / 36;
  background: #000;
  border-radius: 999px;
  box-shadow: 0 0 0 0.5px rgba(255, 255, 255, 0.06);
}

/* Side hardware — volume rocker left, power right. */
.iphone-case::before,
.iphone-case::after {
  content: "";
  position: absolute;
  width: 1.1%;
  z-index: -1;
}
.iphone-case::before {           /* volume + action button */
  left: -0.8%;
  top: 19%;
  height: 15%;
  background: linear-gradient(270deg, #101114 0%, #6b6e75 60%, #3c3e43 100%);
  border-radius: 2px 0 0 2px;
}
.iphone-case::after {            /* power */
  right: -0.8%;
  top: 27%;
  height: 11%;
  background: linear-gradient(90deg, #101114 0%, #6b6e75 60%, #3c3e43 100%);
  border-radius: 0 2px 2px 0;
}

/* Sizing per context — the frame itself never changes, only its width.
   The bezel, island and side buttons are all percentages, and percentages
   resolve against the CONTAINING BLOCK, not the frame. In the strip the
   frame fills its column, so that is fine; in the annotated figure the
   frame used to sit in a ~650px column capped at 260px, so its bezel came
   out three times thicker than the others. A grid track the exact width
   of the frame makes the frame its own containing block. */
.zpx-device {
  display: grid;
  grid-template-columns: min(260px, 100%);
  justify-content: center;
  justify-items: center;
}
.zpx-device .iphone-case { width: 100%; max-width: none; }
.zpx-device .zpx-cap { text-align: center; max-width: 32ch; }
@media (max-width: 720px) {
  .zpx-device { grid-template-columns: min(200px, 100%); }
}

/* =========================================================
   Zapp+ in numbers — three stat cards: label top-left, brand
   top-right, one large figure anchored bottom-left.
   ========================================================= */
.zpx-outcomes { margin-top: 2.6rem; }
.zpx-stat-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.1rem; margin-top: 1.5rem;
}
.zpx-stat {
  display: flex; flex-direction: column; justify-content: space-between;
  min-height: 250px; padding: 1.5rem 1.6rem 1.35rem;
  border-radius: var(--zpx-card-radius);
  /* Brand navy in both themes: these are the product's own numbers. */
  background: #002533;
  border: 1px solid rgba(255, 255, 255, 0.12);
  --zpx-stat-fg: #fff;
  --zpx-stat-muted: rgba(255, 255, 255, 0.72);
  transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.25s ease;
}
.zpx-stat:hover { transform: translateY(-3px); border-color: rgba(255, 255, 255, 0.38); }
.zpx-stat-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; }
.zpx-stat-label { font-size: 0.9rem; line-height: 1.4; color: var(--zpx-stat-muted, rgba(255, 255, 255, 0.62)); }
/* The real Zapp+ wordmark, used as a mask over currentColor so one asset
   reads dark on the light cards and white on the dark ones. */
.zpx-stat-brand {
  flex: none; display: block; width: 72px; aspect-ratio: 640 / 125;
  margin-top: 0.15rem;
  background: var(--zpx-stat-fg, #fff);
  -webkit-mask: url("../images/zapp-plus-mark.png") center / contain no-repeat;
          mask: url("../images/zapp-plus-mark.png") center / contain no-repeat;
}
.zpx-stat-figure {
  display: block; font-size: clamp(3.4rem, 6vw, 5.2rem); font-weight: 600;
  letter-spacing: -0.045em; line-height: 0.95; color: var(--zpx-stat-fg, #fff);
  font-variant-numeric: tabular-nums;
}
.zpx-stat-figure small { font-size: 0.42em; font-weight: 600; letter-spacing: -0.01em; margin-left: 0.06em; vertical-align: 0.42em; }
.zpx-outcomes > .zpx-cap { margin-top: 1rem; }


@media (max-width: 900px) { .zpx-stat-grid { grid-template-columns: 1fr; } .zpx-stat { min-height: 200px; } }
@media (prefers-reduced-motion: reduce) { .zpx-stat { transition: none; } .zpx-stat:hover { transform: none; } }




/* Hypothesis -> metric list under the Zapp+ stat cards (zapp-case.html) */
.zpx-hyp { list-style: none; margin: 1.4rem 0 0; padding: 0; display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.1rem; }
.zpx-hyp li { display: flex; flex-direction: column; gap: 0.3rem; padding: 0 0.2rem; }
.zpx-hyp b { font-size: 0.72rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--zp); }
.zpx-hyp span { font-size: 1rem; font-weight: 700; letter-spacing: -0.01em; }
.zpx-hyp em { font-style: normal; font-size: 0.9rem; line-height: 1.55; color: rgba(255, 255, 255, 0.66); }
[data-theme="light"] .zpx-hyp em { color: rgba(0, 0, 0, 0.62); }
@media (max-width: 900px) { .zpx-hyp { grid-template-columns: 1fr; } }
