/* =====================================================================
   HOMEPAGE SECTIONS — layout modelled on the ALLRICH reference site.
   Order: about (ghost word + stats) → solutions → product center
          → trio → news → contact strip → footer → side rail
   ===================================================================== */

:root {
  --accent: #e1251b;
  --accent-dark: #c71e15;
  --dark: #0a0a0a;
  --hair: #e7eaef;
}

/* ---------- shared bits ---------- */
.sec__label {
  margin: 0 0 12px;
  text-align: center;
  font-size: 15px;
  font-weight: 400;
  letter-spacing: .02em;
  color: #8b95a3;
}
.sec__label--light { color: rgba(255, 255, 255, .8); }
.sec__label--left { text-align: left; }

.btn-red {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 152px;
  height: 44px;
  padding: 0 28px;
  border-radius: 999px;
  border: 0;
  background: var(--accent);
  color: #fff;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: .01em;
  cursor: pointer;
  transition: background-color .2s ease, transform .2s ease, box-shadow .2s ease;
}
.btn-red:hover {
  background: var(--accent-dark);
  transform: translateY(-1px);
  box-shadow: 0 10px 24px rgba(225, 37, 27, .28);
}

/* ---------- giant word with the photo clipped into the glyphs ----------
   Three layers share identical metrics so they register exactly:
   .ghost    -> transparent spacer that reserves the box
   ::before  -> extruded body (stacked outlines down-right) + soft drop shadow
   ::after   -> the photo, clipped to the letters
   The photo is only ever cropped/filtered by CSS — the source file is untouched. */
.ghost {
  position: relative;
  /* Block + fit-content + auto margins: the box is centred by LAYOUT, not by
     text-align, so a stray whitespace node can never shift it off-axis. */
  display: block;
  width: fit-content;
  margin-inline: auto;
  font-size: clamp(52px, 13.5vw, 190px);
  font-weight: 800;
  font-style: italic;
  line-height: .92;
  letter-spacing: .01em;
  text-transform: uppercase;
  color: transparent;
  user-select: none;
  pointer-events: none;
  white-space: nowrap;
  max-width: 100%;
  /* Optical centring: the italic lean plus the down-right 3D extrusion put the
     ink centroid ~0.1em right of the glyph box (measured on the render:
     971.3 vs 952.0 at 190px). Nudging the whole layer back by that amount
     makes the word read as centred; the box itself stays page-centred. */
  transform: translateX(-0.102em);
}
/* The word itself is drawn ONLY by the pseudo-elements (content: attr(data-text)).
   There is no text node inside the span, so a browser translator can never
   rewrite it — translating the page used to shrink the box from 604px to 384px
   and throw the word off-axis.
   ::before is in flow -> it gives the box its width.
   ::after is the photo layer on top. */
