/* =========================================================================
   Riya Connect Landing — LAYER 3: RESET, COMPONENTS, MOTION, RESPONSIVE
   -------------------------------------------------------------------------
   Load last:

     rc-brand-tokens.css   Layer 1 — the brand theme
     rc-land-tokens.css    Layer 2 — what the brand means on this page
     rc-land-components.css        — this file

   Standing rules for anything added here:

   1. No literal colours, type sizes, spacings, radii, shadows, durations or
      easings. Every one is a var(--…) from Layer 2. The only numbers
      allowed raw are ratios and counts (grid fractions, nth-child indices,
      z-index-free stacking order).
   2. A page ships no `style=` attribute, no `<style>` block and no inline
      `<script>`. Interactive state that CSS can hold is held by a form
      control — the mobile navigation is a `:checked` checkbox — and
      everything else arrives as a class from rc-land.js.
   3. Re-theme by overriding a token, never by editing a rule below.
   4. The responsive block at the end changes STRUCTURE only. Anything
      dimensional is a token override in Layer 2.

   Contents
     01  Reset and base
     02  Utilities
     03  Motion system
     04  Buttons, eyebrows, pills, icons
     05  Header and navigation
     06  Hero
     07  Section primitives
     08  What we offer
     09  Technology
     10  Business insight and the product preview
     11  About
     12  Partner call to action
     13  Contact
     14  Footer
     15  Responsive — structure
     16  Reduced motion
   ========================================================================= */


/* =========================================================================
   01  RESET AND BASE
   ========================================================================= */

*,
*::before,
*::after { box-sizing: border-box; }

html {
  /* `clip`, never `hidden`: overflow-x:hidden on <html> silently kills
     position:sticky for every descendant, and the header is sticky. */
  overflow-x: clip;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + var(--sp-3));
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--c-canvas);
  color: var(--c-ink-body);
  font-family: var(--font-body);
  font-size: var(--fs-lead);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5, p, figure, dl, dd { margin: 0; }

ul, ol { margin: 0; padding: 0; list-style: none; }

img, svg { display: block; max-width: 100%; }
img { height: auto; }

a {
  color: var(--c-accent-ink);
  text-decoration: none;
  transition: color var(--dur-hover) var(--ease-hover);
}
a:hover { color: var(--c-accent-strong); }

button, input, select, textarea {
  font: inherit;
  color: inherit;
}
button { cursor: pointer; }

strong { font-weight: var(--fw-semibold); color: var(--c-ink); }

:focus-visible {
  outline: var(--focus-width) solid var(--focus-color);
  outline-offset: var(--focus-offset);
  border-radius: var(--r-xs);
}


/* =========================================================================
   02  UTILITIES
   ========================================================================= */

/* The content column. Every band's inner element carries it, so the page
   has exactly one gutter measurement. */
.rc-wrap {
  width: 100%;
  max-width: var(--wrap-max);
  margin-inline: auto;
  padding-inline: var(--wrap-pad);
}
.rc-wrap--text { max-width: var(--wrap-max-text); }

/* Clipped to 1px but still in the tab order and the accessibility tree.
   Use it only where a control needs a real label the design has no room
   for — never to hide something sighted users should see. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* The first thing in the tab order. Invisible until focused. */
.rc-skip {
  position: absolute;
  top: var(--sp-2);
  left: var(--sp-2);
  z-index: calc(var(--z-nav) + 1);
  padding: var(--sp-3) var(--sp-5);
  background: var(--c-accent);
  color: var(--c-on-brand);
  border-radius: var(--r-sm);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  transform: translateY(calc(-100% - var(--sp-4)));
  transition: transform var(--dur-nav) var(--ease-nav);
}
.rc-skip:focus-visible {
  transform: none;
  color: var(--c-on-brand);
}


/* =========================================================================
   03  MOTION SYSTEM
   -------------------------------------------------------------------------
   Two mechanisms and no third.

   .rc-enter  plays once on first paint, in source order, for the hero only.
              It is pure CSS, so it survives a failed script.
   .rc-reveal plays when the block scrolls into view. It needs a script to
              add .is-in, so it is armed only once rc-land-boot.js has taken
              `no-js` off <html>. Without a script every .rc-reveal block
              simply renders — the page is never blank.

   Both travel by the same token (--enter-lift / --reveal-shift) so nothing
   on the page arrives from a height of its own choosing.
   ========================================================================= */

@keyframes rc-enter-up {
  from { opacity: 0; transform: translateY(var(--enter-lift)); }
  to   { opacity: 1; transform: none; }
}

@keyframes rc-enter-art {
  from { opacity: 0; transform: translateY(var(--enter-lift-art)) scale(0.985); }
  to   { opacity: 1; transform: none; }
}

.rc-enter {
  animation: rc-enter-up var(--dur-enter) var(--ease-out) both;
  animation-delay: var(--enter-base);
}
.rc-enter--2 { animation-delay: calc(var(--enter-base) + 1 * var(--enter-step)); }
.rc-enter--3 { animation-delay: calc(var(--enter-base) + 2 * var(--enter-step)); }
.rc-enter--4 { animation-delay: calc(var(--enter-base) + 3 * var(--enter-step)); }
.rc-enter--5 { animation-delay: calc(var(--enter-base) + 4 * var(--enter-step)); }

.rc-enter--art {
  animation-name: rc-enter-art;
  animation-duration: calc(var(--dur-enter) + var(--t-mid));
  animation-delay: var(--enter-art-delay);
}

html:not(.no-js) .rc-reveal {
  opacity: 0;
  transform: translateY(var(--reveal-shift));
  transition:
    opacity   var(--dur-reveal) var(--ease-reveal),
    transform var(--dur-reveal) var(--ease-reveal);
}
html:not(.no-js) .rc-reveal.is-in {
  opacity: 1;
  transform: none;
}

.rc-reveal--d1 { transition-delay: calc(1 * var(--reveal-step)); }
.rc-reveal--d2 { transition-delay: calc(2 * var(--reveal-step)); }
.rc-reveal--d3 { transition-delay: calc(3 * var(--reveal-step)); }
.rc-reveal--d4 { transition-delay: calc(4 * var(--reveal-step)); }

/* A cascade over a block's own children, so a six-card grid needs one
   class on the grid rather than six on the cards. */
html:not(.no-js) .rc-reveal--cascade > * {
  opacity: 0;
  transform: translateY(var(--reveal-shift));
  transition:
    opacity   var(--dur-reveal) var(--ease-reveal),
    transform var(--dur-reveal) var(--ease-reveal);
}
html:not(.no-js) .rc-reveal--cascade.is-in > * { opacity: 1; transform: none; }
.rc-reveal--cascade.is-in > *:nth-child(1) { transition-delay: calc(0 * var(--reveal-step)); }
.rc-reveal--cascade.is-in > *:nth-child(2) { transition-delay: calc(1 * var(--reveal-step)); }
.rc-reveal--cascade.is-in > *:nth-child(3) { transition-delay: calc(2 * var(--reveal-step)); }
.rc-reveal--cascade.is-in > *:nth-child(4) { transition-delay: calc(3 * var(--reveal-step)); }
.rc-reveal--cascade.is-in > *:nth-child(5) { transition-delay: calc(4 * var(--reveal-step)); }
.rc-reveal--cascade.is-in > *:nth-child(6) { transition-delay: calc(5 * var(--reveal-step)); }

@keyframes rc-float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(calc(-1 * var(--float-rise))); }
}

@keyframes rc-ping {
  0%        { transform: scale(1);   opacity: 0.5; }
  70%, 100% { transform: scale(2.6); opacity: 0; }
}


/* =========================================================================
   04  BUTTONS, EYEBROWS, PILLS, ICONS
   ========================================================================= */

.rc-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-3);
  min-height: var(--control-h);
  padding-inline: var(--btn-px);
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  background: none;
  font-family: var(--font-sans);
  font-size: var(--fs-cta);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-cta);
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
  transition:
    background-color var(--dur-hover) var(--ease-hover),
    border-color     var(--dur-hover) var(--ease-hover),
    color            var(--dur-hover) var(--ease-hover),
    box-shadow       var(--dur-hover) var(--ease-hover),
    transform        var(--dur-hover) var(--ease-hover);
}

.rc-btn--primary {
  background: var(--c-accent);
  color: var(--c-on-brand);
  box-shadow: var(--shadow-brand);
}
.rc-btn--primary:hover,
.rc-btn--primary:focus-visible {
  background: var(--c-accent-strong);
  color: var(--c-on-brand);
  box-shadow: var(--shadow-brand-lift);
}
.rc-btn--primary:active { transform: translateY(1px); }

.rc-btn--outline {
  border-color: var(--c-accent);
  background: var(--c-surface);
  color: var(--c-accent-ink);
}
.rc-btn--outline:hover,
.rc-btn--outline:focus-visible {
  background: var(--c-accent-tint);
  color: var(--c-accent-strong);
}

.rc-btn--ghost {
  border-color: var(--c-line-firm);
  background: var(--c-surface);
  color: var(--c-ink);
}
.rc-btn--ghost:hover,
.rc-btn--ghost:focus-visible {
  border-color: var(--c-accent);
  color: var(--c-accent-ink);
}

.rc-btn--sm  { min-height: var(--control-h-sm); padding-inline: clamp(var(--sp-3), 1.5vw, var(--btn-px)); font-size: var(--fs-cta-sm); }
.rc-btn--lg  { min-height: var(--control-h-lg); padding-inline: var(--btn-px-lg); }
.rc-btn--pill { border-radius: var(--r-pill); }
.rc-btn--block { width: 100%; }

