/* ============================================================
   Changing Nepal — home page
   Depends on cn.css for tokens and shared primitives.
   ============================================================ */

/* ============================================================
   Hero
   ============================================================ */
.cn-hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  background: var(--cn-ink-deep);
  color: var(--cn-on-ink);
}

.cn-hero__media { position: absolute; inset: 0; z-index: 0; }

/* The ground the video loads over, and the whole hero on phones where
   the video is never fetched. A single brand glow so it is not flat. */
.cn-hero {
  background:
    radial-gradient(120% 80% at 78% 8%, rgba(0,163,224,0.22) 0%, rgba(0,163,224,0) 60%),
    radial-gradient(90% 70% at 8% 96%, rgba(62,177,73,0.16) 0%, rgba(62,177,73,0) 62%),
    var(--cn-ink-deep);
}
.cn-no-herovideo .cn-hero__media { display: none; }
.cn-hero__media img,
.cn-hero__media video,
.cn-hero__media iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border: 0;
}

/* A self-hosted file needs none of the iframe's workarounds — it has no
   chrome to crop out and no overlay to wait for. It only fades in so the
   first frame does not pop before the motion starts, and it stays put
   when paused, which is the whole point of using a file. */
.cn-hero__media video {
  opacity: 0;
  transition: opacity 600ms var(--cn-ease);
}
.cn-hero__media video.is-playing { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .cn-hero__media video { transition: none; }
}
/* A 16:9 frame scaled to cover the viewport — YouTube will not
   crop for us, so the iframe is oversized and centred instead.
   The extra 1.35 scale pushes YouTube's own title bar and bottom
   bar outside the visible crop; they are drawn inside the iframe
   and cannot be reached with CSS. pointer-events are off so the
   player can never be paused into showing its overlay. */
.cn-hero__media iframe {
  top: 50%; left: 50%;
  width: 100vw;
  height: 56.25vw;
  min-height: 100svh;
  min-width: 177.78svh;
  transform: translate(-50%, -50%) scale(1.35);
  pointer-events: none;
  /* Held back until the player reports PLAYING. YouTube draws a large
     play overlay over the poster frame while it is starting, and that
     cannot be reached with CSS — so the frame is simply not shown
     until there is moving picture behind the type. */
  opacity: 0;
  transition: opacity 600ms var(--cn-ease);
}
.cn-hero__media iframe.is-playing { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .cn-hero__media iframe { transition: none; }
}
/* The footage is daylight aerial video, so it is bright where the
   type sits. Two layers: a strong base under the copy, and an even
   wash so the headline holds over the lightest frames. */
.cn-hero__scrim {
  position: absolute; inset: 0; z-index: 1;
  background:
    linear-gradient(to top, rgba(0,0,0,0.92) 0%, rgba(0,0,0,0.70) 34%, rgba(0,0,0,0.34) 68%, rgba(0,0,0,0.42) 100%),
    rgba(0,0,0,0.16);
}

/* Hero type sits on video, not on the page ground, so the muted
   tokens have to be re-pointed at the light end. */
.cn-hero .cn-eyebrow { color: rgba(255,255,255,0.88); }
.cn-hero .cn-eyebrow b { color: var(--cn-brand); }

.cn-hero__inner {
  position: relative;
  z-index: 2;
  width: 100%;
  padding-block: clamp(2rem, 6vw, 4.5rem) clamp(2rem, 4vw, 3.5rem);
  padding-top: calc(var(--cn-head-h) + clamp(2rem, 6vw, 4.5rem));
}

.cn-hero__title {
  font-family: var(--cn-display);
  font-size: var(--cn-t-hero);
  font-weight: 800;
  line-height: 0.92;
  letter-spacing: -0.03em;
  margin-bottom: clamp(1rem, 2vw, 1.5rem);
  max-width: 18ch;
}
/* The Nepali line needs its own leading — Devanagari carries
   ascenders the Latin metrics do not account for. */
.cn-hero__title:lang(ne) { line-height: 1.24; letter-spacing: -0.01em; }