.ghost::before,
.ghost::after {
  content: attr(data-text);
  display: block;
  white-space: nowrap;
  text-align: inherit;
  pointer-events: none;
}
.ghost::before {
  color: #6d84a2;
  text-shadow:
    .012em .012em 0 #7b90ad,
    .024em .024em 0 #748aa8,
    .036em .036em 0 #6d84a2,
    .048em .048em 0 #667d9b,
    .06em .06em 0 #5f7694,
    .072em .072em 0 #586f8d,
    .084em .084em 0 #516886;
  filter: drop-shadow(0 .055em .08em rgba(16, 30, 54, .34));
}
.ghost::after {
  position: absolute;
  inset: 0;
  z-index: 1;
  /* NOTE: hard-coded here on purpose — a url() passed through a custom property
     from an inline style resolves against THIS stylesheet (css/…), which 404s. */
  background-image: url("../assets/pc-factory.jpg");
  background-repeat: no-repeat;
  background-size: cover;
  background-position: 50% 40%;
  /* lifts a flat phone shot without touching the source file */
  filter: saturate(1.22) contrast(1.10) brightness(1.02);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

/* =========================== ABOUT =========================== */
.about {
  background: #fff;
  padding: 86px 0 0;
  text-align: center;
  scroll-margin-top: var(--nav-h);
}
.about__inner {
  max-width: 900px;
  margin: 0 auto;
  padding: 0 24px;
}
.about__copy { margin-top: 36px; }
.about__line {
  margin: 0;
  font-size: 16px;
  line-height: 2;
  color: #4b5563;
}
.about__line:first-child { color: #111827; font-weight: 600; }
.about__inner .btn-red { margin-top: 34px; }

.stats {
  margin-top: 66px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 24px;
  padding: 52px 24px 60px;
  /* Uniform dot grid (original version, restored at user request):
     one 1.6px dot every 18px, reading as horizontal rows of dots. */
  background-image: radial-gradient(#e6e9ee 1.6px, transparent 1.6px);
  background-size: 18px 18px;
  background-position: center;
  background-repeat: repeat;
}
.stat { text-align: center; }
.stat__label {
  display: block;
  font-size: 15px;
  color: #6b7280;
}
.stat__value {
  display: block;
  margin-top: 8px;
  font-size: clamp(30px, 3.4vw, 46px);
  font-weight: 800;
  line-height: 1;
  color: var(--accent);
}
.stat__unit {
  font-style: normal;
  font-size: 14px;
  font-weight: 500;
  margin-left: 5px;
  color: #374151;
}

/* =========================== SOLUTIONS =========================== */
/* Split hero: copy on plain white, photograph in a frame of its own.
   Nothing here is glass, and nothing is full-bleed — a 1138px-wide source
   inside a contained column is only ever scaled down, so it stays sharp. */
.sol {
  background: #fff;
  scroll-margin-top: var(--nav-h);
  /* The reveal animation slides this block in from the right (translateX).
     Before it triggers, the offset sits outside the viewport and used to add
     ~32px of horizontal scroll on phones. Clipping the section keeps the
     slide-in effect while the page stays exactly as wide as the screen. */
  overflow: hidden;
}
.sol__inner {
  max-width: 1460px;
  margin: 0 auto;
  padding: 0 32px;
  display: grid;
  grid-template-columns: minmax(0, .86fr) minmax(0, 1.14fr);
  align-items: center;
  gap: 56px;
}
/* The copy column is set as a tight editorial block: a ruled kicker, a heavy
   two-line headline, one restrained deck, a spec-style category track and a
   single primary action with a quieter secondary one. */
.sol__copy { padding: 84px 0; }

.sol__eyebrow {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 0 0 20px;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--accent);
}
.sol__eyebrow i {
  flex: 0 0 auto;
  width: 30px;
  height: 2px;
  background: var(--accent);
}
.sol__title {
  margin: 0;
  font-size: clamp(30px, 3.9vw, 54px);
  font-weight: 800;
  line-height: 1.045;
  letter-spacing: -.028em;
  color: #111827;
  text-wrap: balance;
}
.sol__title span { display: block; }
.sol__sub {
  margin: 20px 0 0;
  max-width: 39ch;
  font-size: clamp(14.5px, 1.05vw, 15.5px);
  line-height: 1.74;
  color: #5b6779;
}

/* Category selector as a tab rail: four equal columns over one continuous
   hairline, the active tab carrying a red rule. Free-width labels broke 3+1 at
   1280 and left four rules of different lengths inside the row, so the columns
   are equal and each tab draws its own segment of the line. */
.sol__cats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin: 34px 0 0;
}
.sol__cat {
  min-width: 0;
  padding: 12px 6px 13px;
  border: 0;
  border-bottom: 1px solid #e9edf2;
  background: none;
  color: #6b7280;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: .01em;
  text-align: center;
  cursor: pointer;
  transition: color .2s ease, border-color .2s ease;
}
.sol__cat:hover {
  color: #111827;
  border-bottom-color: #c3cad5;
  box-shadow: inset 0 -1px 0 0 #c3cad5;
}
.sol__cat.is-active {
  color: #111827;
  border-bottom-color: var(--accent);
  /* second pixel of the rule, drawn without moving the label */
  box-shadow: inset 0 -1px 0 0 var(--accent);
}
.sol__cat:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.sol__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  margin-top: 38px;
}
/* squared CTAs to match the tab track, while the rest of the site keeps capsules */
.sol__actions .btn-red {
  min-width: 0;
  height: 50px;
  padding: 0 24px;
  gap: 10px;
  border-radius: 4px;
  letter-spacing: .005em;
  box-shadow: 0 10px 22px -10px rgba(225, 37, 27, .6);
}
.sol__ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  height: 50px;
  padding: 0 22px;
  border: 1px solid #d7dce4;
  border-radius: 4px;
  background: #fff;
  color: #16202c;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: .005em;
  transition: background-color .2s ease, border-color .2s ease, color .2s ease;
}
.sol__ghost:hover { background: #16202c; border-color: #16202c; color: #fff; }
.sol__arw {
  flex: 0 0 auto;
  transition: transform .26s cubic-bezier(.2, .6, .3, 1);
}
.sol__actions a:hover .sol__arw { transform: translateX(4px); }
.sol__ghost:focus-visible,
.sol__actions .btn-red:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* ---- the photograph: a contained frame that behaves like a short film ----
   1) slow push-in on the active shot (9s, scale 1 → 1.05) — the 1138px
      source is only ever downsampled, so the picture stays sharp;
   2) a fade-in-over cut: the incoming photo fades in ON TOP of the outgoing
      one, which stays at full opacity underneath. A true cross-fade would
      drop both to ~50% at the midpoint and let the pale frame background
      bleed through — that wash-out is what read as a harsh flick;
   Frame ratio is 16 / 9 on purpose: all four files are 1138x640, so a 4:3 box
   cropped a quarter of every picture sideways and read as a square. */
.sol__media {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: #eef1f5;
}

.sol__shot {
  position: absolute;
  inset: 0;
  z-index: 0;
  margin: 0;
  opacity: 0;
  transition: none;
}
/* the frame that is leaving keeps full opacity underneath, so the picture
   never goes half-transparent over the pale background */
.sol__shot.is-prev { z-index: 1; opacity: 1; }
.sol__shot.is-on {
  z-index: 2;
  opacity: 1;
  transition: opacity .95s cubic-bezier(.32, .06, .22, 1);
}
/* The push-in is a TRANSITION, not a keyframe animation: when a frame leaves
   mid-move the transform just carries on from wherever it had got to instead
   of snapping back to its start value. Amplitude stays at 5%, and shots
   1 and 3 drift the other way so consecutive frames never pulse in sync. */
