/* ==========================================================================
   Homepage
   ========================================================================== */

/* ==========================================================================
   1. Intro — fullscreen logo entrance

   PERFORMANCE NOTE
   The first version of this used `filter: blur(90px)` on two 46vmax elements
   and animated them forever, plus blurred the mark on entry and exit. Large
   animated blurs are re-rasterised every frame and were the reason the
   entrance felt heavy.

   Nothing here uses `filter` any more. The softness comes from the radial
   gradients themselves, which cost nothing to move, and every animated
   property is transform or opacity.
   ========================================================================== */
.intro {
  position: fixed;
  inset: 0;
  z-index: var(--z-intro);
  display: grid;
  place-items: center;
  background: var(--bg);
  overflow: hidden;
  transition:
    opacity var(--d-intro) var(--ease-in-out-quart),
    visibility 0s linear var(--d-intro);
}

/* --- Ambient field --- */
.intro__field {
  position: absolute;
  inset: -25%;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--d-slower) var(--ease-out-quart);
}

.intro__field::before,
.intro__field::after {
  content: '';
  position: absolute;
  border-radius: 50%;
  /* These two are the only continuously-animated elements on the page, so
     they are the only ones that earn a compositor layer. */
  will-change: transform;
}

.intro__field::before {
  width: 52vmax;
  height: 52vmax;
  top: 2%;
  left: 4%;
  /* Soft-stopped gradient replaces a blur filter — visually equivalent,
     essentially free to animate. */
  background: radial-gradient(
    circle closest-side,
    color-mix(in srgb, var(--c-blue) 34%, transparent) 0%,
    color-mix(in srgb, var(--c-blue) 16%, transparent) 42%,
    transparent 72%
  );
  animation: ss-drift 18s var(--ease-in-out-quart) infinite;
}

.intro__field::after {
  width: 40vmax;
  height: 40vmax;
  right: 2%;
  bottom: 2%;
  background: radial-gradient(
    circle closest-side,
    color-mix(in srgb, var(--fg) 10%, transparent) 0%,
    color-mix(in srgb, var(--fg) 4%, transparent) 46%,
    transparent 74%
  );
  animation: ss-drift 24s var(--ease-in-out-quart) infinite reverse;
}

.intro[data-state='ready'] .intro__field,
.intro[data-state='exiting'] .intro__field {
  opacity: 1;
}

/* --- Mark --- */
.intro__stage {
  position: relative;
  display: grid;
  place-items: center;
  gap: var(--s-7);
  padding: var(--gutter);
  text-align: center;
}

.intro__mark {
  width: clamp(11rem, 34vw, 26rem);
  height: auto;
  color: var(--fg);
  opacity: 0;
  transform: scale(0.9);
  transition:
    opacity var(--d-slower) var(--ease-out-expo),
    transform var(--d-slower) var(--ease-out-expo);
}

.intro[data-state='ready'] .intro__mark {
  opacity: 1;
  transform: scale(1);
}

/* --- Scroll instruction --- */
.intro__hint {
  display: grid;
  justify-items: center;
  gap: var(--s-3);
  opacity: 0;
  transform: translate3d(0, 0.75rem, 0);
  transition:
    opacity var(--d-slow) var(--ease-out-quart) 460ms,
    transform var(--d-slow) var(--ease-out-quart) 460ms;
}

.intro[data-state='ready'] .intro__hint {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

.intro__hint-text {
  font-family: var(--font-display);
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: var(--track-wider);
  text-transform: uppercase;
  color: var(--fg-faint);
}

.intro__hint-arrow {
  width: 1rem;
  height: 1.5rem;
  color: var(--accent-text);
  animation: ss-scroll-hint 2.4s var(--ease-in-out-quart) infinite;
}

/* --- Skip control --- */
.intro__skip {
  position: absolute;
  bottom: var(--gutter);
  right: var(--gutter);
  padding: var(--s-3) var(--s-4);
  font-family: var(--font-display);
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--fg-faint);
  border: var(--border-w) solid var(--rule-interactive);
  opacity: 0;
  transition:
    opacity var(--d-slow) var(--ease-out-quart) 680ms,
    color var(--d-fast) linear,
    border-color var(--d-fast) linear;
}