.rc-btn__arrow {
  flex: none;
  width: 18px;
  height: 12px;
  transition: transform var(--dur-hover) var(--ease-hover);
}
/* Direct child only: in the pill CTA the arrow sits inside .rc-btn__disc,
   and it is the disc that travels. Both moving would double the shift. */
.rc-btn:hover > .rc-btn__arrow,
.rc-btn:focus-visible > .rc-btn__arrow { transform: translateX(var(--shift-arrow)); }

/* The arrow inside a translucent disc, for the two pill CTAs in the
   closing band. The disc is part of the button, not an icon of its own. */
.rc-btn__disc {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 26px;
  height: 26px;
  border-radius: var(--r-circle);
  background: rgba(255, 255, 255, 0.2);
  transition: transform var(--dur-hover) var(--ease-hover);
}
.rc-btn:hover > .rc-btn__disc,
.rc-btn:focus-visible > .rc-btn__disc { transform: translateX(var(--shift-arrow)); }

/* ---- eyebrow ------------------------------------------------------------
   The all-caps kicker above a headline. Written in sentence case in the
   markup; text-transform does the capitals. */
.rc-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  align-self: flex-start;
  padding: var(--sp-2) var(--sp-4);
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  background: var(--c-accent-tint);
  color: var(--c-accent-ink);
  font-family: var(--font-sans);
  font-size: var(--fs-eyebrow);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-caps);
  line-height: 1.4;
  text-transform: uppercase;
}
.rc-eyebrow--gold {
  border-color: var(--c-premium-line);
  background: var(--c-premium-tint);
  color: var(--c-premium-ink);
  box-shadow: 0 6px 16px var(--brand-gold-a28);
}
/* A quieter variant that keeps its own capitalisation — a section label
   rather than an announcement. */
.rc-eyebrow--quiet {
  background: var(--c-surface-tile);
  color: var(--c-ink);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
  letter-spacing: 0;
  text-transform: none;
}

.rc-dot {
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: var(--r-circle);
  background: var(--c-accent);
}

/* The live indicator: a solid dot with one ring pinging out of it. */
.rc-pulse {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 9px;
  height: 9px;
}
.rc-pulse::before,
.rc-pulse::after {
  content: "";
  position: absolute;
  border-radius: var(--r-circle);
  background: var(--c-accent);
}
.rc-pulse::before {
  width: 9px;
  height: 9px;
  opacity: 0.45;
  animation: rc-ping var(--dur-pulse) cubic-bezier(0.2, 0.6, 0.3, 1) infinite;
}
.rc-pulse::after { width: 7px; height: 7px; }

/* ---- icons --------------------------------------------------------------
   Every inline SVG is authored WITHOUT fill/stroke attributes. Colour comes
   from these classes, so a token change re-colours every glyph on the page.
   .rc-ic-accent / .rc-ic-gold / .rc-ic-invert re-point currentColor for one
   path inside a two-tone glyph. */
.rc-icon { flex: none; width: 20px; height: 20px; fill: none; }
.rc-icon--sm { width: 14px; height: 14px; }
.rc-icon--md { width: 24px; height: 24px; }
.rc-icon--lg { width: 30px; height: 30px; }
.rc-icon--xl { width: 32px; height: 32px; }

.rc-ic-stroke {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.rc-ic-stroke--thin { stroke-width: 1.4; }
.rc-ic-fill   { fill: currentColor; stroke: none; }
.rc-ic-accent { color: var(--c-accent); }
.rc-ic-gold   { color: var(--c-premium); }
.rc-ic-invert { color: var(--n-white); }
.rc-ic-quiet  { color: var(--c-ink-faint); }

/* A glyph on a tinted square — the shape used for every small feature icon
   on the page. */
.rc-tile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--icon-tile);
  height: var(--icon-tile);
  border-radius: var(--r-xl);
  background: var(--c-surface-tile);
  color: var(--c-ink);
}
.rc-tile--sm    { width: var(--icon-tile-sm); height: var(--icon-tile-sm); border-radius: var(--r-lg); }
.rc-tile--brand { background: var(--c-accent-tint); color: var(--c-accent); }
.rc-tile--round { border-radius: var(--r-circle); }

/* For a tile whose artwork already IS a tile — a rounded, self-tinted PNG
   glyph rather than a line icon. The wrapper keeps the box and the hover and
   gives up its own ground and corners; leave them on and the glyph sits in a
   second tile, a sand square peeking out behind a pink one. */
.rc-tile--image {
  background: none;
  border-radius: 0;
}
.rc-tile--image img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}


/* =========================================================================
   05  HEADER AND NAVIGATION
   -------------------------------------------------------------------------
   One bar, sticky, lightweight. Below 62em the link list and the two
   buttons slide in from the right as one panel; the state is a checkbox
   that sits before .rc-nav in the DOM, which is what every rule below
   reaches through with `:checked ~`.
   ========================================================================= */

.rc-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: var(--c-canvas);
  border-bottom: 1px solid var(--c-line);
  box-shadow: var(--shadow-bar);
  transition: box-shadow var(--dur-nav) var(--ease-nav);
}
/* rc-land.js adds .is-scrolled once the page has left the top. The bar
   gains depth rather than height, so nothing below it moves. */
.rc-header.is-scrolled { box-shadow: var(--shadow-bar-lift); }

.rc-header__inner {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  min-height: var(--header-h);
}

/* min-height, not height: the lockup is 34px tall on a phone, and a 34px
   tap target is under the 44px this system promises. The bar is already
   taller than that, so this costs no layout. */
.rc-header__brand {
  display: flex;
  align-items: center;
  flex: none;
  min-height: var(--control-h);
}
.rc-header__logo { height: var(--logo-h); width: auto; }

.rc-nav {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  margin-left: auto;
  min-width: 0;
}

.rc-nav__list {
  display: flex;
  align-items: center;
  gap: clamp(0px, 0.3vw, var(--sp-1));
  min-width: 0;
}

.rc-nav__link {
  position: relative;
  display: flex;
  align-items: center;
  padding: var(--sp-2) clamp(var(--sp-1), 0.7vw, var(--sp-3));
  border-radius: var(--r-xs);
  color: var(--c-ink-body);
  font-family: var(--font-sans);
  font-size: var(--fs-nav);
  font-weight: var(--fw-medium);
  white-space: nowrap;
  transition:
    color var(--dur-hover) var(--ease-hover),
    background-color var(--dur-hover) var(--ease-hover);
}
.rc-nav__link:hover {
  color: var(--c-accent-ink);
  background: var(--c-surface-tile);
}
.rc-nav__link.is-active {
  color: var(--c-accent-ink);
  background: var(--c-accent-tint);
  font-weight: var(--fw-semibold);
}

/* The active marker is a bar that grows out of the centre, so moving
   between links reads as one indicator travelling rather than two
   appearing. */
.rc-nav__link::after {
  content: "";
  position: absolute;
  left: var(--sp-3);
  right: var(--sp-3);
  bottom: 2px;
  height: 2px;
  border-radius: var(--r-pill);
  background: var(--c-accent);
  transform: scaleX(0);
  transition: transform var(--dur-nav) var(--ease-nav);
}
.rc-nav__link.is-active::after { transform: scaleX(1); }

.rc-nav__actions {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex: none;
}

/* ---- the mobile toggle --------------------------------------------------
   The checkbox is the control: it is clipped rather than display:none, so
   it keeps its place in the tab order and Space still opens the menu. The
   label is the picture of it and is hidden from the accessibility tree, so
   the pair is announced once, not twice. */
.rc-nav-state {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  opacity: 0;
  pointer-events: none;
}

.rc-nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--control-h);
  height: var(--control-h);
  margin-left: auto;
  border: 1px solid var(--c-line);
  border-radius: var(--r-sm);
  background: var(--c-surface);
  color: var(--c-ink);
  transition:
    border-color var(--dur-hover) var(--ease-hover),
    background-color var(--dur-hover) var(--ease-hover);
}
.rc-nav-toggle:hover { border-color: var(--c-line-hover); background: var(--c-surface-tile); }
.rc-nav-state:focus-visible + .rc-nav-toggle {
  outline: var(--focus-width) solid var(--focus-color);
  outline-offset: var(--focus-offset);
}

.rc-nav-toggle__bars,
.rc-nav-toggle__bars::before,
.rc-nav-toggle__bars::after {
  display: block;
  width: 18px;
  height: 2px;
  border-radius: var(--r-pill);
  background: currentColor;
  transition: transform var(--dur-nav) var(--ease-nav), opacity var(--dur-hover) linear;
}
.rc-nav-toggle__bars { position: relative; }
.rc-nav-toggle__bars::before { content: ""; position: absolute; top: -6px; }
.rc-nav-toggle__bars::after  { content: ""; position: absolute; top:  6px; }

.rc-nav-state:checked ~ .rc-nav-toggle .rc-nav-toggle__bars { background: transparent; }
.rc-nav-state:checked ~ .rc-nav-toggle .rc-nav-toggle__bars::before { transform: translateY(6px) rotate(45deg); }
.rc-nav-state:checked ~ .rc-nav-toggle .rc-nav-toggle__bars::after  { transform: translateY(-6px) rotate(-45deg); }

/* The scrim closes the panel from anywhere outside it. It is a <label>, so
   it needs no script; it is aria-hidden because the checkbox already is
   the control. */
.rc-nav-scrim {
  display: none;
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-nav) - 1);
  background: rgba(28, 24, 74, 0.42);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur-nav) var(--ease-nav), visibility var(--dur-nav) linear;
}