.sol__shot img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1);
  transition: transform 9s linear;
  will-change: transform;
}
.sol__shot[data-i="1"] img,
.sol__shot[data-i="3"] img { transform: scale(1.05); }
.sol__shot.is-on img { transform: scale(1.05); }
.sol__shot[data-i="1"].is-on img,
.sol__shot[data-i="3"].is-on img { transform: scale(1); }

@media (prefers-reduced-motion: reduce) {
  .sol__shot.is-on { transition: none; }
  .sol__shot img { transition: none; transform: none; }
}

/* =========================== JOURNEY RAIL =========================== */
/* A year scale sitting between Solutions and the product centre: one hairline,
   a tick for every year, the years set beneath it. The rule spans the full
   column so it runs slightly past the first and last tick, the way the
   reference does. Nothing is emphasised except the two ends. */
.tl {
  background: #fff;
  padding: 36px 0 40px;
}
.tl__inner {
  max-width: 1460px;
  margin: 0 auto;
  padding: 0 32px;
}
.tl__rail {
  position: relative;
  display: grid;
  grid-auto-flow: column;
  /* minmax(0, 1fr): a 1fr track refuses to go below its content width, which
     made 24 four-digit labels push the rail past the viewport on phones */
  grid-auto-columns: minmax(0, 1fr);
  align-items: start;
}
.tl__track {
  position: absolute;
  left: 0;
  right: 0;
  top: 3px;
  height: 1px;
  background: #d5dce5;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 1.15s cubic-bezier(.22, .7, .25, 1);
}
.tl.is-in .tl__track { transform: scaleX(1); }

.tl__node {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 13px;
  opacity: 0;
  transform: translateY(-5px);
  transition: opacity .45s ease, transform .45s ease;
  transition-delay: calc(var(--i) * 32ms);
}
.tl.is-in .tl__node {
  opacity: 1;
  transform: none;
}
.tl__node i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #a9b3c1;
  transition: background-color .25s ease, box-shadow .25s ease;
}
.tl__node b {
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: .02em;
  font-variant-numeric: tabular-nums;
  color: #6f7b8c;
  transition: color .25s ease;
}