.intro[data-state='ready'] .intro__skip {
  opacity: 1;
}

.intro__skip:hover,
.intro__skip:focus-visible {
  color: var(--fg);
  border-color: var(--accent);
}

/* --- Exit --------------------------------------------------------------- */
/* The mark accelerates away along its own diagonal — it reads as the logo
   "slipstreaming" off screen and unlocking the site behind it. */
.intro[data-state='exiting'] {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.intro[data-state='exiting'] .intro__mark {
  transform: translate3d(26vw, -18vh, 0) scale(2.2) rotate(-7deg);
  opacity: 0;
  transition:
    transform var(--d-intro) var(--ease-in-out-quart),
    opacity var(--d-intro) var(--ease-in-out-quart);
}

.intro[data-state='exiting'] .intro__hint,
.intro[data-state='exiting'] .intro__skip {
  opacity: 0;
  transition: opacity var(--d-base) linear;
}

/* A blue sheet wipes across as the logo leaves — the "activation" flash. */
.intro__wipe {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 55%;
  background: linear-gradient(
    100deg,
    transparent 0%,
    color-mix(in srgb, var(--c-blue) 70%, transparent) 40%,
    color-mix(in srgb, var(--c-blue) 92%, transparent) 50%,
    color-mix(in srgb, var(--c-blue) 70%, transparent) 60%,
    transparent 100%
  );
  transform: translate3d(-110%, 0, 0);
  pointer-events: none;
  opacity: 0;
}

.intro[data-state='exiting'] .intro__wipe {
  opacity: 0.85;
  transform: translate3d(300%, 0, 0);
  transition:
    transform calc(var(--d-intro) * 0.85) var(--ease-in-out-quart),
    opacity var(--d-base) linear;
}

/* Reduced motion: the intro is removed by JS before paint. This is a
   belt-and-braces guard so nothing can animate if that path is ever missed. */
@media (prefers-reduced-motion: reduce) {
  .intro {
    display: none;
  }
}

/* ==========================================================================
   2. Hero
   ========================================================================== */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* Tightened so the headline, lead and CTAs share one screen. */
  padding-top: calc(var(--nav-h) + var(--s-5));
  padding-bottom: var(--s-6);
  overflow: hidden;
}

/* Faint grid — technical texture, almost subliminal. Static: painted once. */
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, var(--grid-line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid-line) 1px, transparent 1px);
  background-size: clamp(4rem, 12vw, 9rem) clamp(4rem, 12vw, 9rem);
  mask-image: radial-gradient(
    ellipse 90% 70% at 50% 40%,
    #000 20%,
    transparent 75%
  );
  opacity: var(--grid-opacity);
  /* Above the drifting field, below the copy. */
  z-index: 1;
}

/* --- Ambient field behind the headline -----------------------------------
   Two slow-drifting colour fields sit between the grid and the type. Same
   technique as the entrance: soft-stopped radial gradients moved by transform
   only — no filter, so they are effectively free to animate.

   They sit at z-index 0 with the copy at z-index 1, and are aria-hidden, so
   they never interfere with reading or selection.
   ------------------------------------------------------------------------ */
.hero__field {
  position: absolute;
  inset: 0;
  /* No overflow:hidden here — clipping a gradient mid-falloff leaves a hard
     straight edge. The hero itself already clips. */
  pointer-events: none;
  z-index: 0;
}

.hero__field span {
  position: absolute;
  display: block;
  border-radius: 50%;
  will-change: transform;
}

.hero__field span:nth-child(1) {
  width: 56vmax;
  height: 56vmax;
  top: -18%;
  left: -12%;
  background: radial-gradient(
    circle closest-side,
    var(--field-a) 0%,
    var(--field-a-mid) 45%,
    transparent 72%
  );
  animation: ss-drift 22s var(--ease-in-out-quart) infinite;
}

.hero__field span:nth-child(2) {
  width: 42vmax;
  height: 42vmax;
  right: -8%;
  top: 12%;
  background: radial-gradient(
    circle closest-side,
    var(--field-b) 0%,
    var(--field-b-mid) 48%,
    transparent 74%
  );
  animation: ss-drift 30s var(--ease-in-out-quart) infinite reverse;
}