.cn-hero__lead { color: rgba(255,255,255,0.86); max-width: 44ch; font-size: clamp(1rem, 1.4vw, 1.2rem); }
.cn-hero__row { display: flex; flex-wrap: wrap; gap: 0.75rem 1rem; margin-top: clamp(1.5rem, 3vw, 2.25rem); }

/* The ruled band: supporting line on the left, the single call to
   action pushed out to the right margin. */
.cn-hero__band {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.25rem 2rem;
  border-top: 1px solid rgba(255,255,255,0.22);
  margin-top: clamp(1.5rem, 3vw, 2.5rem);
  padding-top: clamp(1.25rem, 2.5vw, 1.75rem);
}
.cn-hero__band .cn-btn { flex: none; }

/* ---------- pause control ---------- */
/* Moved out of the top-right corner, where it sat directly beside the
   headline and read as part of the message rather than as a control
   for the footage behind it. The bottom corner is the conventional
   place for playback control, and it is now free — the floating
   WhatsApp button no longer shows on phones. */
.cn-hero__pause {
  position: absolute;
  top: auto;
  bottom: 1.15rem;
  right: max(var(--cn-gutter), calc(50% - (var(--cn-maxw) / 2) + var(--cn-gutter)));
  z-index: 3;
  padding: 0.5rem 0.9rem;
  border: 1px solid rgba(255,255,255,0.3);
  background: rgba(0,0,0,0.4);
  color: #fff;
  font-family: var(--cn-data);
  font-size: var(--cn-t-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  transition: background var(--cn-dur) var(--cn-ease), border-color var(--cn-dur) var(--cn-ease);
}
.cn-hero__pause:hover { background: var(--cn-brand); border-color: var(--cn-brand); color: var(--cn-on-brand); }

.cn-hero .cn-btn { --cn-btn-fill: var(--cn-on-ink); --cn-btn-on: var(--cn-ink-deep); }
.cn-hero .cn-btn--brand { --cn-btn-fill: var(--cn-brand); --cn-btn-on: var(--cn-on-brand); color: var(--cn-on-ink); border-color: var(--cn-brand); }

/* ---------- hero contact bar ---------- */
.cn-hero__foot {
  position: relative;
  z-index: 2;
  border-top: 1px solid rgba(255,255,255,0.18);
  margin-top: clamp(2rem, 5vw, 3.5rem);
  padding-top: 1.15rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.85rem clamp(1.25rem, 3vw, 2.75rem);
}
.cn-hero__contact {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--cn-data);
  font-size: var(--cn-t-xs);
  letter-spacing: 0.08em;
  color: rgba(255,255,255,0.82);
}
.cn-hero__contact .cn-ico { color: var(--cn-brand); font-size: 1rem; }
.cn-hero__contact a:hover { color: #fff; }
/* Left-aligned with the contact details rather than shoved to the
   opposite end of the rule. On a narrow screen the row wraps, and a
   right-pushed group landed alone on its own line with the whole
   width of the column between it and everything else. */
.cn-hero__social { display: flex; gap: 0.45rem; }
.cn-hero__social a {
  display: grid; place-items: center;
  width: 2.25rem; height: 2.25rem;
  border: 1px solid rgba(255,255,255,0.25);
  transition: background var(--cn-dur) var(--cn-ease), border-color var(--cn-dur) var(--cn-ease), color var(--cn-dur) var(--cn-ease);
}
.cn-hero__social a:hover { background: var(--cn-brand); border-color: var(--cn-brand); color: var(--cn-on-brand); }

/* ============================================================
   Spotlight
   ============================================================ */
.cn-spot { display: grid; gap: clamp(1.5rem, 4vw, 3.5rem); align-items: center; grid-template-columns: 1fr; }
@media (min-width: 62rem) { .cn-spot { grid-template-columns: 1.1fr 1fr; } }
.cn-spot__shot { position: relative; overflow: hidden; background: var(--cn-bg-soft); aspect-ratio: 4 / 3; }
.cn-spot__shot img { width: 100%; height: 100%; object-fit: cover; }
.cn-spot__list { display: grid; gap: 0.6rem; margin-top: 1.5rem; }
.cn-spot__list div { display: flex; justify-content: space-between; gap: 1rem; border-bottom: 1px solid var(--cn-line); padding-bottom: 0.5rem; font-size: var(--cn-t-sm); }
.cn-spot__list dt, .cn-spot__list b { font-family: var(--cn-data); font-size: var(--cn-t-xs); letter-spacing: 0.1em; text-transform: uppercase; color: var(--cn-fg-muted); font-weight: 400; }

/* ============================================================
   Services
   ============================================================ */
.cn-steps { display: grid; gap: 1px; background: var(--cn-line); border: 1px solid var(--cn-line); grid-template-columns: 1fr; }
/* The controller serves at most six services, so two and three
   columns both divide evenly. A four-column row would leave two
   empty cells showing the grid's line colour as grey holes. */
@media (min-width: 44rem) { .cn-steps { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 68rem) { .cn-steps { grid-template-columns: repeat(3, 1fr); } }
.cn-step {
  background: var(--cn-bg);
  padding: clamp(1.25rem, 2.5vw, 1.85rem);
  display: flex; flex-direction: column; gap: 0.6rem;
  transition: background var(--cn-dur) var(--cn-ease);
}
.cn-step:hover { background: var(--cn-bg-soft); }
.cn-step__n { font-family: var(--cn-data); font-size: var(--cn-t-xs); color: var(--cn-brand-deep); letter-spacing: 0.12em; }
.cn-step__t { font-family: var(--cn-display); font-size: var(--cn-t-h3); font-weight: 700; line-height: 1.15; }
.cn-step__d { font-size: var(--cn-t-sm); color: var(--cn-fg-muted); }

/* ============================================================
   Clients
   ============================================================ */
.cn-clients { display: grid; gap: 1px; background: var(--cn-ink-line); border: 1px solid var(--cn-ink-line); grid-template-columns: repeat(2, 1fr); }
@media (min-width: 44rem) { .cn-clients { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 62rem) { .cn-clients { grid-template-columns: repeat(6, 1fr); } }
.cn-client {
  display: grid; place-items: center;
  background: var(--cn-ink-bg);
  aspect-ratio: 3 / 2;
  padding: 1.15rem;
}
/* Grid items default to min-width:auto, so a logo wider than its
   track pushes the whole grid past the page and the document
   scrolls sideways. */
.cn-clients > *, .cn-posts > *, .cn-steps > *, .cn-mega__grid > * { min-width: 0; }
.cn-client img {
  max-width: 100%; max-height: 100%;
  width: auto; object-fit: contain;
  /* Logos arrive in every colour; muting with a filter leaves
     opacity free for the reveal animation to own. */
  filter: grayscale(1) brightness(1.6) opacity(0.62);
  transition: filter 420ms var(--cn-ease);
}
.cn-client:hover img { filter: none; }

/* ============================================================
   Testimonials — the table is empty today, so this only appears
   once the client adds rows through the admin panel.
   ============================================================ */
.cn-says { overflow: hidden; }
.cn-says__track { display: flex; gap: clamp(1rem, 2vw, 1.5rem); width: max-content; animation: cn-slide 60s linear infinite; }
.cn-says.is-paused .cn-says__track, .cn-says:hover .cn-says__track { animation-play-state: paused; }
.cn-say {
  width: min(24rem, 78vw);
  border: 1px solid var(--cn-ink-line);
  padding: clamp(1.25rem, 2.5vw, 1.85rem);
  display: flex; flex-direction: column; gap: 1rem;
}
.cn-say__q { font-size: var(--cn-t-sm); color: var(--cn-on-ink-dim); }
.cn-say__who { display: flex; align-items: center; gap: 0.75rem; margin-top: auto; }
.cn-say__who img { width: 2.75rem; height: 2.75rem; object-fit: cover; border-radius: 50%; }
.cn-say__name { font-weight: 600; font-size: var(--cn-t-sm); }
@media (prefers-reduced-motion: reduce) { .cn-says__track { animation: none; flex-wrap: wrap; width: 100%; } }

/* ============================================================
   Category tiles

   Icons rather than the category photographs. That artwork is
   marketing composites at mismatched crops — eleven of them in a
   row read as noise, and every tile fought the next one. A drawn
   mark gives the grid one rhythm.
   ============================================================ */
.cn-ctiles {
  display: grid;
  gap: 1px;
  background: var(--cn-line);
  border: 1px solid var(--cn-line);
  grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 48rem) { .cn-ctiles { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 70rem) { .cn-ctiles { grid-template-columns: repeat(4, 1fr); } }
.cn-ctiles > * { min-width: 0; }

.cn-ctile {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  padding: clamp(1.15rem, 2.2vw, 1.6rem);
  background: var(--cn-bg);
  transition: background var(--cn-dur) var(--cn-ease);
}
.cn-ctile:hover, .cn-ctile:focus-visible { background: var(--cn-bg-soft); }

.cn-ctile__mark {
  display: grid; place-items: center;
  width: 3rem; height: 3rem;
  border: 1px solid var(--cn-line);
  color: var(--cn-fg);
  transition: background var(--cn-dur) var(--cn-ease),
              border-color var(--cn-dur) var(--cn-ease),
              color var(--cn-dur) var(--cn-ease);
}
.cn-ctile__mark .cn-ico { width: 1.6rem; height: 1.6rem; stroke-width: 1.75; }
.cn-ctile:hover .cn-ctile__mark {
  background: var(--cn-brand); border-color: var(--cn-brand); color: var(--cn-on-brand);
}

.cn-ctile__name {
  font-family: var(--cn-display);
  font-size: var(--cn-t-h3);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.01em;
  margin-top: auto;
}
.cn-ctile__n {
  font-family: var(--cn-data);
  font-size: var(--cn-t-xs);
  letter-spacing: 0.08em;
  color: var(--cn-fg-muted);
}
.cn-ctile__go {
  position: absolute; top: clamp(1.15rem, 2.2vw, 1.6rem); right: clamp(1.15rem, 2.2vw, 1.6rem);
  opacity: 0;
  transform: translate(-4px, 4px);
  transition: opacity var(--cn-dur) var(--cn-ease), transform var(--cn-dur) var(--cn-ease);
  color: var(--cn-brand-deep);
}
.cn-ctile:hover .cn-ctile__go { opacity: 1; transform: none; }

/* ============================================================
   Machine card — the specification card

   The product images are designed posters, not photographs: a
   branded header bar, the machine, and set text. Measured across
   the catalogue their aspect ratios run from 0.59 to 1.84, with
   the bulk at 1.00 and 1.13 — so any single crop would cut the
   header off some and the caption off others. They are contained
   on a square frame instead, whole, on a soft ground.
   ============================================================ */
.cn-sec--soft { background: var(--cn-bg-soft); }

.cn-mach {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--cn-bg);
  border: 1px solid var(--cn-line);
  height: 100%;
  isolation: isolate;
  transition: border-color var(--cn-dur) var(--cn-ease),
              transform 380ms var(--cn-ease),
              box-shadow 380ms var(--cn-ease);
}
.cn-mach:hover,
.cn-mach:focus-visible {
  border-color: var(--cn-brand);
  transform: translateY(-6px);
  box-shadow: 0 22px 40px -24px rgba(0,0,0,0.45);
}

/* getResized() fits the poster inside the box preserving aspect and
   then pads the canvas to exactly WxH with #f3f3f3. So the file is
   already square with its own letterbox baked in: no padding of our
   own (that would shrink it twice) and the frame background is set to
   the same grey so the seam is invisible. */
.cn-mach__shot {
  position: relative;
  overflow: hidden;
  background: #f3f3f3;
  aspect-ratio: 1 / 1;
  display: grid;
  place-items: center;
}
.cn-mach__shot img {
  width: 100%; height: 100%;
  object-fit: contain;
  transition: transform 700ms var(--cn-ease);
}
.cn-mach:hover .cn-mach__shot img { transform: scale(1.04); }

/* Slides up over the foot of the poster on hover. */
.cn-mach__peek {
  position: absolute;
  inset: auto 0 0 0;
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.5rem;
  padding: 0.7rem 0.9rem;
  background: var(--cn-ink-deep);
  color: var(--cn-on-ink);
  font-family: var(--cn-data);
  font-size: var(--cn-t-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  transform: translateY(101%);
  transition: transform 380ms var(--cn-ease);
}
.cn-mach:hover .cn-mach__peek,
.cn-mach:focus-visible .cn-mach__peek { transform: none; }
.cn-mach__peek .cn-ico { width: 1rem; height: 1rem; }

.cn-mach__body { display: flex; flex-direction: column; gap: 0.5rem; padding: 1.15rem; flex: 1; }

/* Category on the left, price on the right — the two things a buyer
   scans for before the name registers. */
.cn-mach__meta {
  display: flex; align-items: baseline; justify-content: space-between; gap: 0.75rem;
  font-family: var(--cn-data); font-size: var(--cn-t-xs);
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--cn-fg-muted);
}
.cn-mach__price { color: var(--cn-green-deep); white-space: nowrap; }
.cn-mach__price--ask { color: var(--cn-fg-muted); }

.cn-mach__name {
  font-family: var(--cn-display);
  font-size: clamp(1.15rem, 1.5vw, 1.35rem);
  font-weight: 700; line-height: 1.15; letter-spacing: -0.01em;
  transition: color var(--cn-dur) var(--cn-ease);
}
.cn-mach:hover .cn-mach__name { color: var(--cn-brand-deep); }

.cn-mach__desc {
  font-size: var(--cn-t-sm);
  color: var(--cn-fg-muted);
  /* Two lines, so a long description cannot make one card taller
     than the rest of the rail. */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Output and power side by side. Only the fields a machine actually
   carries are printed, so a card may show one column or none. */
.cn-mach__specs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.75rem;
  margin-top: auto;
  padding-top: 0.9rem;
  border-top: 1px solid var(--cn-line);
}
.cn-mach__specs > span { display: grid; gap: 0.2rem; min-width: 0; }
.cn-mach__specs b {
  font-family: var(--cn-data); font-size: var(--cn-t-xs); font-weight: 400;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--cn-fg-muted);
}
.cn-mach__specs i {
  font-style: normal; font-size: var(--cn-t-sm); line-height: 1.3;
  overflow-wrap: anywhere;
}

@media (prefers-reduced-motion: reduce) {
  .cn-mach, .cn-mach__shot img, .cn-mach__peek { transition: none; }
  .cn-mach:hover { transform: none; }
}

/* The specification card carries two spec columns, so it needs more
   width than the plain rail card before the values start wrapping. */
.cn-rail--wide .cn-rail__track { grid-auto-columns: minmax(19rem, 24rem); }

/* ============================================================
   Full-bleed rail

   The track spans the viewport, but its first card lines up with
   the content column so the row starts under the heading. The
   right-hand card is deliberately cut by the screen edge — that
   overflow is what signals there is more to scroll.
   ============================================================ */
.cn-rail--bleed { position: relative; }

.cn-rail--bleed .cn-rail__track {
  /* Left inset matches .cn-wrap's content edge; the right inset is
     just breathing room past the last card. */
  padding-left: max(var(--cn-gutter), calc(50% - (var(--cn-maxw) / 2) + var(--cn-gutter)));
  padding-right: var(--cn-gutter);
  /* Snap to the content edge, not the viewport edge, so a snapped
     card lands where the heading starts. */
  scroll-padding-left: max(var(--cn-gutter), calc(50% - (var(--cn-maxw) / 2) + var(--cn-gutter)));
}

/* ---------- progress ---------- */
.cn-rail__foot {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 3vw, 2.5rem);
  margin-top: clamp(1.25rem, 2.5vw, 2rem);
}

.cn-rail__bar {
  position: relative;
  flex: 1;
  height: 2px;
  background: var(--cn-line-hard);
  overflow: hidden;
}
.cn-rail__bar > span {
  position: absolute;
  inset: 0 auto 0 0;
  width: 100%;
  background: var(--cn-brand);
  transform-origin: left center;
  /* Set by cn.js: scaleX is the visible fraction, translateX walks it
     along as the track scrolls. */
  transform: scaleX(0.3);
}

.cn-rail__hint {
  flex: none;
  font-family: var(--cn-data);
  font-size: var(--cn-t-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--cn-fg-muted);
}
@media (max-width: 44rem) { .cn-rail__hint { display: none; } }

/* ============================================================
   Stats band

   The figures come from the stats row the client maintains in
   admin, not from anything invented here.
   ============================================================ */
.cn-stats {
  display: grid;
  gap: clamp(1.5rem, 4vw, 3rem);
  grid-template-columns: repeat(2, 1fr);
  border-top: 1px solid var(--cn-line);
  padding-top: clamp(1.75rem, 3.5vw, 2.75rem);
}
@media (min-width: 60rem) { .cn-stats { grid-template-columns: repeat(4, 1fr); } }
.cn-stats > * { min-width: 0; }

.cn-stat__k {
  font-family: var(--cn-data); font-size: var(--cn-t-xs);
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--cn-fg-muted);
  margin-bottom: 0.5rem;
}
.cn-stat__v {
  font-family: var(--cn-display);
  font-size: clamp(2.2rem, 5vw, 3.6rem);
  font-weight: 800; line-height: 0.95; letter-spacing: -0.03em;
}
.cn-stat__v small {
  font-size: 0.4em; font-weight: 600; letter-spacing: 0;
  color: var(--cn-fg-muted); margin-left: 0.15em;
}