/* =========================================================================
   06  HERO
   ========================================================================= */

.rc-hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background: var(--c-canvas);
  scroll-margin-top: var(--header-h);
}

/* A real <img>, not a background-image, so object-fit frames it and the
   artwork is never stretched. Decorative: alt="" and out of the tree. */
.rc-hero__sky {
  position: absolute;
  inset: 0;
  z-index: var(--z-under);
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 30%;
  opacity: var(--hero-sky-fade);
  pointer-events: none;
}

.rc-hero__grid {
  position: relative;
  z-index: var(--z-base);
  display: grid;
  grid-template-columns: minmax(0, 1.06fr) minmax(0, 0.94fr);
  align-items: center;
  gap: var(--grid-gap);
  padding-block: clamp(var(--sp-10), 4.5vw, var(--sp-14)) clamp(var(--sp-12), 5.5vw, 72px);
}

.rc-hero__copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-6);
  min-width: 0;
}

.rc-hero__title {
  font-family: var(--font-sans);
  font-size: var(--fs-hero);
  font-weight: var(--fw-black);
  line-height: var(--lh-display);
  letter-spacing: var(--ls-display);
  color: var(--c-ink);
  text-wrap: pretty;
}
.rc-hero__accent { color: var(--c-accent); }

/* The lockup under the headline: mark, rule, attribution. */
.rc-lockup {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  flex-wrap: wrap;
}
.rc-lockup__logo { height: var(--logo-h-sm); width: auto; }
.rc-lockup__rule {
  width: 1px;
  height: 32px;
  background: var(--c-line-firm);
}
.rc-lockup__text {
  font-size: var(--fs-body);
  font-weight: var(--fw-medium);
  color: var(--c-ink-body);
}

/* The six services, as glyph over label. */
.rc-servicebar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--servicebar-gap);
  max-width: 660px;
}
.rc-servicebar__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-3);
  width: calc(var(--hero-icon) + var(--sp-4));
}
.rc-servicebar__icon {
  width: var(--hero-icon);
  height: var(--hero-icon);
  object-fit: contain;
  transition: transform var(--dur-hover) var(--ease-hover);
}
.rc-servicebar__item:hover .rc-servicebar__icon { transform: translateY(var(--lift-tile)); }
/* The two glyphs that ship without a tile of their own get one drawn here,
   so the row reads as six equal marks instead of four and two. */
.rc-servicebar__icon--violet,
.rc-servicebar__icon--mint {
  padding: 6px;
  border-radius: var(--r-2xl);
}
.rc-servicebar__icon--violet { background: var(--c-tile-violet); }
.rc-servicebar__icon--mint   { background: var(--c-tile-mint); }

.rc-servicebar__label {
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  line-height: 1.25;
  color: var(--c-ink);
  text-align: center;
}

.rc-hero__art {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
}

/* Three elements, three owners of `transform`, so none of them fight:
     .rc-hero__art      the load entrance (a keyframe)
     .rc-hero__flip     the quarter turn  (a transition)
     .rc-hero__product  the idle float    (a keyframe)
   Collapsing any two of these into one element means the flip cancels the
   float, or the entrance cancels both. */
.rc-hero__stage {
  width: 100%;
  max-width: var(--hero-art-max);
  aspect-ratio: var(--hero-art-ratio);
  perspective: var(--hero-flip-depth);
}

.rc-hero__flip {
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  transition: transform var(--dur-flip) var(--ease-flip);
}
/* Edge-on. rc-land.js changes the face while this class is on, so the swap
   is never seen. */
.rc-hero__flip.is-turning { transform: rotateY(var(--hero-flip-angle)); }

.rc-hero__product {
  width: 100%;
  height: 100%;
  object-fit: contain;
  animation: rc-float var(--dur-float) var(--ease-inout) infinite;
  will-change: transform;
}


/* =========================================================================
   07  SECTION PRIMITIVES
   ========================================================================= */

.rc-section {
  padding-block: var(--section-pad-y);
  background: var(--c-canvas);
  scroll-margin-top: var(--header-h);
}
.rc-section--edge { border-top: 1px solid var(--c-line); }
.rc-section--soft { background: var(--c-surface-soft); }

.rc-section__head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-5);
  text-align: center;
}

.rc-section__title {
  font-family: var(--font-sans);
  font-size: var(--fs-h2);
  font-weight: var(--fw-black);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-tighter);
  color: var(--c-ink);
  text-wrap: pretty;
}
/* The second line of a two-line heading, set lighter so the pair reads as
   one sentence with an emphasis rather than as two headings. */
.rc-section__title-soft { font-weight: var(--fw-medium); }
.rc-section__title-accent { color: var(--c-accent); }

.rc-section__lead {
  max-width: 44ch;
  font-size: var(--fs-lead);
  line-height: var(--lh-body);
  color: var(--c-ink-body);
  text-wrap: pretty;
}

.rc-rule {
  width: 56px;
  height: 3px;
  border-radius: var(--r-pill);
  background: var(--c-accent);
}


/* =========================================================================
   08  WHAT WE OFFER
   -------------------------------------------------------------------------
   Three columns on desktop — cards, hub, cards — with the cards in each
   column offset against each other so the band reads as a composition
   rather than a six-cell grid. The hub is FIRST in the DOM (it carries the
   heading) and is placed into the middle column by grid, so the phone
   layout is heading-then-cards without a second markup order.
   ========================================================================= */

.rc-offer__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(280px, 380px) minmax(0, 1fr);
  align-items: center;
  gap: var(--grid-gap);
}

.rc-offer__hub {
  grid-column: 2;
  grid-row: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-5);
  text-align: center;
}
.rc-offer__mark {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--hub-mark);
  height: var(--hub-mark);
  border: 1px solid var(--c-accent-line);
  border-radius: var(--r-circle);
  background: var(--c-surface);
  box-shadow: 0 0 0 14px var(--c-accent-wash), 0 18px 40px var(--brand-red-a10);
}
.rc-offer__mark img { width: 64%; height: auto; }

.rc-offer__col {
  grid-row: 1;
  display: flex;
  flex-direction: column;
  gap: var(--sp-7);
  min-width: 0;
}
.rc-offer__col--left  { grid-column: 1; align-items: flex-start; }
.rc-offer__col--right { grid-column: 3; align-items: flex-end; }

/* The offset: the middle card of each column steps toward the hub. */
.rc-offer__col--left  > :nth-child(2) { align-self: flex-end; }
.rc-offer__col--right > :nth-child(2) { align-self: flex-start; }

/* ---- the service card --------------------------------------------------- */
.rc-card {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: var(--card-max);
  overflow: hidden;
  border: 1px solid var(--c-line);
  border-radius: var(--r-xl);
  background: var(--c-surface);
  box-shadow: var(--shadow-card);
  transition:
    transform    var(--dur-hover) var(--ease-hover),
    box-shadow   var(--dur-hover) var(--ease-hover),
    border-color var(--dur-hover) var(--ease-hover);
}
.rc-card:hover {
  transform: translateY(var(--lift-card));
  border-color: var(--c-accent-line);
  box-shadow: var(--shadow-card-hover);
}

.rc-card__media {
  flex: none;
  overflow: hidden;
  height: var(--card-media-h);
  background: var(--c-surface-tile);
}
.rc-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--dur-photo) var(--ease-hover);
}
.rc-card:hover .rc-card__media img { transform: scale(var(--zoom-photo)); }

/* flex:1 so cards that share a row in the two-column layout end level
   instead of each stopping at its own copy. */
.rc-card__body {
  flex: 1;
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5) var(--sp-5);
}
.rc-card__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--icon-tile-sm);
  height: var(--icon-tile-sm);
}
.rc-card__icon img { width: 100%; height: 100%; object-fit: contain; }
.rc-card__icon--violet,
.rc-card__icon--mint { border-radius: var(--r-lg); padding: 6px; }
.rc-card__icon--violet { background: var(--c-tile-violet); }
.rc-card__icon--mint   { background: var(--c-tile-mint); }

.rc-card__title {
  font-family: var(--font-sans);
  font-size: var(--fs-h5);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-tight);
  line-height: 1.3;
  color: var(--c-ink);
  transition: color var(--dur-hover) var(--ease-hover);
}
.rc-card:hover .rc-card__title { color: var(--c-accent-ink); }

.rc-card__desc {
  margin-top: 3px;
  font-size: var(--fs-xs);
  line-height: var(--lh-normal);
  color: var(--c-ink-body);
  text-wrap: pretty;
}


/* =========================================================================
   09  TECHNOLOGY
   -------------------------------------------------------------------------
   Default state: a plain responsive grid. That is what a phone gets, what
   a reduced-motion reader gets, and what a browser without container-query
   units gets — the content is never dependent on the animation.

   Marquee state (>= 64em, motion allowed, `cqw` supported): the lane
   becomes a fixed-height strip and each card travels across it on an arc.
   The travel distance is expressed in `cqw` — percentages of the STAGE's
   own width — so one keyframe is exact at every viewport with no script.
   See the GEOMETRY block in Layer 2 for the arithmetic behind the spacing.
   ========================================================================= */

.rc-tech__head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-5);
  text-align: center;
}
.rc-tech__badge {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 70px;
  height: 70px;
  border: 1px solid var(--c-accent-line);
  border-radius: var(--r-2xl);
  background: var(--c-accent-wash);
  color: var(--c-accent);
}

.rc-tech__stage {
  margin-top: var(--sp-10);
  overflow: hidden;
}