.hero__field span:nth-child(3) {
  width: 34vmax;
  height: 34vmax;
  left: 34%;
  bottom: -20%;
  background: radial-gradient(
    circle closest-side,
    var(--field-c) 0%,
    transparent 70%
  );
  animation: ss-drift 26s var(--ease-in-out-quart) infinite 2s;
}

/* An ambient loop is decoration, not information — stop it entirely. */
@media (prefers-reduced-motion: reduce) {
  .hero__field span {
    animation: none !important;
    will-change: auto;
  }
}

.hero__inner {
  position: relative;
  /* Above both the field and the grid. */
  z-index: 2;
  width: 100%;
}

.hero__title {
  font-family: var(--font-display);
  font-size: var(--t-4xl);
  font-weight: 700;
  line-height: var(--lh-tight);
  letter-spacing: var(--track-tight);
  text-transform: uppercase;
  max-width: 14ch;
  margin-bottom: var(--s-5);
}

.hero__meta {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s-7);
  flex-wrap: wrap;
  margin-top: var(--s-5);
  padding-top: var(--s-4);
  border-top: var(--border-w) solid var(--rule-faint);
}

.hero__actions {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  flex-wrap: wrap;
}

.hero__scroll {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  color: var(--fg-faint);
  font-family: var(--font-display);
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: var(--track-wider);
  text-transform: uppercase;
}

.hero__scroll svg {
  width: 0.75rem;
  height: 1.125rem;
  flex: none;
  animation: ss-scroll-hint 2.4s var(--ease-in-out-quart) infinite;
}

/* ==========================================================================
   3. Services
   ========================================================================== */
.services__list {
  border-top: var(--border-w) solid var(--rule-faint);
}

.service {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr 1.1fr;
  gap: var(--s-5) var(--s-7);
  align-items: start;
  padding-block: clamp(var(--s-5), 3.5vw, var(--s-7));
  border-bottom: var(--border-w) solid var(--rule-faint);
  isolation: isolate;
}

/* Blue sheet wipes in from the left on hover. */
.service::before {
  content: '';
  position: absolute;
  inset: 0 calc(var(--gutter) * -0.5);
  z-index: -1;
  background: linear-gradient(
    90deg,
    color-mix(in srgb, var(--c-blue) 12%, transparent),
    transparent 70%
  );
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--d-slow) var(--ease-out-expo);
}

.service:hover::before,
.service:focus-within::before {
  transform: scaleX(1);
}

.service__index {
  font-family: var(--font-display);
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: var(--track-wide);
  color: var(--fg-faint);
  font-variant-numeric: tabular-nums;
  padding-top: 0.55em;
  transition: color var(--d-base) var(--ease-out-quart);
}

.service:hover .service__index {
  color: var(--accent-text);
}

.service__title {
  font-family: var(--font-display);
  font-size: var(--t-lg);
  font-weight: 600;
  line-height: var(--lh-snug);
  letter-spacing: var(--track-snug);
  text-transform: uppercase;
  transition: transform var(--d-slow) var(--ease-out-expo);
}

.service:hover .service__title {
  transform: translate3d(var(--s-3), 0, 0);
}

.service__body {
  color: var(--fg-muted);
  font-size: var(--t-sm);
  line-height: var(--lh-relaxed);
  font-weight: 300;
  max-width: 44ch;
}

/* ==========================================================================
   4. Selected work — carousel
   ========================================================================== */
.work__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s-5);
  flex-wrap: wrap;
  margin-bottom: var(--s-8);
}

.carousel {
  position: relative;
}

/* The scroll container. Native scroll-snap keeps dragging on the compositor,
   so this never janks and works without JS. */
.carousel__viewport {
  display: flex;
  gap: clamp(var(--s-5), 3vw, var(--s-7));
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  /* No padding or negative margin here. Padding shifts every slide's
     offsetLeft, which put the track 8px out of alignment with the page
     gutter and clipped the leading character of each line. The focus ring is
     drawn inside instead (see below). */
  /* Hide the native scrollbar; the dots and buttons are the affordance. */
  scrollbar-width: none;
  -ms-overflow-style: none;
  overscroll-behavior-x: contain;
}

