/* ==========================================================================
   Components — buttons, hero, work list, prose, values, timeline, cards
   ========================================================================== */

/* -------------------------------- Buttons -------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: var(--fw-medium);
  line-height: 1;
  padding: 10px 18px;
  border-radius: var(--radius-media);
  border: var(--border-width) solid transparent;
  cursor: pointer;
  transition: opacity var(--transition-fast), transform var(--transition-fast);
}
/* On hover, just dim the button by 20% (no colour change). */
.btn:hover { text-decoration: none; opacity: 0.8; }
.btn:active { transform: translateY(1px); }

.btn--primary { background: var(--color-text); color: var(--color-text-invert); }

.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: var(--fw-medium);
  color: var(--color-text);
}
.link-arrow::after { content: "→"; transition: transform var(--transition-fast); }
.link-arrow:hover { text-decoration: none; }
.link-arrow:hover::after { transform: translateX(4px); }

/* --------------------------------- Hero ---------------------------------- */
/* Equal breathing room above the title and below the subtitle (120px on
   desktop, scaling down on small screens). */
.hero { padding-block: clamp(var(--space-9), 12vw, 120px); }
/* The section right after the hero shouldn't add its own top padding, or the
   space below the subtitle would exceed the space above the title. */
.hero + .section--tight { padding-top: 0; }
.hero__title {
  font-size: var(--fs-page-title);
  letter-spacing: var(--tracking-tight);
  max-width: 22ch;
}
.hero__lede {
  font-size: var(--fs-body-lg);
  color: var(--color-text-muted);
  max-width: 48ch;
  margin-top: var(--space-4);
  line-height: var(--lh-relaxed);
}

/* ----------------------- Work list (editorial rows) ---------------------- */
.work-list { display: grid; }

.work-item {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "index index"
    "title meta"
    "desc  meta"
    "tags  meta";
  /* "Read case study" shares the title's grid row, so it baseline-aligns to it. */
  align-items: baseline;
  column-gap: clamp(var(--space-4), 3vw, var(--space-6));
  /* 16px inset so the hover highlight keeps breathing room around the
     content (including after the link); straight corners, no gutter bleed */
  padding: var(--space-4);
  border-radius: var(--radius-xs);
  transition: background var(--transition-fast);
}
.work-item:hover { background: color-mix(in srgb, var(--color-bg-subtle) 85%, transparent); }

/* Hairline divider between rows, inset to the content width */
.work-item + .work-item::before {
  content: "";
  position: absolute;
  top: 0;
  /* Span the full row width so the divider matches the hover highlight and
     sits a little past the text on each side. */
  left: 0;
  right: 0;
  border-top: var(--border-width) solid var(--color-border);
}
.work-item:hover::before,
.work-item:hover + .work-item::before { border-color: transparent; }

.work-item__index {
  grid-area: index;
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  letter-spacing: 0.06em;
  color: var(--color-text-subtle);
  margin-bottom: var(--space-2);
}
.work-item__title { grid-area: title; min-width: 0; font-size: var(--fs-h4); }
.work-item__desc {
  grid-area: desc;
  min-width: 0;
  color: var(--color-text-muted);
  font-size: var(--fs-small);
  line-height: var(--lh-normal);
  margin-top: 8px;
  max-width: 58ch;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Topic tags — the same set shown on each case-study cover, in a quiet
   outlined-pill style suited to the light list. */
.work-item__tags {
  grid-area: tags;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-3);
}
.work-item__tag {
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  border: var(--border-width) solid var(--color-border);
  font-size: var(--fs-caption);
  color: var(--color-text-muted);
  line-height: 1.5;
}

/* Right meta: "Read case study" baseline-aligns with the title via the row's
   align-items: baseline. */
.work-item__meta {
  grid-area: meta;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
  text-align: right;
  white-space: nowrap;
}
.work-item__readtime {
  font-family: var(--font-mono);
  font-size: var(--fs-caption);
  color: var(--color-text-subtle);
  letter-spacing: 0.02em;
}
.work-item__cta {
  font-size: var(--fs-small);
  font-weight: var(--fw-medium);
  color: var(--color-text-muted);
  transition: color var(--transition-fast);
}
.work-item:hover .work-item__cta { color: var(--color-text); }
.work-item__cta span { display: inline-block; transition: transform var(--transition-fast); }
.work-item:hover .work-item__cta span { transform: translateX(3px); }

@media (max-width: 639px) {
  .work-item { grid-template-columns: 1fr; grid-template-areas: "index" "title" "desc" "tags"; column-gap: var(--space-4); }
  .work-item__meta { display: none; }
}

/* Whole row clickable */
/* Invisible overlay link: absolutely positioned so it covers the row without
   taking a grid column (which previously added a trailing gap on the right). */
.stretched-link { position: absolute; inset: 0; }