/* Two columns, not auto-fit: there are ten cards, and ten divides evenly
   by two and by five only. Three columns leaves an orphan on the last row,
   and five is too narrow for "Available On Mobile, Desktop Or Laptop". */
/* No max-width or gutter of its own: the .rc-wrap around .rc-tech__stage
   owns both, so the strip lines up with every other band on the page. */
.rc-tech__lane {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-4);
  width: 100%;
}

/* The two wrappers exist for the marquee. In grid mode they must not eat
   the cell's height, or cards in a row stop ending level. */
.rc-tech__travel { display: flex; min-width: 0; }
.rc-tech__arc    { display: flex; flex: 1; min-width: 0; }

/* Five columns from 62em — the other factor of ten, and the width at which
   two columns start stranding one card per half-screen. Note this is 62em,
   not the marquee's 64em: the 992–1023px band runs the grid (the marquee
   has not started yet) and it is far too wide for two columns.
   Above 64em the marquee block below sets `display: block`, so where that
   applies this rule is inert; it is what a reduced-motion reader, or a
   browser without container-query units, gets on a desktop. */
@media (min-width: 62em) {
  .rc-tech__lane { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}

.rc-tech-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-4);
  flex: 1;
  /* Uncapped in grid mode: a card capped at 250px and centred inside a
     460px cell reads as a mistake, not as breathing room. The marquee sets
     an explicit width instead — see the @supports block. */
  padding: var(--sp-7) var(--sp-5) var(--sp-7);
  border: 1px solid var(--c-line);
  border-radius: var(--r-2xl);
  background: var(--c-surface-mute);
  box-shadow: 0 14px 34px rgba(28, 24, 74, 0.07);
  text-align: center;
  transition:
    border-color var(--dur-hover) var(--ease-hover),
    box-shadow   var(--dur-hover) var(--ease-hover);
}
.rc-tech-card:hover {
  border-color: var(--c-accent-line);
  box-shadow: var(--shadow-card-hover);
}
/* A full-colour glyph, not a line icon on a tinted disc — the same family
   as the service marks in the hero, and the reason there is no background
   here: a pink disc behind a multi-colour illustration fights it. */
.rc-tech-card__mark {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--tech-mark);
  height: var(--tech-mark);
}
.rc-tech-card__mark img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.rc-tech-card__title {
  font-family: var(--font-sans);
  font-size: var(--fs-h4);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-tight);
  line-height: var(--lh-snug);
  color: var(--c-ink);
  text-wrap: pretty;
}
.rc-tech-card__desc {
  font-size: var(--fs-sm);
  line-height: var(--lh-normal);
  color: var(--c-ink-muted);
}

/* The dashed route under the strip — decoration, drawn in CSS colours. */
.rc-tech__route {
  width: 100%;
  max-width: 900px;
  height: 70px;
  margin: var(--sp-7) auto 0;
}
.rc-tech__route-line {
  fill: none;
  stroke: var(--c-line-dash);
  stroke-width: 1.4;
  stroke-dasharray: 3 7;
}
.rc-tech__route-dot { fill: var(--c-ink-faint); }

@keyframes rc-tech-travel {
  from { transform: translateX(var(--tech-x-start)); }
  to   { transform: translateX(var(--tech-x-end)); }
}

/* The rise and fall. A card peaks when it is centred in the stage, which
   with the travel above is ~80% of the way through the cycle, not 50%. */
/* The rise and fall.

   THESE PERCENTAGES ARE DERIVED FROM --tech-x-start. Keyframe offsets cannot
   read a custom property, so the coupling is manual: change the travel and
   you MUST re-derive these, or the card slides into view already tilted and
   motionless, sits there, and then lurches upward — which reads as a bounce.
   (That is exactly what happened when the travel went 300cqw -> 240cqw and
   these were left behind.)

   With stage W, card C and start S in stage-widths, travel T = S*W + 1.1C:

     enters the stage   x = W         ->  (S*W - W) / T
     centred in it      x = W/2 - C/2 ->  (S*W - W/2 + C/2) / T
     fully gone         x = -C        ->  (S*W + C) / T

   At S=2.4, W=1280, C=250 that is 53.5%, 76.4%, 99.3%. The peak sits on the
   centre figure and the shoulders are spaced evenly either side of it. The
   rise begins at 50% — a little before the card is actually on screen — so
   the corner where it leaves the parked position happens out of sight.
   W varies with the viewport, but only between 944 and 1280 (the stage is
   inside .rc-wrap), which moves these by about a point. */
@keyframes rc-tech-arc {
  0%, 50% {
    transform: translateY(var(--tech-arc-drop)) rotate(var(--tech-arc-tilt));
  }
  64% {
    transform: translateY(calc(var(--tech-arc-drop) * var(--tech-arc-mid)))
               rotate(calc(var(--tech-arc-tilt) * 0.5));
  }
  76% {
    transform: translateY(0) rotate(0deg);
  }
  88% {
    transform: translateY(calc(var(--tech-arc-drop) * var(--tech-arc-mid)))
               rotate(calc(var(--tech-arc-tilt) * -0.5));
  }
  99%, 100% {
    transform: translateY(var(--tech-arc-drop)) rotate(calc(var(--tech-arc-tilt) * -1));
  }
}

@supports (width: 1cqw) {
  @media (min-width: 64em) and (prefers-reduced-motion: no-preference) {

    .rc-tech__stage {
      container-type: inline-size;
      /* The strip must not begin or end at a hard line. */
      -webkit-mask-image: linear-gradient(90deg, transparent, #000 var(--tech-mask), #000 calc(100% - var(--tech-mask)), transparent);
              mask-image: linear-gradient(90deg, transparent, #000 var(--tech-mask), #000 calc(100% - var(--tech-mask)), transparent);
    }

    .rc-tech__lane {
      display: block;
      position: relative;
      height: var(--tech-stage-h);
    }

    .rc-tech__travel {
      display: block;
      position: absolute;
      top: 0;
      left: 0;
      width: var(--tech-card-w);
      animation: rc-tech-travel var(--tech-cycle) linear infinite;
      will-change: transform;
    }
    .rc-tech__arc {
      display: block;
      animation: rc-tech-arc var(--tech-cycle) linear infinite;
    }

    /* Ten evenly spaced negative delays. The pair on each row must match,
       or the card's height stops tracking its position. Change
       --tech-count and this list changes with it. */
    .rc-tech__travel:nth-child(1),  .rc-tech__travel:nth-child(1)  .rc-tech__arc { animation-delay: calc(var(--tech-cycle) * -0.0); }
    .rc-tech__travel:nth-child(2),  .rc-tech__travel:nth-child(2)  .rc-tech__arc { animation-delay: calc(var(--tech-cycle) * -0.1); }
    .rc-tech__travel:nth-child(3),  .rc-tech__travel:nth-child(3)  .rc-tech__arc { animation-delay: calc(var(--tech-cycle) * -0.2); }
    .rc-tech__travel:nth-child(4),  .rc-tech__travel:nth-child(4)  .rc-tech__arc { animation-delay: calc(var(--tech-cycle) * -0.3); }
    .rc-tech__travel:nth-child(5),  .rc-tech__travel:nth-child(5)  .rc-tech__arc { animation-delay: calc(var(--tech-cycle) * -0.4); }
    .rc-tech__travel:nth-child(6),  .rc-tech__travel:nth-child(6)  .rc-tech__arc { animation-delay: calc(var(--tech-cycle) * -0.5); }
    .rc-tech__travel:nth-child(7),  .rc-tech__travel:nth-child(7)  .rc-tech__arc { animation-delay: calc(var(--tech-cycle) * -0.6); }
    .rc-tech__travel:nth-child(8),  .rc-tech__travel:nth-child(8)  .rc-tech__arc { animation-delay: calc(var(--tech-cycle) * -0.7); }
    .rc-tech__travel:nth-child(9),  .rc-tech__travel:nth-child(9)  .rc-tech__arc { animation-delay: calc(var(--tech-cycle) * -0.8); }
    .rc-tech__travel:nth-child(10), .rc-tech__travel:nth-child(10) .rc-tech__arc { animation-delay: calc(var(--tech-cycle) * -0.9); }

    /* Rest the pointer on the strip and it holds still, so a card that
       caught the reader's eye can actually be read. */
    .rc-tech__stage:hover .rc-tech__travel,
    .rc-tech__stage:hover .rc-tech__arc,
    .rc-tech__stage:focus-within .rc-tech__travel,
    .rc-tech__stage:focus-within .rc-tech__arc { animation-play-state: paused; }

    /* One height for every traveller, so the strip is a row of equal
       objects rather than ten cards of assorted size bobbing past.
       Content is centred in that height, not top-aligned: the arc already
       puts every card at a different y, so there is no common mark line to
       preserve, and a one-line title left at the top would sit above 90px
       of nothing. */
    .rc-tech-card {
      width: var(--tech-card-w);
      height: var(--tech-card-h);
      flex: none;
      justify-content: center;
    }
  }
}


/* =========================================================================
   10  BUSINESS INSIGHT AND THE PRODUCT PREVIEW
   ========================================================================= */

/* One column by default; the min-width: 80em block in section 15 splits it.
   Narrow-first here rather than wide-first, because the split is the
   exception on this band — see the comment on that block. */
.rc-insight__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: center;
  gap: var(--grid-gap);
}

.rc-insight__copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-6);
  min-width: 0;
}
.rc-insight__title {
  font-family: var(--font-sans);
  font-size: var(--fs-h2);
  font-weight: var(--fw-black);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-tighter);
  color: var(--c-ink);
  text-wrap: pretty;
}
.rc-insight__lead { max-width: 42ch; font-size: var(--fs-lead); line-height: var(--lh-body); }