/* Draw the focus ring inside the scroll container so it needs no padding. */
.carousel__viewport:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

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

@media (prefers-reduced-motion: reduce) {
  .carousel__viewport {
    scroll-behavior: auto;
  }
}

.carousel__slide {
  flex: 0 0 100%;
  scroll-snap-align: start;
  min-width: 0;
}

/* --- Project ------------------------------------------------------------ */
.project {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-6) clamp(var(--s-6), 5vw, var(--s-9));
  align-items: center;
}

.project__visual {
  position: relative;
  aspect-ratio: 4 / 3;
  display: grid;
  place-items: center;
  padding: clamp(var(--s-6), 6vw, var(--s-9));
  overflow: hidden;
  border: var(--border-w) solid transparent;
  background: radial-gradient(
    ellipse 72% 64% at 50% 45%,
    var(--plate-core) 0%,
    var(--plate-edge) 100%
  );
  transition: border-color var(--d-slow) var(--ease-out-quart);
}

.project:hover .project__visual {
  border-color: var(--rule-faint);
}

/* --- Logo plate ----------------------------------------------------------
   The plate is always the current theme's own surface, so it reads as part
   of the page rather than a floating card. Each client logo ships a matching
   per-theme variant whose neutral ink is adapted to the background, so no
   mark is ever lost — brand hues are untouched.
   See tools/build-logo-variants.py and js/home.js.
   ------------------------------------------------------------------------ */
/* The <img> sits inside a <picture> (WebP + PNG fallback), so the PICTURE is
   the grid item, not the image.

   `align-self: stretch` makes it take the plate's height outright, so the
   image can size against a definite box without relying on percentage-height
   resolution — which is what silently failed before: the picture measured a
   correct 284x153 while the image inside still rendered 284x284 and got
   cropped by the plate's overflow:hidden. */
.project__visual picture {
  display: block;
  align-self: stretch;
  justify-self: center;
  width: 100%;
  max-width: 22rem;
  min-height: 0;
}

.project__logo {
  /* Fills the picture box and letterboxes inside it. object-fit: contain
     scales the artwork down to fit; it never crops. */
  width: 100%;
  height: 100%;
  object-fit: contain;
  transition: transform var(--d-slower) var(--ease-out-expo);
}

.project:hover .project__logo {
  transform: scale(1.04);
}

/* No colour overlay on the plate. These are client trademarks and must be
   reproduced as supplied — a blue veil recolours them (see CLAUDE.md §5).
   Hover feedback comes from the logo scale, the border, the project number
   and the rule instead. */

.project__body {
  display: grid;
  gap: var(--s-4);
  align-content: center;
}

.project__meta {
  display: flex;
  align-items: center;
  gap: var(--s-4);
}

.project__number {
  font-family: var(--font-display);
  font-size: var(--t-xl);
  font-weight: 700;
  line-height: 1;
  color: transparent;
  -webkit-text-stroke: 1px var(--rule-interactive);
  font-variant-numeric: tabular-nums;
  transition:
    -webkit-text-stroke-color var(--d-slow) var(--ease-out-quart),
    transform var(--d-slow) var(--ease-out-expo);
}

.project:hover .project__number {
  -webkit-text-stroke-color: var(--accent);
  transform: translate3d(0, -0.15em, 0);
}

.project__rule {
  flex: 1;
  height: var(--border-w);
  background: var(--rule);
  transform-origin: left;
  transform: scaleX(0.35);
  transition: transform var(--d-slower) var(--ease-out-expo);
}

.project:hover .project__rule {
  transform: scaleX(1);
}

.project__title {
  font-family: var(--font-display);
  font-size: var(--t-xl);
  font-weight: 700;
  line-height: var(--lh-snug);
  letter-spacing: var(--track-tight);
  text-transform: uppercase;
}

/* Matches .work-item__category on the Portfolio page — same data field, same
   treatment, so the two surfaces cannot look like different components. */
.project__category {
  font-size: var(--t-sm);
  color: var(--accent-text);
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
}