/* --------------------------------- Prose --------------------------------- */
.prose { max-width: var(--container-narrow); }
.prose > * + * { margin-top: var(--space-5); }
.prose > :first-child { margin-top: 0; }
.prose h2 {
  font-size: clamp(1.375rem, 1.2rem + 0.6vw, 1.625rem);
  margin-top: var(--space-9);
}
.prose h3 {
  font-size: clamp(1.125rem, 1.02rem + 0.45vw, 1.3125rem);
  margin-top: var(--space-7);
}
.prose h4 { font-size: 1.0625rem; margin-top: var(--space-6); }
/* When prose is split by media (a figure, embed, or flow diagram), the heading
   that begins the next block is a :first-child and loses its top margin —
   restore it so headings keep breathing room after images and prototypes. */
.figure + .prose > h2:first-child,
.figure + .prose > h3:first-child,
.figure + .prose > h4:first-child,
.proto-embed + .prose > h2:first-child,
.proto-embed + .prose > h3:first-child,
.proto-embed + .prose > h4:first-child,
.flow + .prose > h2:first-child,
.flow + .prose > h3:first-child,
.flow + .prose > h4:first-child {
  margin-top: var(--space-8);
}

/* Standalone section headings (outside .prose) — match the prose H2 scale so
   they read as section titles, not page titles. */
.section-heading { font-size: clamp(1.375rem, 1.2rem + 0.6vw, 1.625rem); }
.prose p, .prose li {
  font-size: var(--fs-body);
  line-height: var(--lh-relaxed);
  color: var(--color-text);
}
.prose ul { display: grid; gap: var(--space-4); }
.prose ul li { padding-left: var(--space-5); position: relative; }
.prose ul li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.72em;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--color-text-subtle);
}
.prose .lead {
  font-size: var(--fs-body-lg);
  color: var(--color-text-muted);
}
/* Inline content links: solid pink, underlined for affordance.
   Uses --pink-03 (#CE198E, 5.06:1 on white) so link text meets WCAG AA;
   the brighter --pink-02 is reserved for decorative accents. */
.prose a {
  font-weight: var(--fw-medium);
  color: var(--pink-03);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
.prose a:hover { text-decoration-thickness: 2px; }
/* External-link arrow icon shown inside a link */
.ext-icon { display: inline-block; vertical-align: -0.05em; margin-left: 0.2em; }

/* Status chip */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  padding: 1px 10px;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  font-size: var(--fs-caption);
  font-weight: var(--fw-medium);
  line-height: 1.5;
  white-space: nowrap;
}
/* Light green bg with dark green border + text: green-03 on green-01 ~ 8.9:1 (AAA) */
.chip--live {
  background: var(--green-01);
  border-color: var(--green-03);
  color: var(--green-03);
}
/* Light amber bg with dark amber border + text: amber-03 on amber-01 ~ 6.6:1 (AA) */
.chip--soon {
  background: var(--amber-01);
  border-color: var(--amber-03);
  color: var(--amber-03);
}

/* --------------------------- Page intro header --------------------------- */
/* Equal 120px breathing room above and below (scales down on small screens) */
.page-head { padding-block: clamp(var(--space-9), 12vw, 120px); }
.page-head__eyebrow {
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-text-subtle);
  margin-bottom: var(--space-4);
}
.page-head__title { font-size: var(--fs-page-title); max-width: 20ch; }
.page-head__sub {
  font-size: var(--fs-body-lg);
  color: var(--color-text-muted);
  margin-top: var(--space-4);
  max-width: 50ch;
}

/* ------------------------------- Values grid ----------------------------- */
.values { display: grid; gap: var(--space-6); margin-top: var(--space-7); }
@media (min-width: 640px) { .values { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .values { grid-template-columns: repeat(3, 1fr); } }

.value-card {
  padding: var(--space-6);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-xs);
  background: var(--color-surface);
}
.value-card__name {
  font-size: var(--fs-h4);
  margin-bottom: var(--space-2);
}
.value-card__quote {
  color: var(--color-text-muted);
  font-style: italic;
  margin-bottom: var(--space-3);
}
.value-card__text { color: var(--color-text); }

/* -------------------------------- Timeline ------------------------------- */
.timeline {
  display: flex;
  gap: var(--space-6);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: var(--space-5);
  -webkit-overflow-scrolling: touch;
  /* Bleed the strip to the right edge of the viewport so cards scroll off
     screen instead of being clipped mid-card at the container edge. The first
     card stays aligned under the heading. */
  margin-right: calc(50% - 50vw);
  padding-right: var(--gutter);
}
.timeline__item {
  scroll-snap-align: start;
  /* Match one value-card column so the first cards line up under the values
     grid above — same left rail, same width, same gap = one shared grid. */
  flex: 0 0 clamp(240px, 70vw, calc((var(--container-max) - 2 * var(--gutter) - 2 * var(--space-6)) / 3));
  padding: var(--space-6);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-xs);
  background: var(--color-surface);
}
.timeline__year {
  font-size: var(--fs-h3);
  color: var(--color-text);
  margin-bottom: var(--space-2);
}
.timeline__role { font-weight: var(--fw-semibold); margin-bottom: var(--space-2); }
.timeline__desc { color: var(--color-text-muted); line-height: var(--lh-relaxed); }