/* Four across, explicitly. auto-fit would give three and an orphan at the
   width this column actually gets, which reads as a mistake. */
.rc-highlights {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--sp-5);
  width: 100%;
  max-width: 520px;
  margin-top: var(--sp-1);
}
.rc-highlight {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
.rc-highlight__label {
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  line-height: 1.35;
  color: var(--c-ink);
}
/* The lift only. These tiles bring their own colour, so there is no ground
   left to tint on hover. */
.rc-highlight .rc-tile { transition: transform var(--dur-hover) var(--ease-hover); }
.rc-highlight:hover .rc-tile { transform: translateY(var(--lift-tile)); }

/* ---- the product preview ------------------------------------------------
   A screenshot of the real dashboard, framed like a card. This used to be a
   hand-built mockup of one - forty rules, its own type scale and a container
   query - kept in step with a product it could only ever approximate. An
   image cannot drift.

   The frame keeps the mockup's border, radius and shadow, so the band reads
   exactly as before; only what sits inside it changed. */
.rc-dash {
  margin: 0;
  overflow: hidden;
  border: 1px solid var(--c-line);
  border-radius: var(--r-2xl);
  background: var(--c-surface);
  box-shadow: var(--shadow-float);
}

/* aspect-ratio rather than letting the image size itself: the box is
   reserved at its final height before the bytes arrive, so a lazily-loaded
   200KB screenshot cannot shove the rest of the band down as it lands.
   Re-measure --dash-ratio if the shot is ever replaced. */
.rc-dash__shot {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: var(--dash-ratio);
}


/* =========================================================================
   11  ABOUT
   ========================================================================= */

.rc-about { display: flex; flex-direction: column; gap: var(--band-gap); }

.rc-about__row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: center;
  gap: var(--grid-gap);
}
/* Row two puts the photograph first, so the two rows mirror each other. */
.rc-about__row--flip .rc-about__copy { order: 2; }
.rc-about__row--flip .rc-about__media { order: 1; }

.rc-about__copy { display: flex; flex-direction: column; gap: var(--sp-5); min-width: 0; }
.rc-about__title {
  font-family: var(--font-sans);
  font-size: var(--fs-h3);
  font-weight: var(--fw-bold);
  line-height: var(--lh-snug);
  letter-spacing: var(--ls-tight);
  color: var(--c-ink);
  text-wrap: pretty;
}
.rc-about__text {
  font-size: var(--fs-body);
  line-height: var(--lh-relaxed);
  color: var(--c-ink-body);
  text-wrap: pretty;
}

.rc-chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.rc-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-4);
  border: 1px solid var(--c-line);
  border-radius: var(--r-pill);
  background: var(--c-surface);
  color: var(--c-ink);
  font-family: var(--font-sans);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-medium);
  transition: border-color var(--dur-hover) var(--ease-hover), background-color var(--dur-hover) var(--ease-hover);
}
.rc-chip:hover { border-color: var(--c-accent-line); background: var(--c-accent-wash); }
.rc-chip .rc-icon { color: var(--c-accent); }

.rc-about__media {
  overflow: hidden;
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-card);
  min-width: 0;
}
.rc-about__media img {
  width: 100%;
  height: clamp(240px, 26vw, 320px);
  object-fit: cover;
  /* The subject of both photographs sits in the lower half, and a narrow
     screen crops these to a 3:1 letterbox. Centre framing would keep the
     sky and throw away the skyline. */
  object-position: center 68%;
  transition: transform var(--dur-photo) var(--ease-hover);
}
.rc-about__media:hover img { transform: scale(var(--zoom-photo)); }


/* =========================================================================
   12  PARTNER CALL TO ACTION
   ========================================================================= */

.rc-cta { padding-block: clamp(var(--sp-8), 3.5vw, var(--sp-10)); background: var(--c-canvas); }

.rc-cta__panel {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  padding: clamp(var(--sp-10), 4.5vw, var(--sp-16)) clamp(var(--sp-6), 4vw, var(--sp-14));
  border: 1px solid var(--c-line);
  border-radius: var(--r-3xl);
  background: linear-gradient(120deg, var(--n-paper) 0%, var(--n-mist) 100%);
}
.rc-cta__route {
  position: absolute;
  inset: 0;
  z-index: var(--z-under);
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.rc-cta__route-line {
  fill: none;
  stroke: var(--c-line-dash);
  stroke-width: 1.4;
  stroke-dasharray: 4 8;
}
.rc-cta__plane {
  position: absolute;
  top: var(--sp-8);
  right: 16%;
  z-index: var(--z-under);
  width: 34px;
  height: 34px;
  color: var(--c-line-firm);
  transform: rotate(48deg);
  pointer-events: none;
}

.rc-cta__grid {
  position: relative;
  z-index: var(--z-base);
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  align-items: center;
  gap: var(--grid-gap);
}
.rc-cta__copy { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-5); min-width: 0; }
.rc-cta__title {
  font-family: var(--font-sans);
  font-size: var(--fs-h2);
  font-weight: var(--fw-black);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-tighter);
  color: var(--c-ink);
  text-wrap: pretty;
}
.rc-cta__lead { font-size: var(--fs-lead); line-height: var(--lh-normal); color: var(--c-ink-body); }
.rc-cta__actions { display: flex; flex-wrap: wrap; gap: var(--sp-4); margin-top: var(--sp-1); }

.rc-stats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-4);
  min-width: 0;
}
.rc-stat {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-5);
  border: 1px solid var(--c-line);
  border-radius: var(--r-xl);
  background: var(--c-surface);
  box-shadow: var(--shadow-tile);
  min-width: 0;
  transition: transform var(--dur-hover) var(--ease-hover), box-shadow var(--dur-hover) var(--ease-hover);
}
.rc-stat:hover { transform: translateY(var(--lift-tile)); box-shadow: var(--shadow-card); }
.rc-stat__n {
  font-family: var(--font-sans);
  font-size: 1.5rem;
  font-weight: var(--fw-black);
  letter-spacing: var(--ls-tight);
  line-height: 1;
  color: var(--c-ink);
}
.rc-stat__label { font-size: var(--fs-xs); line-height: 1.45; color: var(--c-ink-body); }


/* =========================================================================
   13  CONTACT
   ========================================================================= */

.rc-contact__grid {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  align-items: start;
  gap: var(--grid-gap);
}

.rc-contact__copy { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-4); min-width: 0; }
.rc-contact__title {
  font-family: var(--font-sans);
  font-size: var(--fs-h2);
  font-weight: var(--fw-black);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-tighter);
  color: var(--c-ink);
  text-wrap: pretty;
}
.rc-contact__title-soft { font-weight: var(--fw-medium); color: var(--c-ink-body); }
.rc-contact__lead { font-size: var(--fs-sm); line-height: var(--lh-normal); color: var(--c-ink-body); }

.rc-contact__cards { display: flex; flex-direction: column; gap: var(--sp-3); width: 100%; margin-top: var(--sp-1); }
.rc-contact-card {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-4);
  border: 1px solid var(--c-line);
  border-radius: var(--r-lg);
  background: var(--c-surface);
  box-shadow: var(--shadow-tile);
  transition: transform var(--dur-hover) var(--ease-hover), box-shadow var(--dur-hover) var(--ease-hover), border-color var(--dur-hover) var(--ease-hover);
}
.rc-contact-card:hover {
  transform: translateY(var(--lift-tile));
  border-color: var(--c-accent-line);
  box-shadow: var(--shadow-card);
}
.rc-contact-card__mark {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: var(--r-lg);
  background: var(--c-accent-tint);
  color: var(--c-accent);
}
.rc-contact-card__label { font-size: var(--fs-3xs); color: var(--c-ink-muted); }
.rc-contact-card__value {
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
  line-height: var(--lh-normal);
  color: var(--c-ink);
}
/* padding-block on an inline element grows the hit area without growing
   the line box, so the address rows keep their spacing and gain a target
   big enough to hit with a thumb. */
.rc-contact-card__value a { padding-block: var(--sp-1); color: inherit; }
.rc-contact-card__value a:hover { color: var(--c-accent-ink); }

.rc-contact__note { display: flex; align-items: center; gap: var(--sp-3); margin-top: var(--sp-1); }
.rc-contact__note-title { font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--c-ink); }
.rc-contact__note-sub { font-size: var(--fs-2xs); color: var(--c-ink-muted); }

/* ---- the enquiry form --------------------------------------------------- */
.rc-form {
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
  padding: clamp(var(--sp-5), 2.5vw, var(--sp-8));
  border: 1px solid var(--c-line);
  border-radius: var(--r-2xl);
  background: var(--c-surface);
  box-shadow: var(--shadow-panel);
  min-width: 0;
}
.rc-form__title {
  font-family: var(--font-sans);
  font-size: var(--fs-h3);
  font-weight: var(--fw-black);
  letter-spacing: var(--ls-tighter);
  color: var(--c-ink);
}
.rc-form__sub { margin-top: var(--sp-2); font-size: var(--fs-sm); color: var(--c-ink-body); }

.rc-form__row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-4);
}

.rc-field { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.rc-field__label {
  font-family: var(--font-sans);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-medium);
  color: var(--c-ink);
}
.rc-field__req { color: var(--c-accent); }