.project__link {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  margin-top: var(--s-2);
  font-family: var(--font-display);
  font-size: var(--t-sm);
  font-weight: 500;
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  width: fit-content;
}

/* Whole-slide click target, without nesting interactive elements. */
.project__link::after {
  content: '';
  position: absolute;
  inset: 0;
}

/* No live URL yet: a static marker, not a link — no slide-wide hit area. */
.project__link--soon {
  color: var(--fg-faint);
}

.project__link--soon::after {
  content: none;
}

.project__link--soon::before {
  content: '';
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 50%;
  background: var(--accent);
  flex: none;
}

.project__link svg {
  transition: transform var(--d-base) var(--ease-out-expo);
}

.project:hover .project__link svg {
  transform: translate3d(0.3rem, -0.3rem, 0);
}

/* --- Carousel controls -------------------------------------------------- */
.carousel__controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
  margin-top: var(--s-7);
  padding-top: var(--s-5);
  border-top: var(--border-w) solid var(--rule-faint);
}

.carousel__dots {
  display: flex;
  align-items: center;
  gap: var(--s-2);
}

.carousel__dot {
  position: relative;
  width: 2.75rem;
  height: 2.75rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* The visible dot is a pseudo-element so the hit area can stay 44px. */
.carousel__dot::before {
  content: '';
  width: 2rem;
  height: 2px;
  background: var(--rule);
  transition:
    background-color var(--d-base) var(--ease-out-quart),
    transform var(--d-base) var(--ease-out-expo);
}

.carousel__dot:hover::before {
  background: var(--fg-faint);
}

.carousel__dot[aria-selected='true']::before {
  background: var(--accent);
  transform: scaleY(2);
}

.carousel__arrows {
  display: flex;
  align-items: center;
  gap: var(--s-3);
}

.carousel__arrow {
  width: 3rem;
  height: 3rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: var(--border-w) solid var(--rule-interactive);
  color: var(--fg);
  transition:
    color var(--d-base) var(--ease-out-quart),
    border-color var(--d-base) var(--ease-out-quart),
    background-color var(--d-base) var(--ease-out-quart);
}

.carousel__arrow:hover:not(:disabled),
.carousel__arrow:focus-visible:not(:disabled) {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--btn-primary-fg);
}

.carousel__arrow:disabled {
  opacity: 0.32;
  cursor: not-allowed;
}

.carousel__arrow svg {
  width: 1rem;
  height: 1rem;
}

.work__more {
  margin-top: clamp(var(--s-6), 4vw, var(--s-8));
  display: flex;
  justify-content: flex-end;
}

/* ==========================================================================
   5. Process
   ========================================================================== */
.process__list {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--s-6);
}

.step {
  display: grid;
  gap: var(--s-3);
  align-content: start;
  padding-top: var(--s-4);
  border-top: var(--border-w) solid var(--rule-faint);
  position: relative;
  /* Hovering anywhere on the column drives the whole group. */
  transition: transform var(--d-base) var(--ease-out-expo);
}

.step:hover {
  transform: translate3d(0, -0.35rem, 0);
}

.step__title {
  transition: color var(--d-base) var(--ease-out-quart);
}

.step:hover .step__title {
  color: var(--accent-text);
}

.step__body {
  transition:
    color var(--d-base) var(--ease-out-quart),
    opacity var(--d-base) var(--ease-out-quart);
  opacity: 0.85;
}

.step:hover .step__body {
  color: var(--fg);
  opacity: 1;
}

/* The index slides right and the blue rule above thickens. */
.step__index {
  transition: transform var(--d-base) var(--ease-out-expo);
}

.step:hover .step__index {
  transform: translate3d(0.3rem, 0, 0);
}

.step:hover::before {
  transform: scaleX(1) scaleY(2.5);
}

/* The rule above each step fills with blue as it reveals. */
.step::before {
  content: '';
  position: absolute;
  inset: -1px 0 auto 0;
  height: var(--border-w);
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left top;
  transition: transform var(--d-slower) var(--ease-out-expo);
  transition-delay: var(--reveal-delay, 0ms);
}

.step[data-revealed]::before {
  transform: scaleX(1);
}