/* ----------------------------- Contact / CTA ----------------------------- */
/* Full-bleed dark "Let's talk" CTA band */
.cta-dark {
  background: var(--grey-80);
  color: var(--grey-00);
  padding-block: clamp(var(--space-9), 7vw, var(--space-11));
  margin-top: var(--space-11);
}
.cta-dark__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-8);
}
.cta-dark__lead { max-width: 48ch; }
.cta-dark__title {
  color: var(--grey-00);
  font-size: clamp(1.5rem, 1.25rem + 1vw, 1.875rem);
  margin-bottom: var(--space-3);
}
.cta-dark__text { color: var(--grey-30); font-size: var(--fs-body); line-height: var(--lh-relaxed); }
.cta-dark__link {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--grey-00);
  white-space: nowrap;
}
.cta-dark__link span { display: inline-block; transition: transform var(--transition-fast); }
.cta-dark__link:hover span { transform: translateX(4px); }

@media (max-width: 639px) {
  .cta-dark__inner { flex-direction: column; align-items: flex-start; gap: var(--space-5); }
}

/* ------------------------------- Media figure ---------------------------- */
.figure { margin-block: var(--space-7); max-width: var(--container-narrow); }
.figure img {
  width: 100%;
  display: block;
}
/* Figure images open in a lightbox on click */
.figure img { cursor: zoom-in; }

/* -------------------------------- Lightbox ------------------------------- */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-5);
  background: rgba(20, 20, 22, 0.86);
  cursor: zoom-out;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s ease, visibility 0.2s ease;
}
.lightbox.is-open { opacity: 1; visibility: visible; }
.lightbox__img {
  max-width: min(1200px, 96vw);
  max-height: 92vh;
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: var(--radius-md);
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.45);
}
.lightbox__close {
  position: absolute;
  top: var(--space-4);
  right: var(--space-4);
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  line-height: 1;
  color: #fff;
  background: rgba(255, 255, 255, 0.14);
  border: 0;
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: background var(--transition-fast);
}
.lightbox__close:hover { background: rgba(255, 255, 255, 0.26); }
@media (prefers-reduced-motion: reduce) { .lightbox { transition: none; } }
.figure figcaption {
  margin-top: var(--space-3);
  font-size: var(--fs-small);
  color: var(--color-text-subtle);
  text-align: center;
}

/* Row of phone screenshots (app previews) with mobile-style rounded corners */
.phone-row {
  display: flex;
  gap: var(--space-4);
  margin-block: var(--space-6);
  max-width: var(--container-narrow);
}
.phone-shot {
  flex: 1 1 0;
  min-width: 0;
  width: 100%;
  height: auto;
  display: block;
  border-radius: 20px;
  box-shadow: var(--shadow-sm);
  cursor: zoom-in;
}
@media (max-width: 480px) { .phone-row { gap: var(--space-2); } .phone-shot { border-radius: 12px; } }

/* Two images side by side, 8px corners (e.g. paired screenshots) */
.img-pair {
  display: flex;
  gap: var(--space-4);
  margin-block: var(--space-6);
  max-width: var(--container-narrow);
}
.img-pair img {
  flex: 1 1 0;
  min-width: 0;
  width: 100%;
  height: auto;
  display: block;
  border-radius: var(--radius-xs);
  cursor: zoom-in;
}
@media (max-width: 480px) { .img-pair { gap: var(--space-2); } }

/* ----------------------------- Scroll reveal ----------------------------- */
/* Content fades + rises into view. Enabled only when JS adds .reveal-ready to
   <html> (pre-paint head script) and motion is allowed, so no-JS / reduced-
   motion users always see content. The hidden state is gated with
   :not(.is-revealed) so a revealed element carries no leftover transform
   (card / hover transforms stay intact). */
.reveal-ready :is(
  .prose > *, .figure, .callout, .panel, .stat,
  .value-card, .section-heading,
  .more-work__title, .more-work__grid > a,
  .cta-dark__inner > *, .work-list .work-item
) {
  transition: opacity 0.6s ease, transform 0.6s cubic-bezier(0.22, 0.61, 0.36, 1);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: opacity, transform;
}
.reveal-ready :is(
  .prose > *, .figure, .callout, .panel, .stat,
  .value-card, .section-heading,
  .more-work__title, .more-work__grid > a,
  .cta-dark__inner > *, .work-list .work-item
):not(.is-revealed) {
  opacity: 0;
  transform: translateY(16px);
}