/* the two ends: founding year in red, today in ink */
.tl__node.is-first i {
  background: var(--accent);
  box-shadow: 0 0 0 3px rgba(225, 37, 27, .13);
}
.tl__node.is-first b { color: var(--accent); font-weight: 700; }
.tl__node.is-last i {
  background: #16202c;
  box-shadow: 0 0 0 3px rgba(22, 32, 44, .1);
}
.tl__node.is-last b { color: #16202c; font-weight: 700; }

.tl__node:hover i { background: #16202c; }
.tl__node:hover b { color: #16202c; }
.tl__node.is-first:hover i { background: var(--accent); }

@media (prefers-reduced-motion: reduce) {
  .tl__track,
  .tl__node { transition: none; }
  .tl__track { transform: scaleX(1); }
  .tl__node { opacity: 1; transform: none; }
}

/* narrower: the labels shrink first, then only the two ends keep a label */
@media (max-width: 900px) {
  .tl { padding: 38px 0 42px; }
  .tl__inner { padding: 0 18px; }
  .tl__node { gap: 11px; }
  .tl__node b { font-size: 10.5px; letter-spacing: 0; }
}

@media (max-width: 820px) {
  .tl__node b { display: none; }
  .tl__node.is-first b,
  .tl__node.is-last b { display: block; font-size: 11px; }
  .tl__node i { width: 5px; height: 5px; }
  .tl__track { top: 2px; }
}

/* =========================== PRODUCT CENTER =========================== */
.pc {
  background: #fff;
  padding: 92px 0 96px;
  scroll-margin-top: var(--nav-h);
}
.pc__inner {
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 24px;
}
.pc__title {
  margin: 0 0 48px;
  text-align: center;
  font-size: clamp(22px, 2.6vw, 34px);
  font-weight: 700;
  color: #111827;
  line-height: 1.3;
}
.pc__tabs {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 4px 32px;
  margin-bottom: 40px;
}
/* Text-only tabs. The old line-art pictograms read as generic "AI" symbols,
   so the category is carried by the label plus a single red rule. */
.pc__tab {
  position: relative;
  padding: 6px 0 12px;
  border: 0;
  background: none;
  color: #6b7280;
  font-family: inherit;
  font-size: 15px;
  font-weight: 500;
  letter-spacing: .01em;
  cursor: pointer;
  transition: color .2s ease;
}
.pc__tab::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: transparent;
  transition: background-color .2s ease;
}
.pc__tab:hover { color: #111827; }
.pc__tab.is-active { color: #111827; font-weight: 650; }
.pc__tab.is-active::after { background: var(--accent); }
.pc__tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }

.pc__slider {
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.pc__slider::-webkit-scrollbar { display: none; }
.pc__track { display: flex; gap: 24px; }
.pc__card {
  flex: 0 0 calc((100% - 72px) / 4);
  scroll-snap-align: start;
  display: block;
  color: inherit;
}
.pc__thumb {
  display: block;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: #f4f6f9;
}
.pc__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .5s ease;
}
.pc__card:hover .pc__thumb img { transform: scale(1.04); }
.pc__label {
  display: block;
  margin-top: 16px;
  font-size: 15px;
  font-weight: 600;
  color: #16202c;
}
.pc__card:hover .pc__label { color: var(--accent); }

.pc__bar {
  display: flex;
  align-items: center;
  gap: 28px;
  margin-top: 44px;
}
.pc__progress {
  position: relative;
  flex: 1;
  height: 2px;
  background: var(--hair);
}
.pc__progress-fill {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 12%;
  background: var(--accent);
  transition: width .35s ease;
}
.pc__arrows { display: flex; gap: 12px; }
.pc__arrow {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 1px solid #e2e6ec;
  border-radius: 50%;
  background: #fff;
  color: #6b7280;
  cursor: pointer;
  transition: background-color .2s, border-color .2s, color .2s;
}
.pc__arrow:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

/* =========================== TRIO CARDS =========================== */
.trio {
  background: #fff;
  padding: 0 0 96px;
  scroll-margin-top: var(--nav-h);
}
.trio__inner {
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 24px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
.trio__card {
  position: relative;
  display: block;
  min-height: 430px;
  overflow: hidden;
  color: #fff;
  background: #0d1218;
}
.trio__bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  transition: transform .6s ease;
}
.trio__card:hover .trio__bg { transform: scale(1.05); }
.trio__card--dark .trio__bg { opacity: .28; }
.trio__shade {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(8, 12, 18, .82), rgba(8, 12, 18, .3) 46%, rgba(8, 12, 18, .78));
}
.trio__body {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 34px 30px;
}
.trio__title { font-size: 22px; font-weight: 700; }
.trio__text {
  font-size: 14.5px;
  line-height: 1.78;
  color: rgba(255, 255, 255, .86);
  max-width: 34ch;
}

/* =========================== CERTIFICATES (open book) =========================== */
.certs {
  background: #f6f7f9;
  padding: 92px 0 96px;
  scroll-margin-top: var(--nav-h);
}
.certs__inner {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 24px;
  text-align: center;
}
.certs__title {
  margin: 0 0 14px;
  font-size: clamp(24px, 2.8vw, 36px);
  font-weight: 700;
  line-height: 1.25;
  color: #111827;
}
.certs__intro {
  margin: 0 auto 46px;
  max-width: 660px;
  font-size: 15px;
  line-height: 1.7;
  color: #5a6675;
}

.book { max-width: 1000px; margin: 0 auto; outline: none; }
.book:focus-visible .book__stage { outline: 2px solid var(--accent); outline-offset: 8px; }

.book__stage {
  position: relative;
  display: grid;
  perspective: 2400px;
}

/* ---- the book itself: a cover board with the two sheets bound into it ---- */
.book__cover {
  position: relative;
  padding: 16px 18px;
  border-radius: 8px;
  /* the turning sheet is a DIRECT child, so this perspective is what gives
     its rotateY real foreshortening — without it the flip renders as a flat
     horizontal squeeze, which is why the turn read as stiff */
  perspective: 2200px;
  /* warm paper board — a certificate binder, not a black box, so the
     colourful documents keep their presence */
  background:
    linear-gradient(90deg, rgba(140, 122, 92, 0) 46%, rgba(140, 122, 92, .26) 50%, rgba(140, 122, 92, 0) 54%),
    linear-gradient(180deg, #f5f0e6, #eae3d4);
  box-shadow:
    inset 0 0 0 1px rgba(120, 104, 78, .12),
    0 26px 52px rgba(90, 76, 56, .18);
}
/* fore-edges: the cut ends of the sheet stack sticking out on both sides */
.book__cover::before,
.book__cover::after {
  content: "";
  position: absolute;
  top: 14px;
  bottom: 14px;
  width: 7px;
  border-radius: 3px;
  background: repeating-linear-gradient(180deg, #ffffff 0 2px, #dde3ec 2px 4px);
  box-shadow: 0 0 0 1px rgba(12, 20, 34, .14);
  pointer-events: none;
}
.book__cover::before { left: -7px; }
.book__cover::after { right: -7px; }

.book__spread {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 34px;
  align-items: start;
}

/* each page is a sheet of paper: white board around the document */
.book__page { margin: 0; min-width: 0; cursor: pointer; }
.book__page--blank { cursor: default; }
.book__page img {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1.414;
  object-fit: contain;
  background: #fff;
  box-shadow: 0 16px 34px rgba(16, 26, 44, .16);
  transition: box-shadow .25s ease;
}
.book__page:not(.book__page--blank):hover {
  box-shadow: 0 20px 40px rgba(8, 14, 26, .38);
}
.book__page--blank {
  aspect-ratio: 1 / 1.414;
  background: transparent;
}
.book__page:not(.book__page--blank) {
  padding: 14px 14px 0;
  border: 1px solid rgba(120, 104, 78, .16);
  border-radius: 2px;
  background: #fff;
  box-shadow: 0 14px 30px rgba(80, 68, 50, .22);
}
.book__page:not(.book__page--blank) img {
  border: 1px solid #eceff4;
  box-shadow: none;
}
.book__page:not(.book__page--blank) .book__cap { padding: 14px 2px 18px; }
.book__ph {
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: 1 / 1.414;
  background: #fff;
  box-shadow: 0 16px 34px rgba(16, 26, 44, .10);
  font-size: 13px;
  line-height: 1.7;
  color: #9aa4b2;
  text-align: center;
}

.book__cap { padding-top: 16px; text-align: left; }
.book__cap strong {
  display: block;
  font-size: 16px;
  font-weight: 700;
  line-height: 1.35;
  color: #111827;
}
.book__issuer {
  display: block;
  margin-top: 5px;
  font-size: 13px;
  color: #6b7280;
}
.book__cap p {
  margin: 9px 0 0;
  font-size: 13.5px;
  line-height: 1.65;
  color: #5a6675;
}

.book__bar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
  margin-top: 30px;
}
.book__nav {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border: 1px solid #d8dee8;
  border-radius: 50%;
  background: #fff;
  color: #16202c;
  cursor: pointer;
  transition: border-color .2s ease, color .2s ease, opacity .2s ease;
}
.book__nav:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.book__nav:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.book__nav:disabled { opacity: .3; cursor: default; }
.book__count {
  font-size: 14px;
  color: #6b7280;
  font-variant-numeric: tabular-nums;
}
.book__count b { color: #111827; font-weight: 600; }

/* ---- the sheet in flight: one page crosses the gutter ---- */
.book__turn {
  position: absolute;
  top: 0;
  left: calc(50% + 17px);
  right: 0;
  z-index: 6;
  transform-origin: left center;
  transform-style: preserve-3d;
  backface-visibility: hidden;
  pointer-events: none;
  will-change: transform;
}
.book__turn::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, rgba(120, 104, 78, .26), rgba(120, 104, 78, 0) 55%);
  opacity: 0;
  pointer-events: none;
}
.book__turn--next { animation: sheetNext .95s cubic-bezier(.45, .05, .55, .95) forwards; }
.book__turn--prev { animation: sheetPrev .95s cubic-bezier(.45, .05, .55, .95) forwards; }
.book__turn--next::after { animation: sheetShade .95s ease-in-out forwards; }
.book__turn--prev::after { animation: sheetShade .95s ease-in-out reverse forwards; }

@keyframes sheetNext {
  0%   { transform: rotateY(0deg)    translateZ(0); }
  50%  { transform: rotateY(-94deg)  translateZ(34px); }
  100% { transform: rotateY(-180deg) translateZ(0); }
}
@keyframes sheetPrev {
  0%   { transform: rotateY(-180deg) translateZ(0); }
  50%  { transform: rotateY(-86deg)  translateZ(34px); }
  100% { transform: rotateY(0deg)    translateZ(0); }
}
/* light sweeping across the moving page */
@keyframes sheetShade {
  0%   { opacity: 0; }
  55%  { opacity: .55; }
  100% { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .book__turn { display: none; }
}

/* =========================== NEWS =========================== */
/* Non-home pages open with their lead section flush at the top of the
   document, where the fixed bar sits — give that section the bar's height
   plus breathing room so labels, dates and headings never slide beneath it. */
body[data-page="news"] .news,
body[data-page="contact"] .cta,
body[data-page="about"] .about {
  padding-top: calc(var(--nav-h) + 34px);
}
.news {
  position: relative;
  overflow: hidden;
  background: #fff;
  padding: 86px 0 96px;
  scroll-margin-top: var(--nav-h);
}
.news::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 32%;
  background-image: radial-gradient(rgba(225, 37, 27, .17) 1.4px, transparent 1.4px);
  background-size: 16px 16px;
  pointer-events: none;
}
.news__inner {
  position: relative;
  z-index: 1;
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 24px;
  display: grid;
  grid-template-columns: 300px 1fr;
  gap: 72px;
}
.news__side { text-align: left; }
.news__heading {
  margin: 0 0 34px;
  font-size: clamp(24px, 2.6vw, 32px);
  font-weight: 800;
  color: #111827;
  line-height: 1.3;
}
.news__list { display: flex; flex-direction: column; }
.news__item { padding: 26px 0; border-bottom: 1px solid var(--hair); }
.news__item:first-child { padding-top: 0; }
.news__item:last-child { border-bottom: 0; padding-bottom: 0; }
.news__date { font-size: 14px; color: #6b7280; }
.news__title {
  margin: 10px 0 12px;
  font-size: 19px;
  font-weight: 600;
  color: #111827;
  line-height: 1.45;
}
.news__excerpt {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.8;
  color: #5b6675;
}

/* =========================== CONTACT STRIP =========================== */
/* Plain pale panel, no photograph behind it: the strip closes the page in the
   same light key as the footer, so the two read as one quiet ending instead of
   a dark band sitting on top of a dark footer. */
.cta {
  position: relative;
  background: #f4f6f8;
  color: #111827;
  padding: 66px 0 62px;
  scroll-margin-top: var(--nav-h);
}
.cta__inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 24px;
}
.cta__title {
  margin: 0 0 14px;
  font-size: clamp(24px, 3vw, 36px);
  font-weight: 700;
  letter-spacing: -.015em;
  color: #111827;
}
.cta__sub {
  margin: 0 0 40px;
  max-width: 720px;
  font-size: 15px;
  line-height: 1.75;
  color: #5a6675;
}
.cta__form {
  display: grid;
  grid-template-columns: .9fr .9fr 1.5fr auto;
  align-items: center;
  padding: 8px 8px 8px 26px;
  border: 1px solid #e1e6ee;
  border-radius: 999px;
  background: #fff;
  box-shadow: 0 2px 12px rgba(17, 24, 39, .05);
  transition: border-color .2s ease, box-shadow .2s ease;
}
.cta__form:focus-within {
  border-color: #c9d1dd;
  box-shadow: 0 4px 18px rgba(17, 24, 39, .08);
}
.cta__field {
  min-width: 0;
  padding: 13px 18px;
  border: 0;
  border-right: 1px solid #e6e9ee;
  background: transparent;
  color: #111827;
  font-family: inherit;
  font-size: 15px;
  outline: none;
}
.cta__field::placeholder { color: #9aa4b2; }
.cta__field--area {
  resize: none;
  min-height: 50px;
  max-height: 200px;
  line-height: 1.5;
  padding-top: 14px;
  overflow-y: auto;
}
.cta__send {
  height: 46px;
  margin-left: 8px;
  padding: 0 34px;
  border: 0;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-family: inherit;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition: background-color .2s ease;
}
.cta__send:hover { background: var(--accent-dark); }
.cta__note {
  margin: 16px 0 0;
  font-size: 13.5px;
  color: #5a6675;
}
/* the status line should not reserve a gap until there is something to say */
.cta__note:empty { margin: 0; }
.cta__note.is-warn { color: #c02418; }

/* =========================== FOOTER =========================== */
/* Modelled on the EKO domestic footer: brand, three link columns, a flag grid
   of markets and a QR / hotline block, with hairlines between the groups and a
   centred social row above the notice. Type is deliberately larger than a
   typical footer — the reference reads at 14–15px, not 12. */
.foot {
  background: #fff;
  color: #4b5563;
  border-top: 1px solid #eef1f5;
}
.foot__inner {
  max-width: 1380px;
  margin: 0 auto;
  padding: 54px 32px 42px;
  display: grid;
  /* brand runs across the top, the three groups sit beneath it so the link
     columns never have to squeeze "Small Animal Cages" onto two lines */
  /* the link columns only need ~170px each; the freed width goes to the flag
     grid so each cloth is as dominant inside its cell as the reference */
  grid-template-columns: 540px minmax(0, 1fr) 250px;
  row-gap: 34px;
  column-gap: 0;
}
.foot__brand { grid-column: 1 / -1; }
.foot__company {
  margin: 0 0 14px;
  font-size: 19px;
  font-weight: 700;
  line-height: 1.42;
  letter-spacing: -.01em;
  color: #111827;
  text-wrap: balance;
}
.foot__tagline {
  margin: 0;
  max-width: 72ch;
  font-size: 14px;
  line-height: 1.72;
  color: #5a6675;
}

/* ---- three link columns ----
   The column titles ("Products" / "Solutions" / "Company") and the block under
   them are centred inside their own column, so every heading in the footer
   nav sits on the centre line of its column. */
.foot__nav {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 22px;
  padding-right: 16px;
  text-align: center;
}
.foot__title {
  margin: 0 0 18px;
  font-size: 15px;
  font-weight: 700;
  line-height: 1.3;
  color: #111827;
}
.foot__links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 11px;
  font-size: 14.5px;
  line-height: 1.45;
}
.foot__links a { color: #5a6675; transition: color .2s ease; }
.foot__links a:hover { color: var(--accent); }

/* ---- markets: big flags over their names, three across ---- */
.foot__mk {
  padding: 0 30px;
  border-left: 1px solid #eef1f5;
  text-align: center;
}
.foot__markets {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  /* an even 3x2 grid; every cloth sits in the middle of its own cell */
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 34px 24px;
}
.foot__markets li {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 11px;
  text-align: center;
}
.foot__flagwrap {
  position: relative;
  display: block;
  width: 96px;
  height: 63px;   /* the supplied PNGs are all 170x112 (≈1.52) — same cell */
  border-radius: 2px;
  overflow: hidden;
  box-shadow: 0 1px 4px rgba(17, 24, 39, .25);
}
/* the user-supplied cloths already carry their own sheen — no extra overlay */
/* fill, not contain: the artwork (1.518) and the cell (1.524) differ by four
   tenths of a percent, so filling leaves no visible distortion and can never
   show a letterbox stripe at either side */
.foot__flagwrap img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: fill;
}
.foot__mk-name {
  font-size: 12px;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: #4b5563;
}

/* ---- QR pair + hotline + address ---- */
.foot__aside {
  padding-left: 30px;
  border-left: 1px solid #eef1f5;
}
.foot__qrs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
.foot__qr { margin: 0; text-align: center; }
.foot__qr img {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  padding: 5px;
  border: 1px solid #eef1f5;
  border-radius: 4px;
  background: #fff;
}
.foot__qr figcaption {
  margin-top: 8px;
  font-size: 13px;
  line-height: 1.35;
  color: #5a6675;
}
.foot__info {
  list-style: none;
  margin: 18px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.foot__info li,
.foot__info a {
  display: flex;
  align-items: flex-start;
  gap: 9px;
}
.foot__info a:hover span { color: var(--accent); }
.foot__ico { flex: none; margin-top: 1px; color: #9aa4b2; }
.foot__info i {
  display: block;
  margin-bottom: 3px;
  font-size: 11.5px;
  font-style: normal;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #98a2b3;
}
.foot__info span {
  display: block;
  font-size: 13.5px;
  line-height: 1.65;
  color: #374151;
  word-break: break-word;
  transition: color .2s ease;
}

/* ---- centred social row + notice ---- */
.foot__bar {
  border-top: 1px solid #eef1f5;
  padding: 26px 32px;
  text-align: center;
}
.foot__social {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin-bottom: 16px;
}
.foot__soc {
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: #f1f4f8;
  color: #4b5563;
  transition: background-color .2s ease, color .2s ease, transform .2s ease;
}
.foot__soc:hover {
  background: var(--accent);
  color: #fff;
  transform: translateY(-1px);
}
/* WeChat has no "add friend" web URL — the icon is a button that pops the QR
   up above it so the visitor scans it with their phone instead. */
.foot__qrwrap { position: relative; display: inline-grid; }
.foot__soc[aria-expanded] { cursor: pointer; border: 0; font-family: inherit; }
.foot__qrpop {
  position: absolute;
  bottom: calc(100% + 12px);
  left: 50%;
  transform: translateX(-50%) translateY(6px);
  width: 190px;
  padding: 12px 12px 10px;
  border: 1px solid #eef1f5;
  border-radius: 10px;
  background: #fff;
  box-shadow: 0 16px 40px rgba(10, 18, 30, .18);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .2s ease, transform .2s ease, visibility .2s;
  text-align: center;
  z-index: 6;
}
.foot__qrwrap.is-open .foot__qrpop {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateX(-50%) translateY(0);
}
.foot__qrpop img {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  padding: 5px;
  border: 1px solid #eef1f5;
  border-radius: 4px;
  background: #fff;
}
.foot__qrpop b {
  display: block;
  margin-top: 8px;
  font-size: 12.5px;
  line-height: 1.4;
  color: #374151;
}
.foot__bar p {
  margin: 0;
  font-size: 13px;
  line-height: 1.6;
  color: #8b95a3;
}

/* ---- scroll entrance: one-shot horizontal slide (classes added by main.js) ----
   Blocks slide in from the left, alternating with a right-side entrance
   (.rv--r), so the page feels like it assembles from both sides. */
/* Direction is picked per block in js/main.js (side copy slides in from its own
   side, wide bands fade straight up, card clusters ease in with a hair of
   scale) — not "everything slides left/right". Only opacity and transform
   animate, both compositor-only, so a 1200px grid can move without repainting.
   will-change is set here and dropped by JS once the block has landed, so the
   browser stops holding a layer for every section. */
.rv {
  opacity: 0;
  transform: translate3d(0, 18px, 0);
  transition: opacity .58s ease, transform .66s cubic-bezier(.22, .61, .36, 1);
  will-change: opacity, transform;
}
.rv--l { transform: translate3d(-32px, 0, 0); }
.rv--r { transform: translate3d(32px, 0, 0); }
.rv--z { transform: scale(.975); }
.rv--f { transform: none; }
.rv.is-in {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  .rv,
  .rv--l,
  .rv--r,
  .rv--z,
  .rv--f {
    opacity: 1;
    transform: none;
    transition: none;
    will-change: auto;
  }
}

/* Row-by-row entrance for lists that read as a column of articles: each row
   arrives from alternating sides, 70ms behind the previous one, so the block
   assembles line by line instead of fading in as one slab. */
.rv-item {
  opacity: 0;
  transform: translate3d(-32px, 0, 0);
  transition: opacity .55s ease, transform .62s cubic-bezier(.22, .61, .36, 1);
  transition-delay: calc(var(--i, 0) * 90ms);
  will-change: opacity, transform;
}
.rv-item--r { transform: translate3d(32px, 0, 0); }
.rv-item.is-in {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  .rv-item,
  .rv-item--r {
    opacity: 1;
    transform: none;
    transition: none;
    will-change: auto;
  }
}

/* =========================== SIDE RAIL =========================== */
.rail {
  position: fixed;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  z-index: 900;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.rail__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 64px;
  padding: 12px 6px;
  border: 0;
  background: var(--accent);
  color: #fff;
  font-family: inherit;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: .01em;
  text-align: center;
  cursor: pointer;
  transition: background-color .2s ease;
}
.rail__item:hover { background: var(--accent-dark); }
.rail__item:focus-visible { outline: 2px solid #fff; outline-offset: -4px; }

/* --- WeChat QR popover (opens to the left of the rail) --- */
.rail__qr-wrap { position: relative; }
.rail__qr {
  position: absolute;
  right: calc(100% + 12px);
  top: 50%;
  transform: translateY(-50%) translateX(6px);
  width: 208px;
  padding: 12px 12px 10px;
  background: #fff;
  border: 1px solid #e5e8ee;
  border-radius: 6px;
  box-shadow: 0 16px 40px rgba(10, 18, 30, .18);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .2s ease, transform .2s ease, visibility .2s;
}
.rail__qr-wrap.is-open .rail__qr,
.rail__qr-wrap:hover .rail__qr {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateY(-50%) translateX(0);
}
.rail__qr img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 4px;
}
.rail__qr p {
  margin: 8px 0 0;
  font-size: 12.5px;
  line-height: 1.4;
  color: #55606d;
  text-align: center;
}

/* =========================== RESPONSIVE =========================== */
@media (max-width: 1320px) {
  /* the four blocks stop fitting on one line — brand and the link columns take
     full rows, markets and the QR block share the row beneath them */
  .foot__inner {
    grid-template-columns: minmax(0, 1fr) 250px;
    row-gap: 38px;
  }
  .foot__brand,
  .foot__nav { grid-column: 1 / -1; }
  .foot__nav { padding-right: 0; }
  .foot__mk { border-left: 0; padding-left: 0; padding-right: 30px; }
  .foot__aside { padding-left: 30px; }
}

@media (max-width: 1366px) {
  /* the longest label measures 121px in a 125px column — no side padding left */
  .sol__cat { padding-left: 0; padding-right: 0; font-size: 12.5px; }
  /* at 54px the second headline line ran to 540px, which broke it into three
     rows once the column narrowed — 3.6vw keeps it on two rows down to 1024 */
  .sol__title { font-size: clamp(28px, 3.6vw, 47px); }
}

@media (max-width: 1240px) {
  /* four columns get too tight for "Small Animal Cages" below this width */
  .sol__cats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .sol__cat { font-size: 13px; }
}

@media (max-width: 1100px) {
  /* 227 + 217 will not sit side by side in a 389px column, and squeezing the
     type made a label wrap inside its own button — stack them, left aligned */
  .sol__actions {
    display: grid;
    grid-template-columns: 1fr;
    justify-items: start;
    gap: 10px;
  }
  .sol__actions .btn-red,
  .sol__ghost { height: 46px; padding: 0 18px; font-size: 14px; }

  .pc__card { flex: 0 0 calc((100% - 48px) / 3); }
  .news__inner { grid-template-columns: 240px 1fr; gap: 44px; }
  .foot__inner { padding: 46px 28px 36px; }
}

@media (max-width: 900px) {
  .about { padding-top: 64px; }
  .about__copy { margin-top: 26px; }
  .about__line { font-size: 15px; line-height: 1.95; }
  .stats { grid-template-columns: repeat(2, 1fr); gap: 30px 18px; margin-top: 46px; padding: 40px 18px 46px; }

  .sol__inner { grid-template-columns: 1fr; gap: 0; padding: 0 18px; }
  .sol__copy { padding: 64px 0 34px; }
  .sol__title { font-size: 30px; }
  .sol__sub { margin-top: 14px; font-size: 15px; }
  .sol__cats { margin-top: 26px; }
  .sol__cat { padding: 10px 4px 11px; font-size: 12.5px; }
  .sol__actions { gap: 10px; margin-top: 26px; grid-template-columns: 1fr; justify-items: stretch; }
  .sol__actions .btn-red,
  .sol__ghost { font-size: 14.5px; padding: 0 18px; }
  .sol__media { aspect-ratio: 16 / 9; margin-bottom: 64px; }

  .pc { padding: 68px 0 72px; }
  /* text tabs wrap into two centred rows on phones */
  .pc__tabs {
    gap: 2px 20px;
    margin-bottom: 24px;
  }
  .pc__tab { padding: 5px 0 10px; font-size: 13.5px; }
  .pc__card { flex: 0 0 calc((100% - 24px) / 2); }
  .pc__bar { margin-top: 30px; gap: 18px; }

  .trio__inner { grid-template-columns: 1fr; gap: 10px; }
  .trio__card { min-height: 260px; }
  .trio__body { padding: 26px 22px; }

  .certs { padding: 64px 0 72px; }
  .certs__intro { margin-bottom: 30px; font-size: 14.5px; }
  /* one page per row on phones — two A4 sheets side by side would be unreadable */
  .book__spread { grid-template-columns: 1fr; gap: 26px; }
  .book__cover::before,
  .book__cover::after { display: none; }
  .book__turn { display: none; }   /* 3D turn needs the two-column spread */
  .book__cap strong { font-size: 15.5px; }
  .book__cap p { font-size: 13px; }

  .news { padding: 64px 0 70px; }
  .news::before { width: 100%; opacity: .5; }
  .news__inner { grid-template-columns: 1fr; gap: 34px; }
  .news__heading { margin-bottom: 22px; }

  .cta { padding: 62px 0 70px; }
  .cta__form {
    grid-template-columns: 1fr;
    gap: 0;
    padding: 14px;
    border-radius: 18px;
  }
  .cta__field {
    border-right: 0;
    border-bottom: 1px solid rgba(255, 255, 255, .16);
    padding: 14px 6px;
  }
  .cta__field--area { height: 74px; }
  .cta__send { margin: 14px 0 0; width: 100%; }

  .foot__inner { padding: 42px 20px 32px; }
  .foot__company { font-size: 18px; }

  /* compact rail on phones: Message + Top (a QR is useless on the device
     you would have to scan it with) */
  .rail__item { width: 46px; padding: 9px 3px; gap: 4px; font-size: 10px; }
  .rail__qr-wrap { display: none; }
}

/* phones: everything stacks, last so it wins over the 900 block */
@media (max-width: 640px) {
  .foot__inner { grid-template-columns: minmax(0, 1fr); row-gap: 30px; }
  .foot__brand,
  .foot__nav,
  .foot__mk,
  .foot__aside { grid-column: 1 / -1; }
  .foot__mk { padding-right: 0; }
  .foot__aside {
    padding: 28px 0 0;
    border-left: 0;
    border-top: 1px solid #eef1f5;
  }
  .foot__markets { gap: 24px 18px; }
  .foot__flagwrap { width: 84px; height: 55px; }
  .foot__mk-name { font-size: 12px; }
}