/* Once revealed, hover reacts fast — the slow reveal easing would feel laggy
   as an interaction. */
.step[data-revealed]::before {
  transition-delay: 0ms;
  transition-duration: var(--d-base);
}

.step__index {
  font-family: var(--font-display);
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: var(--track-wide);
  color: var(--accent-text);
  font-variant-numeric: tabular-nums;
}

.step__title {
  font-family: var(--font-display);
  font-size: var(--t-md);
  font-weight: 600;
  letter-spacing: var(--track-snug);
  text-transform: uppercase;
}

.step__body {
  font-size: var(--t-sm);
  color: var(--fg-muted);
  font-weight: 300;
  line-height: var(--lh-relaxed);
}

/* ==========================================================================
   6. Philosophy
   ========================================================================== */
.philosophy {
  background: var(--bg-raised);
  border-block: var(--border-w) solid var(--rule-faint);
}

.philosophy__statement {
  font-family: var(--font-display);
  font-size: var(--t-2xl);
  font-weight: 500;
  line-height: var(--lh-snug);
  letter-spacing: var(--track-tight);
  max-width: 20ch;
  text-wrap: balance;
  margin-bottom: var(--s-9);
}

.philosophy__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--s-6);
}

.principle {
  display: grid;
  gap: var(--s-2);
  align-content: start;
  padding-top: var(--s-4);
  border-top: var(--border-w) solid var(--rule-faint);
  position: relative;
  transition: transform var(--d-base) var(--ease-out-expo);
}

.principle:hover {
  transform: translate3d(0, -0.35rem, 0);
}

.principle::before {
  content: '';
  position: absolute;
  inset: -1px 0 auto 0;
  height: var(--border-w);
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left top;
  transition: transform var(--d-slower) var(--ease-out-expo);
  transition-delay: var(--reveal-delay, 0ms);
}

.principle[data-revealed]::before {
  transform: scaleX(1);
}

.principle[data-revealed]::before {
  transition-delay: 0ms;
  transition-duration: var(--d-base);
}

.principle:hover::before {
  transform: scaleX(1) scaleY(2.5);
}

.principle__title {
  font-family: var(--font-display);
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  display: flex;
  align-items: baseline;
  gap: var(--s-3);
  transition: color var(--d-base) var(--ease-out-quart);
}

.principle:hover .principle__title {
  color: var(--accent-text);
}

/* The diamond spins a quarter turn and grows slightly. */
.principle__title::before {
  content: '';
  width: 0.5rem;
  height: 0.5rem;
  background: var(--accent);
  flex: none;
  transform: rotate(45deg);
  transition: transform var(--d-slow) var(--ease-out-expo);
}

.principle:hover .principle__title::before {
  transform: rotate(135deg) scale(1.25);
}

.principle__body {
  font-size: var(--t-sm);
  color: var(--fg-muted);
  font-weight: 300;
  opacity: 0.9;
  transition:
    color var(--d-base) var(--ease-out-quart),
    opacity var(--d-base) var(--ease-out-quart);
}

.principle:hover .principle__body {
  color: var(--fg);
  opacity: 1;
}

/* ==========================================================================
   7. Final CTA
   ========================================================================== */
.cta {
  position: relative;
  text-align: center;
  overflow: hidden;
}

.cta__glow {
  position: absolute;
  inset: -10% -20% -40%;
  pointer-events: none;
  background: radial-gradient(
    ellipse 50% 60% at 50% 100%,
    color-mix(in srgb, var(--c-blue) 20%, transparent) 0%,
    color-mix(in srgb, var(--c-blue) 8%, transparent) 40%,
    transparent 72%
  );
}

.cta__inner {
  position: relative;
  display: grid;
  justify-items: center;
  gap: var(--s-5);
}

.cta__title {
  font-family: var(--font-display);
  font-size: var(--t-3xl);
  font-weight: 700;
  line-height: var(--lh-tight);
  letter-spacing: var(--track-tight);
  text-transform: uppercase;
  max-width: 16ch;
}

.cta__body {
  color: var(--fg-muted);
  max-width: 40ch;
  font-weight: 300;
}

.cta__action {
  margin-top: var(--s-4);
}