.rc-field__input,
.rc-field__select,
.rc-field__area {
  width: 100%;
  min-width: 0;
  padding: 0 var(--control-px);
  min-height: var(--control-h);
  border: 1px solid var(--c-line-firm);
  border-radius: var(--r-sm);
  background: var(--c-surface);
  color: var(--c-ink);
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  transition:
    border-color var(--dur-hover) var(--ease-hover),
    box-shadow   var(--dur-hover) var(--ease-hover);
}
.rc-field__area {
  padding: var(--sp-3) var(--control-px) var(--sp-7);
  min-height: 118px;
  line-height: var(--lh-normal);
  resize: vertical;
}
.rc-field__input::placeholder,
.rc-field__area::placeholder { color: var(--c-ink-faint); }

.rc-field__input:hover,
.rc-field__select:hover,
.rc-field__area:hover { border-color: var(--c-line-hover); }

.rc-field__input:focus,
.rc-field__select:focus,
.rc-field__area:focus {
  outline: none;
  border-color: var(--c-accent);
  box-shadow: 0 0 0 3px var(--c-accent-ring);
}
.rc-field__input:focus-visible,
.rc-field__select:focus-visible,
.rc-field__area:focus-visible { outline: none; }

/* :user-invalid, not :invalid — a required field is invalid the moment the
   page loads, and a form that greets the reader in red is a bug. This waits
   until they have actually tried. */
.rc-field__input:user-invalid,
.rc-field__select:user-invalid,
.rc-field__area:user-invalid {
  border-color: var(--st-error);
  background: var(--st-error-tint);
}
.rc-field__error {
  display: none;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-3xs);
  color: var(--st-error);
}
.rc-field__input:user-invalid  ~ .rc-field__error,
.rc-field__select:user-invalid ~ .rc-field__error,
.rc-field__area:user-invalid   ~ .rc-field__error { display: flex; }

.rc-field__group { display: flex; gap: var(--sp-2); min-width: 0; }
.rc-field__group .rc-field__select { flex: none; width: 118px; padding-inline: var(--sp-2); }
.rc-field__group .rc-field__input  { flex: 1; font-family: var(--font-mono); }

.rc-field__count {
  align-self: flex-end;
  font-family: var(--font-mono);
  font-size: var(--fs-3xs);
  color: var(--c-ink-muted);
}

/* The success panel. Hidden until rc-land.js puts .is-sent on the form. */
.rc-form__status {
  display: none;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-4);
  border: 1px solid var(--st-ok-line);
  border-radius: var(--r-md);
  background: var(--st-ok-tint);
  color: var(--st-ok);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
}
.rc-form.is-sent .rc-form__status { display: flex; }

.rc-form__submit { align-self: flex-start; }

/* The embedded enquiry form. A frame is replaced content: it needs a block
   box and an explicit height, and its own border switched off - the card
   around it already draws one. */
.rc-form__embed {
  display: block;
  width: 99%;
  height: var(--form-embed-h);
  border: 0;
}


/* =========================================================================
   13b  FLOATING DOCK
   -------------------------------------------------------------------------
   Two shortcuts that follow the reader down the page: one to the contact
   band, one back to the top. Both are real links, so both work from the
   keyboard and without script; rc-land.js only decides when they are on
   screen, by adding .is-visible to the dock and .is-hidden to the enquiry
   button.

   `hidden` in the markup is the no-script state. It is the attribute, not a
   class, so a page whose script never runs never shows a dock that cannot
   be dismissed — and rc-land.js removes it before doing anything else.
   ========================================================================= */

.rc-dock {
  position: fixed;
  right: var(--dock-inset);
  bottom: var(--dock-inset);
  z-index: var(--z-dock);
  display: flex;
  align-items: center;
  gap: var(--dock-gap);
  /* Parked: pushed down, faded, and out of the tab order. visibility is on
     the transition list rather than switched instantly, so the dock is
     still drawn while it slides away. */
  opacity: 0;
  visibility: hidden;
  transform: translateY(var(--dock-shift));
  transition:
    opacity    var(--dur-nav) var(--ease-nav),
    transform  var(--dur-nav) var(--ease-nav),
    visibility var(--dur-nav) linear;
}
.rc-dock[hidden] { display: none; }
.rc-dock.is-visible {
  opacity: 1;
  visibility: visible;
  transform: none;
}

.rc-dock__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: var(--dock-size);
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  font-family: var(--font-sans);
  font-size: var(--fs-cta-sm);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-cta);
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
  transition:
    background-color var(--dur-hover) var(--ease-hover),
    border-color     var(--dur-hover) var(--ease-hover),
    color            var(--dur-hover) var(--ease-hover),
    box-shadow       var(--dur-hover) var(--ease-hover),
    transform        var(--dur-hover) var(--ease-hover),
    opacity          var(--dur-nav)   var(--ease-nav),
    visibility       var(--dur-nav)   linear;
}
.rc-dock__btn:hover { transform: translateY(var(--lift-tile)); }

.rc-dock__btn--enquiry {
  padding-inline: var(--sp-5);
  background: var(--c-accent);
  color: var(--c-on-brand);
  box-shadow: var(--shadow-brand);
}
.rc-dock__btn--enquiry:hover,
.rc-dock__btn--enquiry:focus-visible {
  background: var(--c-accent-strong);
  color: var(--c-on-brand);
  box-shadow: var(--shadow-brand-lift);
}
/* Stood down while the contact band is on screen. It keeps its space in the
   flex row rather than collapsing it, so the round button does not jump
   sideways as the reader crosses into the band. */
.rc-dock__btn--enquiry.is-hidden {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.rc-dock__btn--top {
  width: var(--dock-size);
  padding: 0;
  flex: none;
  border-color: var(--c-line);
  background: var(--c-surface);
  color: var(--c-ink);
  box-shadow: var(--shadow-card);
}
.rc-dock__btn--top:hover,
.rc-dock__btn--top:focus-visible {
  border-color: var(--c-accent);
  color: var(--c-accent-ink);
}


/* =========================================================================
   13c  LEGAL PAGES  (privacy-policy.html, terms-conditions.html)
   -------------------------------------------------------------------------
   A banner, then one content card. Two content shapes share it: the terms
   are an accordion, the privacy policy is continuous prose. Everything else
   on those pages — header, footer, dock, buttons, tokens — is the same
   furniture as the landing page, which is why they load this same sheet.
   ========================================================================= */

.rc-legal-hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  align-items: center;
  min-height: var(--legal-hero-min);
  /* The gradient is not decoration behind the art — it IS the band below
     48em, where the art is hidden. Sampled from the artwork's left edge so
     the two are one surface. */
  background: linear-gradient(180deg, var(--c-legal-sky) 0%, var(--c-legal-sky-fade) 100%);
  padding-block: clamp(var(--sp-8), 4vw, var(--sp-12));
}

/* The illustration sits to the right and the copy runs over its empty half.
   aspect-ratio holds the band's height before the image lands. */
.rc-legal-hero__art {
  position: absolute;
  inset: 0;
  z-index: var(--z-under);
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: right center;
  pointer-events: none;
}

.rc-legal-hero__copy {
  position: relative;
  z-index: var(--z-base);
  /* Half the band on desktop: the artwork owns the other half, and copy
     running under a shield or a plane is copy nobody can read. */
  max-width: 34rem;
}
.rc-legal-hero__title {
  margin-top: var(--sp-3);
  font-family: var(--font-sans);
  font-size: var(--fs-h2);
  font-weight: var(--fw-black);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-tighter);
  color: var(--c-ink);
  text-wrap: pretty;
}
.rc-legal-hero__lead {
  margin-top: var(--sp-4);
  font-size: var(--fs-lead);
  line-height: var(--lh-body);
  color: var(--c-ink-body);
  text-wrap: pretty;
}

/* The card rides up over the banner's bottom edge. */
.rc-legal-body {
  position: relative;
  z-index: var(--z-base);
  margin-top: calc(-1 * var(--legal-card-lift));
  margin-bottom: var(--section-pad-y);
  padding: clamp(var(--sp-6), 3vw, var(--sp-10));
  border: 1px solid var(--c-line);
  border-radius: var(--r-2xl);
  background: var(--c-surface);
  box-shadow: var(--shadow-panel);
}

/* ---- legal prose --------------------------------------------------------
   One place that styles the running text, so neither page restates it. */
.rc-prose { color: var(--c-ink-body); }
/* The flow spacing has to name BOTH containers. On the terms page the
   paragraphs are direct children of .rc-prose (it sits on the accordion
   body); on the privacy page .rc-prose sits on the card and the paragraphs
   are a level down, inside .rc-legal-section. A `> * + *` on .rc-prose
   alone spaces the sections and leaves the text inside them touching. */
.rc-prose > * + *,
.rc-legal-section > * + * { margin-top: var(--sp-4); }
/* A heading sits closer to the text it introduces than to the block above. */
.rc-legal-section__title + * { margin-top: var(--sp-3); }
.rc-prose p {
  font-size: var(--fs-body);
  line-height: var(--lh-relaxed);
  text-wrap: pretty;
}
.rc-prose ul { display: flex; flex-direction: column; gap: var(--sp-2); }
.rc-prose li {
  position: relative;
  padding-left: var(--sp-6);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
}
/* A drawn dot rather than list-style, so its colour is a token and its
   position does not drift with the font. */
.rc-prose li::before {
  content: "";
  position: absolute;
  left: var(--sp-2);
  top: 0.6em;
  width: 5px;
  height: 5px;
  border-radius: var(--r-circle);
  background: var(--c-accent);
}
/* padding-block grows the hit area past 24px without growing the line box,
   the same trade the footer and contact links make. */
.rc-prose a {
  padding-block: var(--sp-1);
  color: var(--c-accent-ink);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ---- the privacy policy's numbered sections ---------------------------- */
.rc-legal-section + .rc-legal-section { margin-top: var(--sp-8); }
.rc-legal-section__title {
  font-family: var(--font-sans);
  font-size: var(--fs-h5);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--c-ink);
}