/* ============================================================
   Process

   The company's real services, read as a route from first call to
   after-sales. Each step is a mark, a number and two or three
   words — the detail lives on the services page.
   ============================================================ */
.cn-flow {
  display: grid;
  gap: 1px;
  background: var(--cn-ink-line);
  border: 1px solid var(--cn-ink-line);
  grid-template-columns: 1fr;
}
@media (min-width: 40rem) { .cn-flow { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 64rem) { .cn-flow { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 88rem) { .cn-flow { grid-template-columns: repeat(5, 1fr); } }
.cn-flow > * { min-width: 0; }

.cn-flow__step {
  position: relative;
  display: flex; flex-direction: column; gap: 0.85rem;
  background: var(--cn-ink-bg);
  padding: clamp(1.25rem, 2.4vw, 1.75rem);
  transition: background var(--cn-dur) var(--cn-ease);
}
.cn-flow__step:hover { background: var(--cn-ink-soft); }

.cn-flow__mark {
  display: grid; place-items: center;
  width: 3rem; height: 3rem;
  border: 1px solid var(--cn-ink-line);
  color: var(--cn-on-ink);
  transition: background var(--cn-dur) var(--cn-ease),
              border-color var(--cn-dur) var(--cn-ease),
              color var(--cn-dur) var(--cn-ease);
}
.cn-flow__mark .cn-ico { width: 1.5rem; height: 1.5rem; stroke-width: 1.7; }
.cn-flow__step:hover .cn-flow__mark {
  background: var(--cn-brand); border-color: var(--cn-brand); color: var(--cn-on-brand);
}

.cn-flow__n {
  font-family: var(--cn-data); font-size: var(--cn-t-xs);
  letter-spacing: 0.14em; color: var(--cn-brand);
}
.cn-flow__t {
  font-family: var(--cn-display);
  font-size: var(--cn-t-h3);
  font-weight: 700; line-height: 1.15; letter-spacing: -0.01em;
  margin-top: auto;
}

/* ============================================================
   Closing call to action — the enquiry, on the page
   ============================================================ */
.cn-cta {
  display: grid;
  gap: clamp(2rem, 5vw, 4rem);
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 68rem) { .cn-cta { grid-template-columns: 1fr 1fr; } }

.cn-cta__aside .cn-h2 { margin-block: 0.75rem 1.15rem; }
.cn-cta__points { display: grid; gap: 0.85rem; margin-top: clamp(1.5rem, 3vw, 2rem); }
.cn-cta__points div { display: flex; gap: 0.75rem; align-items: flex-start; font-size: var(--cn-t-sm); }
.cn-cta__points .cn-ico { color: var(--cn-brand-deep); margin-top: 0.2em; }

/* On a light ground the enquiry panel needs its own surface. */
.cn-cta .cn-ask { background: var(--cn-bg); max-width: none; }

/* Card foot: the price alone now, with the one spec moved up beside
   the category. Two lines of prose per card made the rail unscannable. */
.cn-mach__spec { color: var(--cn-fg-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cn-mach__foot { margin-top: auto; padding-top: 0.9rem; border-top: 1px solid var(--cn-line); }
.cn-mach__foot .cn-mach__price { font-family: var(--cn-data); font-size: var(--cn-t-sm); letter-spacing: 0.04em; }

/* Client wall on the light ground. */
.cn-clients--light { background: var(--cn-line); border-color: var(--cn-line); }
.cn-clients--light .cn-client { background: var(--cn-bg); }
.cn-clients--light .cn-client img { filter: grayscale(1) opacity(0.62); }
.cn-clients--light .cn-client:hover img { filter: none; }

/* ---------- card foot: one action, no price ---------- */
.cn-mach__meta { color: var(--cn-fg-muted); }
.cn-mach__view,
.cn-card__go {
  display: inline-flex; align-items: center; gap: 0.45rem;
  font-family: var(--cn-data); font-size: var(--cn-t-xs);
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--cn-fg);
}
.cn-mach:hover .cn-mach__view,
.cn-card:hover .cn-card__go { color: var(--cn-brand-deep); }
.cn-mach__view .cn-ico,
.cn-card__go .cn-ico { transition: transform var(--cn-dur) var(--cn-ease); }
.cn-mach:hover .cn-mach__view .cn-ico,
.cn-card:hover .cn-card__go .cn-ico { transform: translate(2px, -2px); }

/* ---------- testimonials ---------- */
.cn-say {
  width: min(26rem, 82vw);
  border: 1px solid var(--cn-ink-line);
  padding: clamp(1.35rem, 2.6vw, 2rem);
  display: flex; flex-direction: column; gap: 1.25rem;
  transition: border-color var(--cn-dur) var(--cn-ease), background var(--cn-dur) var(--cn-ease);
}
.cn-say:hover { border-color: var(--cn-brand); background: var(--cn-ink-soft); }
.cn-say__q {
  font-family: var(--cn-display);
  font-size: clamp(1.05rem, 1.5vw, 1.25rem);
  font-weight: 600; line-height: 1.35; letter-spacing: -0.01em;
  color: var(--cn-on-ink);
}
/* The opening mark, set large and low-contrast behind the quote. */
.cn-say__q::before {
  content: '"';
  display: block;
  font-size: 2.5em; line-height: 0.6;
  color: var(--cn-brand);
  margin-bottom: 0.15em;
}
.cn-say__who { display: flex; align-items: center; gap: 0.85rem; margin-top: auto; }
.cn-say__mark {
  display: grid; place-items: center;
  width: 2.5rem; height: 2.5rem; flex: none;
  border-radius: 50%;
  background: var(--cn-brand); color: var(--cn-on-brand);
  font-family: var(--cn-display); font-weight: 700;
}
.cn-say__name { font-weight: 600; font-size: var(--cn-t-sm); color: var(--cn-on-ink); }
.cn-say__co { font-family: var(--cn-data); font-size: var(--cn-t-xs); color: var(--cn-on-ink-dim); }

.cn-note {
  font-family: var(--cn-data); font-size: var(--cn-t-xs);
  letter-spacing: 0.08em; color: var(--cn-on-ink-dim);
  margin-top: clamp(1.25rem, 2.5vw, 2rem);
}

/* ---------- footer: the band is the button ---------- */
.cn-blast__cta {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem;
  margin-top: clamp(0.75rem, 2vw, 1.25rem);
  padding-block: clamp(0.5rem, 1.5vw, 1rem);
  color: var(--cn-on-ink);
}
.cn-blast__cta .cn-blast__line { transition: color var(--cn-dur) var(--cn-ease); }
.cn-blast__cta:hover .cn-blast__line,
.cn-blast__cta:focus-visible .cn-blast__line { color: var(--cn-brand); }
.cn-blast__arrow {
  flex: none;
  display: grid; place-items: center;
  width: clamp(3rem, 6vw, 4.5rem); height: clamp(3rem, 6vw, 4.5rem);
  border: 1px solid var(--cn-ink-line);
  border-radius: 50%;
  transition: background var(--cn-dur) var(--cn-ease),
              border-color var(--cn-dur) var(--cn-ease),
              color var(--cn-dur) var(--cn-ease),
              transform 380ms var(--cn-ease);
}
.cn-blast__arrow .cn-ico { width: 45%; height: 45%; stroke-width: 1.5; }
.cn-blast__cta:hover .cn-blast__arrow,
.cn-blast__cta:focus-visible .cn-blast__arrow {
  background: var(--cn-brand); border-color: var(--cn-brand); color: var(--cn-on-brand);
  transform: translate(4px, -4px);
}
.cn-blast__or { margin-top: 0.5rem; }
@media (prefers-reduced-motion: reduce) {
  .cn-blast__arrow { transition: none; }
  .cn-blast__cta:hover .cn-blast__arrow { transform: none; }
}

/* Phones and tablets: the hero's stat band and footer row start at
   the left edge like the headline above them, rather than floating
   in the middle of a narrow column. See the note in cn.css. */
@media (max-width: 64rem) {
  .cn-hero__band,
  .cn-hero__foot { justify-content: flex-start; }
}

/* ------------------------------------------------------------
   Hero on phones

   The hero is pinned to the viewport height with its content
   bottom-aligned, which is right on a desktop where the footage
   carries the empty upper half. On a 812px phone the content stack
   is only about 660px tall, so the remaining 150px collected above
   the eyebrow and the top padding added another 124 — roughly 270px
   of blank ground between the logo and the first word.

   Below 48rem the hero is sized by its content instead. Nothing is
   removed and the video still covers the whole section; it simply
   stops reserving space nothing occupies.
   ------------------------------------------------------------ */
@media (max-width: 48rem) {
  .cn-hero { min-height: 0; }

  /* ----------------------------------------------------------
     The footage takes the top band only.

     Full-bleed video behind the whole hero works on a wide screen,
     where the type sits in the left third and the picture fills the
     rest. On a phone the two stack on top of each other: every line
     of the headline lands on moving footage, and no scrim makes
     white type on a daylit aerial genuinely easy to read.

     So the video gets the upper 38vh and the words get solid
     ground below it. The header still sits over the footage, which
     is where the logo reads best.
     ---------------------------------------------------------- */
  .cn-hero__media {
    inset: 0 0 auto 0;
    height: 38vh;
  }

  /* The scrim follows the media instead of covering the whole
     section — over solid ground it would only muddy the black. It
     also fades the band's bottom edge into that ground so the video
     ends on a soft transition rather than a hard line. */
  .cn-hero__scrim {
    inset: 0 0 auto 0;
    height: 38vh;
    background: linear-gradient(
      to bottom,
      rgba(0, 0, 0, 0.42) 0%,
      rgba(0, 0, 0, 0.20) 45%,
      rgba(0, 0, 0, 0.75) 82%,
      var(--cn-ink-deep) 100%
    );
  }

  /* Content clears the band. */
  .cn-hero__inner { padding-top: calc(38vh + 1.75rem); }

  /* Auto-playing footage normally needs an explicit stop, and on a
     wide screen it has one. Here the clip is a 38vh band above the
     content rather than the backdrop to it, and the control was
     landing in the middle of the contact row. Motion is still
     suppressed entirely for prefers-reduced-motion. */
  .cn-hero__pause { display: none; }

  /* The phone number, email and address are in the header's call
     button, in the footer of every page and on the contact page.
     Repeating all three here pushed the hero past a screen and a
     half for information nobody is looking for at the top of a
     homepage. The social links stay. */
  .cn-hero__contact { display: none; }

  .cn-hero__foot { padding-right: 0; }
}