/* ---- the terms accordion ------------------------------------------------
   <details>/<summary>, not a script. It is keyboard-operable and
   screen-reader-announced for free, and it still works with JavaScript off
   — which matters more on a legal page than anywhere else on the site.

   The `name` attribute makes it exclusive (opening one closes the rest) in
   browsers that support it, and simply allows several open in those that
   do not. That is a fine thing to degrade to; nothing is lost. */
.rc-accordion { display: flex; flex-direction: column; gap: var(--sp-3); }

.rc-accordion__item {
  border: 1px solid var(--c-line);
  border-radius: var(--r-lg);
  background: var(--c-surface);
  transition: border-color var(--dur-hover) var(--ease-hover),
              box-shadow   var(--dur-hover) var(--ease-hover);
}
.rc-accordion__item:hover { border-color: var(--c-line-hover); }
.rc-accordion__item[open] {
  border-color: var(--c-accent-line);
  box-shadow: var(--shadow-tile);
}

.rc-accordion__head {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
  cursor: pointer;
  /* Both are needed: Safari uses the -webkit pseudo-element, everyone else
     honours list-style. Without them the native triangle sits beside ours. */
  list-style: none;
}
.rc-accordion__head::-webkit-details-marker { display: none; }
.rc-accordion__head:focus-visible {
  outline: var(--focus-width) solid var(--focus-color);
  outline-offset: calc(-1 * var(--focus-width));
  border-radius: var(--r-lg);
}

.rc-accordion__num {
  flex: none;
  min-width: var(--legal-num-w);
  padding: var(--sp-1) var(--sp-2);
  border-radius: var(--r-xs);
  background: var(--c-accent-tint);
  color: var(--c-accent-ink);
  font-family: var(--font-sans);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-bold);
  font-variant-numeric: tabular-nums;
  text-align: center;
}
.rc-accordion__title {
  flex: 1;
  min-width: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-h5);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-tight);
  color: var(--c-ink);
}
.rc-accordion__chevron {
  flex: none;
  color: var(--c-ink-muted);
  transition: transform var(--dur-nav) var(--ease-nav), color var(--dur-hover) var(--ease-hover);
}
.rc-accordion__item[open] .rc-accordion__chevron { transform: rotate(180deg); color: var(--c-accent); }

.rc-accordion__body {
  padding: 0 var(--sp-5) var(--sp-5);
  /* Indented to the title, so the body reads as belonging to it rather than
     starting a new column under the number. */
  padding-left: calc(var(--sp-5) + var(--legal-num-w) + var(--sp-4));
  border-top: 1px solid var(--c-line);
  margin-top: var(--sp-1);
  padding-top: var(--sp-4);
}


/* =========================================================================
   14  FOOTER
   -------------------------------------------------------------------------
   Visually lighter than the hero and the closing band: one tinted ground,
   hairline dividers, no elevation.
   ========================================================================= */

.rc-footer {
  border-top: 1px solid var(--c-line);
  background: var(--c-surface-soft);
  padding-block: clamp(var(--sp-10), 4vw, var(--sp-14)) 0;
}

/* Three columns divided by hairlines. The grid has NO column gap: the rule
   is a border on the column itself and the space either side of it is that
   column's padding, so the line lands midway between two blocks of text
   instead of hard against one of them. Add a fourth column and it picks up
   its own rule with no further work. */
.rc-footer__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr);
  row-gap: var(--sp-8);
  padding-bottom: var(--sp-10);
}
.rc-footer__col { padding-inline: var(--footer-col-pad); min-width: 0; }
.rc-footer__col:first-child { padding-left: 0; }
.rc-footer__col + .rc-footer__col { border-left: 1px solid var(--c-line); }

.rc-footer__brand { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-4); }
.rc-footer__logo { height: var(--footer-logo-h); width: auto; }
.rc-footer__tagline { font-size: var(--fs-sm); line-height: var(--lh-normal); color: var(--c-ink-muted); }

/* ---- an office ---------------------------------------------------------
   The pin sits in the heading rather than beside the address, so the name
   and its marker read as one line and the postal lines hang cleanly under
   them. The <h2> is flex; the address is plain text with <br>s, because
   these ARE lines rather than a list. */
.rc-office__name {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  font-family: var(--font-sans);
  font-size: var(--fs-h5);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-tight);
  color: var(--c-ink);
}
.rc-office__address {
  margin-top: var(--sp-3);
  /* <address> is italic by default and these are postal lines, not asides. */
  font-style: normal;
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
  color: var(--c-ink-body);
}

.rc-footer__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--sp-3);
  padding-block: var(--sp-5);
  border-top: 1px solid var(--c-line);
  font-size: var(--fs-3xs);
  color: var(--c-ink-muted);
}

/* Each legal link carries the divider on its own left edge â€” including the
   first, which is what puts a rule between the copyright and the pair. */
.rc-footer__legal { display: flex; flex-wrap: wrap; }
.rc-footer__legal a {
  display: inline-block;
  padding-block: var(--sp-1);
  padding-inline: var(--sp-5);
  border-left: 1px solid var(--c-line);
  color: var(--c-ink-muted);
}
.rc-footer__legal a:last-child { padding-right: 0; }
.rc-footer__legal a:hover { color: var(--c-accent-ink); }


/* =========================================================================
   15  RESPONSIVE — STRUCTURE
   -------------------------------------------------------------------------
   Layout changes only. Anything dimensional is a token override in Layer 2.
   Breakpoints, and what each one is actually for:

     75em   the "what we offer" hub can no longer hold a column either side
     62em   the navigation becomes a panel; two-column bands become one
     48em   the phone layout proper — full-width controls, stacked forms
     30em   the last step before 320px
   ========================================================================= */

@media (max-width: 74.999em) {
  /* Three columns of cards around a hub stops working once the hub is
     narrower than the cards. Two columns of cards under the hub does. */
  .rc-offer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: stretch; }
  .rc-offer__hub  { grid-column: 1 / -1; grid-row: 1; margin-bottom: var(--sp-2); }
  /* display:contents dissolves the two column wrappers so all six cards
     become direct children of the grid — otherwise a column of three would
     have to reflow into two cells and leave an orphan. */
  .rc-offer__col  { display: contents; }
  .rc-card        { max-width: none; }
}

@media (max-width: 61.999em) {

  /* ---- navigation becomes a panel ---- */
  .rc-nav-toggle { display: flex; }

  .rc-nav {
    position: fixed;
    top: var(--header-h);
    right: 0;
    bottom: 0;
    z-index: var(--z-nav);
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    gap: var(--sp-6);
    width: min(340px, 88vw);
    margin-left: 0;
    padding: var(--sp-6) var(--sp-5) var(--sp-10);
    overflow-y: auto;
    overscroll-behavior: contain;
    border-left: 1px solid var(--c-line);
    background: var(--c-canvas);
    box-shadow: var(--shadow-float);
    transform: translateX(100%);
    /* visibility keeps the links out of the tab order while parked — it is
       on the transition list, not switched instantly, so the panel is still
       visible while it slides away. */
    visibility: hidden;
    transition:
      transform  var(--dur-nav) var(--ease-nav),
      visibility var(--dur-nav) linear;
  }
  .rc-nav-state:checked ~ .rc-nav { transform: none; visibility: visible; }

  .rc-nav__list { flex-direction: column; align-items: stretch; gap: var(--sp-1); }
  .rc-nav__link { padding: var(--sp-3) var(--sp-4); border-radius: var(--r-sm); font-size: var(--fs-lead); }
  .rc-nav__link::after { display: none; }

  .rc-nav__actions { flex-direction: column; align-items: stretch; padding-top: var(--sp-5); border-top: 1px solid var(--c-line); }
  .rc-nav__actions .rc-btn { width: 100%; min-height: var(--control-h); font-size: var(--fs-cta); }

  .rc-nav-scrim { display: block; }
  .rc-nav-state:checked ~ .rc-nav-scrim { opacity: 1; visibility: visible; }

  /* ---- the two-column bands become one ----
     The business-insight band is NOT in this list. It splits later, at
     80em: half a 992px page is ~490px, and the product preview needs
     roughly 850 before its metric row stops being squeezed. See the
     min-width: 80em block at the end of this section. */
  .rc-hero__grid,
  .rc-cta__grid,
  .rc-contact__grid,
  .rc-about__row { grid-template-columns: minmax(0, 1fr); }

  /* ---- the hero is re-ordered, not just stacked ----
     One column, and the pieces run: eyebrow, headline, product, call to
     action. The product sits BETWEEN the headline and the button, which the
     DOM cannot give us directly — .rc-hero__art is a sibling of
     .rc-hero__copy because it is the second column on desktop.

     So the wrapper is dissolved with `display: contents` and its children
     become grid items in their own right, re-ordered with `order`. Two
     things to know if you touch this:

       · the selectors stay `.rc-hero__copy > …`. display:contents changes
         the box tree, not the DOM, so the child combinator still reads the
         real parent. Scoping matters here — a bare `.rc-eyebrow { order: 1 }`
         would send the eyebrow to the bottom of every other band on the page.
       · the column is centred. `justify-items: center` sizes the eyebrow
         pill and the button to their own content and centres them;
         `text-align: center` carries the headline with them. The two
         pieces that need the full column ask for it explicitly, and centre
         their contents rather than their boxes. */
  .rc-hero__copy { display: contents; }
  .rc-hero__grid {
    row-gap: var(--sp-6);
    justify-items: center;
    text-align: center;
  }
  .rc-hero__copy > .rc-eyebrow     { order: 1; }
  .rc-hero__copy > .rc-hero__title { order: 2; justify-self: stretch; }
  .rc-hero__copy > .rc-lockup      { order: 3; }
  .rc-hero__art                    { order: 4; justify-self: stretch; }
  .rc-hero__copy > .rc-btn         { order: 5; }

  /* The six service glyphs go. They are the widest thing in the hero and
     the first to push the call to action under the fold; the same six are
     the whole of the band immediately below, so nothing is actually lost. */
  .rc-hero__copy > .rc-servicebar { display: none; }

  /* The product is now mid-column rather than beside the copy, so it has to
     leave room for the button under it. */
  .rc-hero__stage { max-width: min(var(--hero-art-max), 74vw); }

  /* Mirroring two rows only reads as mirroring when they are side by side. */
  .rc-about__row--flip .rc-about__copy,
  .rc-about__row--flip .rc-about__media { order: 0; }

  /* ---- the contact copy goes full width and centres ----
     Same reasoning as the hero and the business-insight band: with the
     form below it rather than beside it, the copy has no second column to
     align against, so it sits on the page's axis.

     The headline's <br>s go with it — composed for the narrow desktop
     column, they would otherwise hold it to ~310px of a 900px row. */
  .rc-contact__copy { align-items: center; text-align: center; }
  .rc-contact__copy > .rc-eyebrow { align-self: center; }
  .rc-contact__title    { align-self: stretch; }
  .rc-contact__title br { display: none; }

  /* The cards keep their full width; it is their CONTENTS that centre.
     Left alone, each one is a 44px icon pinned to the left edge of a
     900px card with the rest empty. */
  .rc-contact-card,
  .rc-contact__note { justify-content: center; }

  /* The brand takes the full row and the offices pair up beneath it, two
     per row. A vertical rule is only meaningful when there is a column to
     its left, so every office that STARTS a row has to drop its own.

     Which ones those are is arithmetic, not guesswork: the brand spans the
     row on its own, so the offices begin in column 1 of the next row and
     alternate from there — :nth-child(2) column 1, (3) column 2, (4)
     column 1 again. Every even child opens a row. Stated that way the rule
     keeps working as offices are added or removed, which the old
     `.rc-footer__brand + .rc-footer__col` (only ever the first one) did
     not: a third office arrived and its border pointed at nothing. */
  .rc-footer__grid  { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .rc-footer__brand { grid-column: 1 / -1; padding-inline: 0; }
  .rc-footer__col:nth-child(even) { border-left: 0; padding-left: 0; }
}

@media (max-width: 47.999em) {

  .rc-offer__grid { grid-template-columns: minmax(0, 1fr); }


  /* A call to action that is the width of its own label reads as an
     afterthought on a phone. */
  .rc-hero__copy .rc-btn,
  .rc-cta__actions .rc-btn,
  .rc-insight__copy .rc-btn { width: 100%; }
  .rc-cta__actions { width: 100%; }
  .rc-form__submit { align-self: stretch; }

  .rc-form__row { grid-template-columns: minmax(0, 1fr); }
  .rc-field__group { flex-wrap: wrap; }
  .rc-field__group .rc-field__select { width: 100%; }
  .rc-field__group .rc-field__input { flex: 1 1 100%; }

  /* The banner art goes: at this width the illustration reaches across the
     whole band and the headline would sit on top of a shield. The gradient
     it was sampled from carries the band on its own. */
  .rc-legal-hero__art { display: none; }
  .rc-legal-hero__copy { max-width: none; }
  /* No number column to indent past once the head has wrapped. */
  .rc-accordion__body { padding-left: var(--sp-5); }

  .rc-cta__plane { display: none; }

  /* The footer stacks here, not at 30em: the longest address line ("512,
     5th Floor, 7953 Khalid Bin Walid Street,") needs ~285px, so two office
     columns want 650px of viewport before they stop wrapping mid-street.
     One column, and the vertical rule turns on its side to divide the
     blocks it can no longer sit between. */
  .rc-footer__grid { grid-template-columns: minmax(0, 1fr); row-gap: 0; }
  .rc-footer__col  { padding-inline: 0; }
  .rc-footer__col + .rc-footer__col {
    border-left: 0;
    border-top: 1px solid var(--c-line);
    margin-top: var(--sp-6);
    padding-top: var(--sp-6);
  }

  /* ---- and it centres, like every other single-column band ----
     Three things have to be told separately: the columns' text, the brand
     stack (a flex column pinned to flex-start), and the office name (a flex
     ROW, so it needs justify-content rather than align-items). */
  .rc-footer__col   { text-align: center; }
  .rc-footer__brand { align-items: center; }
  .rc-office__name  { justify-content: center; }

  .rc-footer__bar { justify-content: center; text-align: center; }
  .rc-footer__legal { justify-content: center; }
  /* The leading divider exists to separate the links from the copyright
     beside them. Stacked and centred there is nothing to its left, so it
     would hang off the front of the group. */
  .rc-footer__legal a:first-child { border-left: 0; }

  /* The dock goes icon-only. A labelled pill plus the round button is 228px
     — most of a 320px screen — sitting on top of the content. The label is
     clipped rather than removed, so the link keeps its accessible name. */
  .rc-dock__btn--enquiry { width: var(--dock-size); padding-inline: 0; }
  .rc-dock__label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  /* Four columns of two-word labels do not survive a phone. (The preview's
     own metric row is not here: it answers to a container query instead.) */
  .rc-highlights { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: none; }
}

/* ---------------------------------------------------------------------------
   Below the business-insight band's own split, its headline goes full width.

   The three lines of "Your Business. / At A Glance / On Riya Connect." are
   hard <br>s, composed for the narrow copy column of the two-column desktop
   band. Left in place they keep that shape in a column three times wider,
   so the headline sits in ~320px of a ~1200px row with the rest empty.
   Switching the breaks off lets the sentence wrap to whatever width it
   actually has — one line at 1200, two on a tablet, four on a phone.

   `align-self: stretch` because .rc-insight__copy is a flex column with
   align-items:flex-start, which otherwise shrink-wraps the h2 to its
   longest line rather than the column.
   ------------------------------------------------------------------------- */
@media (max-width: 79.999em) {
  .rc-insight__title    { align-self: stretch; }
  .rc-insight__title br { display: none; }

  /* And centred, the same way the hero is: once the band is a single
     column there is no second column for the copy to be left-aligned
     against, so it sits on the page's axis instead of hugging one edge. */
  .rc-insight__copy { align-items: center; text-align: center; }

  /* .rc-eyebrow pins itself with align-self:flex-start, for the flex
     columns it usually lives in. Here the container decides. */
  .rc-insight__copy > .rc-eyebrow { align-self: center; }

  /* Each highlight is its own flex column — the tile has to centre over
     its label, not just the group over the row. */
  .rc-highlight { align-items: center; }
}

/* ---------------------------------------------------------------------------
   Short screens, not narrow ones.

   Whether the re-ordered hero fits above the fold is a question about
   HEIGHT, and answering it with a width query punishes the wrong devices: a
   390x844 phone has 236px to spare, while a 320x568 one is 3px short. Keyed
   to width, the fix for the second shrinks the product on the first for no
   reason.

   So this is the one query on the page that asks about height. It catches
   the short phones and landscape-ish viewports and leaves everything else
   alone.
   ------------------------------------------------------------------------- */
@media (max-width: 61.999em) and (max-height: 700px) {
  .rc-hero__grid {
    row-gap: var(--sp-4);
    padding-block: var(--sp-5) var(--sp-6);
  }
  .rc-hero__stage { max-width: 56vw; }
}

/* ---------------------------------------------------------------------------
   The business-insight band splits at 80em (1280px) — later than every other
   split on the page.

   Why: it sets the copy beside a screenshot of a dashboard, and a dashboard
   shrunk to half a 992px page is 490px of unreadable four-point type. Below
   80em the preview takes the full content column instead, where the figures
   can actually be read. The split ratio leans the same way, 0.82/1.18: the
   copy is a headline, a line of lead and four small tiles and reads fine in
   ~500px, while every pixel the screenshot gains is legibility.
   ------------------------------------------------------------------------- */
@media (min-width: 80em) {
  .rc-insight__grid { grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr); }
}

@media (max-width: 29.999em) {
  .rc-stats { grid-template-columns: minmax(0, 1fr); }
  .rc-lockup { gap: var(--sp-3); }
  .rc-lockup__rule { display: none; }
  /* Two 140px columns cannot hold "Available On Mobile, Desktop Or Laptop". */
  .rc-tech__lane { grid-template-columns: minmax(0, 1fr); }


  /* At this width a button's label is wider than the screen allows, and a
     button is the one thing on the page that must never be cut off. Two
     centred lines is the honest answer; the type size stays put, because no
     breakpoint in this system resizes text. */
  .rc-btn {
    white-space: normal;
    text-align: center;
    line-height: var(--lh-snug);
    padding-block: var(--sp-3);
  }
}


/* =========================================================================
   16  REDUCED MOTION
   -------------------------------------------------------------------------
   Layer 2 already collapses every duration and travel token. What is left
   for this block is the two things a zero duration cannot stop: an infinite
   loop, and the marquee (which is switched off by not matching its
   `prefers-reduced-motion: no-preference` query, leaving the grid).
   ========================================================================= */

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

  .rc-hero__product,
  .rc-pulse::before {
    animation: none !important;
  }
  .rc-hero__flip { transition: none !important; }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
