/* =============================================================================
   RBNs Studio — marketing page stylesheet (self-contained / portable)

   This page is intentionally NOT coupled to the Podbits design system: it will
   eventually be lifted out to a standalone rbns.studio site with no build step.
   The bulk of this file is the compiled Tailwind utility + preflight layer that
   the approved mockup was authored against, appended verbatim below the
   extension layer. Fonts are loaded by templates/rbns_studio/base.html via a
   single Google Fonts request (Space Grotesk / Hanken Grotesk / JetBrains Mono
   / Newsreader) — the @font-face blocks from the mockup export (which pointed at
   dead blob: URLs) are deliberately omitted.

   PALETTE (hardcoded in the utility layer as literal rgb()):
     paper #FBFAF6 · ink #15140F · brand #12A06A · branddk #0B7A50
     accents → blue #2F6BD6 · violet #6B4DE0 · amber #C9881A · coral #EF6038
   ============================================================================= */

/* ---------------------------------------------------------------------------
   EXTENSION LAYER — utilities/components used by sections added on top of the
   mockup (real screenshots in browser frames, real logo walls, connector logos).
   Kept small and reuse-first; everything else comes from the compiled layer.
   --------------------------------------------------------------------------- */

/* Utility steps used by the added sections that the mockup's compiled subset
   happens not to include (the export only emitted classes the original markup
   used). Defining them here avoids silently-dead classes. */
/* single-column base for grids that hold a carousel: minmax(0,1fr) keeps the
   track at container width instead of letting the swiper's intrinsic content
   size an implicit auto track to millions of px below the lg: breakpoint. */
.grid-cols-1 { grid-template-columns: repeat(1, minmax(0, 1fr)); }
.gap-5 { gap: 1.25rem; }
.gap-3\.5 { gap: .875rem; }
.gap-x-6 { column-gap: 1.5rem; }
.gap-x-7 { column-gap: 1.75rem; }
.gap-y-3 { row-gap: .75rem; }
.mt-9 { margin-top: 2.25rem; }
.p-2 { padding: .5rem; }
.px-8 { padding-left: 2rem; padding-right: 2rem; }
.px-10 { padding-left: 2.5rem; padding-right: 2.5rem; }
@media (min-width: 640px) { .sm\:px-10 { padding-left: 2.5rem; padding-right: 2.5rem; } }
.text-\[13px\] { font-size: 13px; }
.text-\[22px\] { font-size: 22px; }
.text-paper\/50 { color: rgba(251, 250, 246, .5); }
.text-paper\/60 { color: rgba(251, 250, 246, .6); }

/* Utilities the animated Figma canvas (section 13) markup references but the
   mockup's compiled subset never emitted — that block was authored after the
   export, so its classes resolved to nothing. Most degraded quietly, but the
   missing col-span pair broke the panel outright below sm: with no
   `.col-span-4`/`.col-span-8`, both children fell back to `grid-column: auto`
   and took one 29px track each out of twelve, collapsing the layers rail and
   the canvas into the left ~80px of a 350px card. */
.col-span-4 { grid-column: span 4 / span 4; }
.col-span-8 { grid-column: span 8 / span 8; }
@media (min-width: 640px) { .sm\:col-span-3 { grid-column: span 3 / span 3; } }
/* the 92px phone frame is a flex item: it needs both the basis and the
   shrink-0, or a narrow canvas squeezes it to a sliver */
.w-\[92px\] { width: 92px; }
.shrink-0 { flex-shrink: 0; }
/* lets the component column shrink past its min-content on ~320px screens,
   where the fixed 92px frame + gap leaves it less room than its text needs */
.min-w-0 { min-width: 0; }
.w-4 { width: 1rem; }
.h-4 { height: 1rem; }
.h-11 { height: 2.75rem; }
.top-3 { top: 0.75rem; }
.right-3 { right: 0.75rem; }
.ml-3 { margin-left: 0.75rem; }
.mb-1\.5 { margin-bottom: 0.375rem; }
.pl-4 { padding-left: 1rem; }
.rounded-sm { border-radius: 0.125rem; }
.rounded-\[5px\] { border-radius: 5px; }
.text-\[8px\] { font-size: 8px; }
.text-\[8\.5px\] { font-size: 8.5px; }
.shadow-sm { --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color); box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); }
/* violet/mint steps at the duotone values (#6600ff / #ADFFBE), matching the
   !important overrides in section 2 rather than the compiled layer's #6B4DE0 */
.bg-violet\/10 { background-color: rgba(102, 0, 255, .10); }
.bg-violet\/50 { background-color: rgba(102, 0, 255, .50); }
.bg-mint\/60 { background-color: rgba(173, 255, 190, .6); }
.bg-ink\/20 { background-color: rgba(21, 20, 15, 0.2); }
.-space-x-1\.5 > :not([hidden]) ~ :not([hidden]) { --tw-space-x-reverse: 0; margin-right: calc(-0.375rem * var(--tw-space-x-reverse)); margin-left: calc(-0.375rem * calc(1 - var(--tw-space-x-reverse))); }

/* object-fit helpers (not in the compiled utility subset) */
.object-cover { object-fit: cover; }
.object-contain { object-fit: contain; }
.object-top { object-position: top; }
.object-left-top { object-position: left top; }
.object-center { object-position: center; }

/* aspect helpers for product screenshots */
.shot-16-10 { aspect-ratio: 16 / 10; }
.shot-3-2   { aspect-ratio: 3 / 2; }
.shot-1-1   { aspect-ratio: 1 / 1; }

/* screenshot frame: image fills the framed area, pinned to the top */
.shot { overflow: hidden; background: #fff; }
.shot img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top; }
.shot.contain img { object-fit: contain; object-position: center; background: #fff; }

/* real-logo "trusted by / worked at" wall — desaturated, lifts on hover.
   Height is fixed here (not via h-* utilities — the compiled subset doesn't
   include every step, and an unconstrained img scales to full container width). */
.logo-mark { height: 26px; width: auto; max-width: 160px; object-fit: contain; filter: grayscale(1); opacity: .55; transition: opacity .3s ease, filter .3s ease, transform .3s ease; }
.logo-mark:hover { filter: grayscale(0); opacity: 1; transform: translateY(-2px); }
@media (min-width: 640px) { .logo-mark { height: 32px; } }

/* connector marquee — real integration logos inside the existing .chip-logo chips */
.conn-logo { height: 20px; width: auto; object-fit: contain; }

/* brand "R." mark in the nav/footer (real logo, swaps the CSS diamond) */
.brand-r { height: 26px; width: auto; display: block; }

/* small screenshot thumbnail strip (ESCL gallery) */
.thumb { overflow: hidden; }
.thumb img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top; transition: transform .4s cubic-bezier(.2,.7,.2,1); }
.thumb:hover img { transform: scale(1.04); }

/* ---------------------------------------------------------------------------
   COMPILED LAYER — Tailwind preflight + utilities + bespoke component classes
   (appended from the approved mockup). Do not hand-edit; regenerate from source.
   --------------------------------------------------------------------------- */
*, ::before, ::after { --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; }
::backdrop { --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; --tw-contain-size: ; --tw-contain-layout: ; --tw-contain-paint: ; --tw-contain-style: ; }
*, ::after, ::before { box-sizing: border-box; border-width: 0px; border-style: solid; border-color: rgb(229, 231, 235); }
::after, ::before { --tw-content: ''; }
:host, html { line-height: 1.5; text-size-adjust: 100%; tab-size: 4; font-family: "Hanken Grotesk", sans-serif; font-feature-settings: normal; font-variation-settings: normal; -webkit-tap-highlight-color: transparent; }
body { margin: 0px; line-height: inherit; }
hr { height: 0px; color: inherit; border-top-width: 1px; }
abbr:where([title]) { text-decoration: underline dotted; }
h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: inherit; }
a { color: inherit; text-decoration: inherit; }
b, strong { font-weight: bolder; }
code, kbd, pre, samp { font-family: "JetBrains Mono", monospace; font-feature-settings: normal; font-variation-settings: normal; font-size: 1em; }
small { font-size: 80%; }
sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
sub { bottom: -0.25em; }
sup { top: -0.5em; }
table { text-indent: 0px; border-color: inherit; border-collapse: collapse; }
button, input, optgroup, select, textarea { font-family: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 100%; font-weight: inherit; line-height: inherit; letter-spacing: inherit; color: inherit; margin: 0px; padding: 0px; }
button, select { text-transform: none; }
button, input:where([type="button"]), input:where([type="reset"]), input:where([type="submit"]) { appearance: button; background-color: transparent; background-image: none; }
progress { vertical-align: baseline; }
::-webkit-inner-spin-button, ::-webkit-outer-spin-button { height: auto; }
[type="search"] { appearance: textfield; outline-offset: -2px; }
::-webkit-search-decoration { appearance: none; }
::-webkit-file-upload-button { appearance: button; font: inherit; }
summary { display: list-item; }
blockquote, dd, dl, figure, h1, h2, h3, h4, h5, h6, hr, p, pre { margin: 0px; }
fieldset { margin: 0px; padding: 0px; }
legend { padding: 0px; }
menu, ol, ul { list-style: none; margin: 0px; padding: 0px; }
dialog { padding: 0px; }
textarea { resize: vertical; }
input::placeholder, textarea::placeholder { opacity: 1; color: rgb(156, 163, 175); }
[role="button"], button { cursor: pointer; }
:disabled { cursor: default; }
audio, canvas, embed, iframe, img, object, svg, video { display: block; vertical-align: middle; }
img, video { max-width: 100%; height: auto; }
[hidden]:where(:not([hidden="until-found"])) { display: none; }
.pointer-events-none { pointer-events: none; }
.fixed { position: fixed; }
.absolute { position: absolute; }
.relative { position: relative; }
.-inset-4 { inset: -1rem; }
.inset-0 { inset: 0px; }
.inset-x-0 { left: 0px; right: 0px; }
.inset-y-0 { top: 0px; bottom: 0px; }
.-bottom-32 { bottom: -8rem; }
.-bottom-6 { bottom: -1.5rem; }
.-left-24 { left: -6rem; }
.-left-4 { left: -1rem; }
.-right-20 { right: -5rem; }
.-right-3 { right: -0.75rem; }
.-top-28 { top: -7rem; }
.-top-4 { top: -1rem; }
.right-0 { right: 0px; }
.right-44 { right: 11rem; }
.top-0 { top: 0px; }
.top-44 { top: 11rem; }
.left-0 { left: 0px; }
.top-\[15px\] { top: 15px; }
.-right-10 { right: -2.5rem; }
.-top-20 { top: -5rem; }
.z-10 { z-index: 10; }
.z-50 { z-index: 50; }
.order-1 { order: 1; }
.order-2 { order: 2; }
.col-span-2 { grid-column: span 2 / span 2; }
.col-span-3 { grid-column: span 3 / span 3; }
.col-span-5 { grid-column: span 5 / span 5; }
.col-span-9 { grid-column: span 9 / span 9; }
.col-span-12 { grid-column: span 12 / span 12; }
.mx-auto { margin-left: auto; margin-right: auto; }
.-mr-1 { margin-right: -0.25rem; }
.mb-1 { margin-bottom: 0.25rem; }
.mb-2 { margin-bottom: 0.5rem; }
.mb-3 { margin-bottom: 0.75rem; }
.mb-4 { margin-bottom: 1rem; }
.mb-5 { margin-bottom: 1.25rem; }
.mb-6 { margin-bottom: 1.5rem; }
.ml-2 { margin-left: 0.5rem; }
.ml-auto { margin-left: auto; }
.mt-0\.5 { margin-top: 0.125rem; }
.mt-1 { margin-top: 0.25rem; }
.mt-10 { margin-top: 2.5rem; }
.mt-2 { margin-top: 0.5rem; }
.mt-3 { margin-top: 0.75rem; }
.mt-4 { margin-top: 1rem; }
.mt-5 { margin-top: 1.25rem; }
.mt-6 { margin-top: 1.5rem; }
.mt-7 { margin-top: 1.75rem; }
.mt-8 { margin-top: 2rem; }
.mb-10 { margin-bottom: 2.5rem; }
.mt-1\.5 { margin-top: 0.375rem; }
.mt-12 { margin-top: 3rem; }
.mt-14 { margin-top: 3.5rem; }
.mb-2\.5 { margin-bottom: 0.625rem; }
.ml-1\.5 { margin-left: 0.375rem; }
.block { display: block; }
.inline-block { display: inline-block; }
.flex { display: flex; }
.inline-flex { display: inline-flex; }
.grid { display: grid; }
.hidden { display: none; }
.aspect-\[4\/3\] { aspect-ratio: 4 / 3; }
.aspect-\[5\/4\] { aspect-ratio: 5 / 4; }
.h-1\.5 { height: 0.375rem; }
.h-16 { height: 4rem; }
.h-2 { height: 0.5rem; }
.h-2\.5 { height: 0.625rem; }
.h-3\.5 { height: 0.875rem; }
.h-6 { height: 1.5rem; }
.h-7 { height: 1.75rem; }
.h-8 { height: 2rem; }
.h-9 { height: 2.25rem; }
.h-\[150px\] { height: 150px; }
.h-\[300px\] { height: 300px; }
.h-\[420px\] { height: 420px; }
.h-\[440px\] { height: 440px; }
.h-\[460px\] { height: 460px; }
.h-px { height: 1px; }
.h-\[64px\] { height: 64px; }
.h-1 { height: 0.25rem; }
.h-52 { height: 13rem; }
.h-\[360px\] { height: 360px; }
.w-1\.5 { width: 0.375rem; }
.w-1\/2 { width: 50%; }
.w-1\/3 { width: 33.3333%; }
.w-2 { width: 0.5rem; }
.w-2\.5 { width: 0.625rem; }
.w-2\/3 { width: 66.6667%; }
.w-3\.5 { width: 0.875rem; }
.w-3\/4 { width: 75%; }
.w-4\/5 { width: 80%; }
.w-5 { width: 1.25rem; }
.w-5\/6 { width: 83.3333%; }
.w-6 { width: 1.5rem; }
.w-7 { width: 1.75rem; }
.w-9 { width: 2.25rem; }
.w-\[230px\] { width: 230px; }
.w-\[300px\] { width: 300px; }
.w-\[420px\] { width: 420px; }
.w-\[440px\] { width: 440px; }
.w-\[460px\] { width: 460px; }
.w-\[96px\] { width: 96px; }
.w-full { width: 100%; }
.w-8 { width: 2rem; }
.w-fit { width: fit-content; }
.w-1 { width: 0.25rem; }
.w-\[360px\] { width: 360px; }
.max-w-2xl { max-width: 42rem; }
.max-w-3xl { max-width: 48rem; }
.max-w-\[36rem\] { max-width: 36rem; }
.max-w-container { max-width: 1200px; }
.max-w-md { max-width: 28rem; }
.max-w-xl { max-width: 36rem; }
.max-w-lg { max-width: 32rem; }
.max-w-xs { max-width: 20rem; }
.flex-1 { flex: 1 1 0%; }
.rotate-45 { --tw-rotate: 45deg; transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); }
@keyframes pulse { 
  50% { opacity: 0.5; }
}
.animate-pulse { animation: 2s cubic-bezier(0.4, 0, 0.6, 1) 0s infinite normal none running pulse; }
.grid-cols-12 { grid-template-columns: repeat(12, minmax(0px, 1fr)); }
.grid-cols-2 { grid-template-columns: repeat(2, minmax(0px, 1fr)); }
.grid-cols-4 { grid-template-columns: repeat(4, minmax(0px, 1fr)); }
.flex-col { flex-direction: column; }
.flex-wrap { flex-wrap: wrap; }
.items-end { align-items: flex-end; }
.items-center { align-items: center; }
.justify-center { justify-content: center; }
.justify-between { justify-content: space-between; }
.gap-1 { gap: 0.25rem; }
.gap-1\.5 { gap: 0.375rem; }
.gap-10 { gap: 2.5rem; }
.gap-12 { gap: 3rem; }
.gap-2 { gap: 0.5rem; }
.gap-2\.5 { gap: 0.625rem; }
.gap-3 { gap: 0.75rem; }
.gap-7 { gap: 1.75rem; }
.gap-\[5px\] { gap: 5px; }
.gap-8 { gap: 2rem; }
.gap-4 { gap: 1rem; }
.gap-x-5 { column-gap: 1.25rem; }
.gap-x-9 { column-gap: 2.25rem; }
.gap-y-2 { row-gap: 0.5rem; }
.gap-y-4 { row-gap: 1rem; }
.gap-x-3 { column-gap: 0.75rem; }
.gap-y-8 { row-gap: 2rem; }
.space-y-1\.5 > :not([hidden]) ~ :not([hidden]) { --tw-space-y-reverse: 0; margin-top: calc(0.375rem * calc(1 - var(--tw-space-y-reverse))); margin-bottom: calc(0.375rem * var(--tw-space-y-reverse)); }
.space-y-2 > :not([hidden]) ~ :not([hidden]) { --tw-space-y-reverse: 0; margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse))); margin-bottom: calc(0.5rem * var(--tw-space-y-reverse)); }
.space-y-3 > :not([hidden]) ~ :not([hidden]) { --tw-space-y-reverse: 0; margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse))); margin-bottom: calc(0.75rem * var(--tw-space-y-reverse)); }
.space-y-2\.5 > :not([hidden]) ~ :not([hidden]) { --tw-space-y-reverse: 0; margin-top: calc(0.625rem * calc(1 - var(--tw-space-y-reverse))); margin-bottom: calc(0.625rem * var(--tw-space-y-reverse)); }
.space-y-1 > :not([hidden]) ~ :not([hidden]) { --tw-space-y-reverse: 0; margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse))); margin-bottom: calc(0.25rem * var(--tw-space-y-reverse)); }
.overflow-hidden { overflow: hidden; }
.scroll-smooth { scroll-behavior: smooth; }
.rounded { border-radius: 0.25rem; }
.rounded-2xl { border-radius: 1rem; }
.rounded-\[22px\] { border-radius: 22px; }
.rounded-\[30px\] { border-radius: 30px; }
.rounded-\[3px\] { border-radius: 3px; }
.rounded-full { border-radius: 9999px; }
.rounded-lg { border-radius: 0.5rem; }
.rounded-md { border-radius: 0.375rem; }
.rounded-xl { border-radius: 0.75rem; }
.rounded-3xl { border-radius: 1.5rem; }
.rounded-t { border-top-left-radius: 0.25rem; border-top-right-radius: 0.25rem; }
.border { border-width: 1px; }
.border-y { border-top-width: 1px; border-bottom-width: 1px; }
.border-b { border-bottom-width: 1px; }
.border-r { border-right-width: 1px; }
.border-t { border-top-width: 1px; }
.border-b-2 { border-bottom-width: 2px; }
.border-brand\/20 { border-color: rgba(18, 160, 106, 0.2); }
.border-ink\/10 { border-color: rgba(21, 20, 15, 0.1); }
.border-line { --tw-border-opacity: 1; border-color: rgb(231 225 212 / var(--tw-border-opacity, 1)); }
.border-line\/60 { border-color: rgba(231, 225, 212, 0.6); }
.border-line\/70 { border-color: rgba(231, 225, 212, 0.7); }
.border-white\/10 { border-color: rgba(255, 255, 255, 0.1); }
.border-white\/15 { border-color: rgba(255, 255, 255, 0.15); }
.border-ink\/20 { border-color: rgba(21, 20, 15, 0.2); }
.border-brand { --tw-border-opacity: 1; border-color: rgb(18 160 106 / var(--tw-border-opacity, 1)); }
.border-white\/20 { border-color: rgba(255, 255, 255, 0.2); }
.border-white\/40 { border-color: rgba(255, 255, 255, 0.4); }
.bg-amber { --tw-bg-opacity: 1; background-color: rgb(201 136 26 / var(--tw-bg-opacity, 1)); }
.bg-amber\/50 { background-color: rgba(201, 136, 26, 0.5); }
.bg-amber\/70 { background-color: rgba(201, 136, 26, 0.7); }
.bg-ambersoft { --tw-bg-opacity: 1; background-color: rgb(249 238 207 / var(--tw-bg-opacity, 1)); }
.bg-ambersoft\/60 { background-color: rgba(249, 238, 207, 0.6); }
.bg-blue { --tw-bg-opacity: 1; background-color: rgb(47 107 214 / var(--tw-bg-opacity, 1)); }
.bg-blue\/30 { background-color: rgba(47, 107, 214, 0.3); }
.bg-bluesoft { --tw-bg-opacity: 1; background-color: rgb(229 236 251 / var(--tw-bg-opacity, 1)); }
.bg-bluesoft\/60 { background-color: rgba(229, 236, 251, 0.6); }
.bg-brand { --tw-bg-opacity: 1; background-color: rgb(18 160 106 / var(--tw-bg-opacity, 1)); }
.bg-brand\/20 { background-color: rgba(18, 160, 106, 0.2); }
.bg-brand\/70 { background-color: rgba(18, 160, 106, 0.7); }
.bg-brandsoft { --tw-bg-opacity: 1; background-color: rgb(225 242 233 / var(--tw-bg-opacity, 1)); }
.bg-brandsoft\/60 { background-color: rgba(225, 242, 233, 0.6); }
.bg-brandsoft\/70 { background-color: rgba(225, 242, 233, 0.7); }
.bg-coral { --tw-bg-opacity: 1; background-color: rgb(239 96 56 / var(--tw-bg-opacity, 1)); }
.bg-coral\/70 { background-color: rgba(239, 96, 56, 0.7); }
.bg-coralsoft { --tw-bg-opacity: 1; background-color: rgb(252 230 220 / var(--tw-bg-opacity, 1)); }
.bg-coralsoft\/60 { background-color: rgba(252, 230, 220, 0.6); }
.bg-deep { --tw-bg-opacity: 1; background-color: rgb(12 61 42 / var(--tw-bg-opacity, 1)); }
.bg-ink { --tw-bg-opacity: 1; background-color: rgb(21 20 15 / var(--tw-bg-opacity, 1)); }
.bg-ink\/10 { background-color: rgba(21, 20, 15, 0.1); }
.bg-ink\/15 { background-color: rgba(21, 20, 15, 0.15); }
.bg-mist { --tw-bg-opacity: 1; background-color: rgb(242 239 231 / var(--tw-bg-opacity, 1)); }
.bg-paper { --tw-bg-opacity: 1; background-color: rgb(251 250 246 / var(--tw-bg-opacity, 1)); }
.bg-paper\/40 { background-color: rgba(251, 250, 246, 0.4); }
.bg-paper\/70 { background-color: rgba(251, 250, 246, 0.7); }
.bg-paper\/85 { background-color: rgba(251, 250, 246, 0.85); }
.bg-surface { --tw-bg-opacity: 1; background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1)); }
.bg-violet { --tw-bg-opacity: 1; background-color: rgb(107 77 224 / var(--tw-bg-opacity, 1)); }
.bg-violet\/30 { background-color: rgba(107, 77, 224, 0.3); }
.bg-violet\/40 { background-color: rgba(107, 77, 224, 0.4); }
.bg-violet\/60 { background-color: rgba(107, 77, 224, 0.6); }
.bg-violet\/70 { background-color: rgba(107, 77, 224, 0.7); }
.bg-violetsoft { --tw-bg-opacity: 1; background-color: rgb(236 230 251 / var(--tw-bg-opacity, 1)); }
.bg-violetsoft\/60 { background-color: rgba(236, 230, 251, 0.6); }
.bg-white { --tw-bg-opacity: 1; background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1)); }
.bg-white\/40 { background-color: rgba(255, 255, 255, 0.4); }
.bg-black\/30 { background-color: rgba(0, 0, 0, 0.3); }
.bg-white\/\[0\.03\] { background-color: rgba(255, 255, 255, 0.03); }
.bg-amber\/30 { background-color: rgba(201, 136, 26, 0.3); }
.bg-ambersoft\/40 { background-color: rgba(249, 238, 207, 0.4); }
.bg-bluesoft\/40 { background-color: rgba(229, 236, 251, 0.4); }
.bg-brandsoft\/40 { background-color: rgba(225, 242, 233, 0.4); }
.bg-violetsoft\/40 { background-color: rgba(236, 230, 251, 0.4); }
.bg-deep\/40 { background-color: rgba(12, 61, 42, 0.4); }
.bg-white\/10 { background-color: rgba(255, 255, 255, 0.1); }
.bg-\[repeating-linear-gradient\(0deg\,\#0000_0_22px\,\#0000_22px\)\,radial-gradient\(\#e7e1d4_1px\,transparent_1px\)\] { background-image: repeating-linear-gradient(0deg, rgba(0, 0, 0, 0) 0px, rgba(0, 0, 0, 0) 22px, rgba(0, 0, 0, 0) 22px), radial-gradient(rgb(231, 225, 212) 1px, transparent 1px); }
.bg-gradient-to-tr { background-image: linear-gradient(to top right, var(--tw-gradient-stops)); }
.from-brand\/20 { --tw-gradient-from: rgb(18 160 106 / 0.2) var(--tw-gradient-from-position); --tw-gradient-to: rgb(18 160 106 / 0) var(--tw-gradient-to-position); --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); }
.via-transparent { --tw-gradient-to: rgb(0 0 0 / 0)  var(--tw-gradient-to-position); --tw-gradient-stops: var(--tw-gradient-from), transparent var(--tw-gradient-via-position), var(--tw-gradient-to); }
.to-mint\/40 { --tw-gradient-to: rgb(127 217 174 / 0.4) var(--tw-gradient-to-position); }
.p-2\.5 { padding: 0.625rem; }
.p-3 { padding: 0.75rem; }
.p-4 { padding: 1rem; }
.p-5 { padding: 1.25rem; }
.p-6 { padding: 1.5rem; }
.p-7 { padding: 1.75rem; }
.p-3\.5 { padding: 0.875rem; }
.p-8 { padding: 2rem; }
.px-1\.5 { padding-left: 0.375rem; padding-right: 0.375rem; }
.px-2\.5 { padding-left: 0.625rem; padding-right: 0.625rem; }
.px-3 { padding-left: 0.75rem; padding-right: 0.75rem; }
.px-4 { padding-left: 1rem; padding-right: 1rem; }
.px-5 { padding-left: 1.25rem; padding-right: 1.25rem; }
.px-6 { padding-left: 1.5rem; padding-right: 1.5rem; }
.py-0\.5 { padding-top: 0.125rem; padding-bottom: 0.125rem; }
.py-1 { padding-top: 0.25rem; padding-bottom: 0.25rem; }
.py-1\.5 { padding-top: 0.375rem; padding-bottom: 0.375rem; }
.py-2 { padding-top: 0.5rem; padding-bottom: 0.5rem; }
.py-2\.5 { padding-top: 0.625rem; padding-bottom: 0.625rem; }
.py-20 { padding-top: 5rem; padding-bottom: 5rem; }
.py-3 { padding-top: 0.75rem; padding-bottom: 0.75rem; }
.py-3\.5 { padding-top: 0.875rem; padding-bottom: 0.875rem; }
.py-4 { padding-top: 1rem; padding-bottom: 1rem; }
.py-7 { padding-top: 1.75rem; padding-bottom: 1.75rem; }
.px-2 { padding-left: 0.5rem; padding-right: 0.5rem; }
.px-1 { padding-left: 0.25rem; padding-right: 0.25rem; }
.px-3\.5 { padding-left: 0.875rem; padding-right: 0.875rem; }
.py-12 { padding-top: 3rem; padding-bottom: 3rem; }
.pb-16 { padding-bottom: 4rem; }
.pl-2\.5 { padding-left: 0.625rem; }
.pr-3 { padding-right: 0.75rem; }
.pt-28 { padding-top: 7rem; }
.pb-10 { padding-bottom: 2.5rem; }
.pb-3 { padding-bottom: 0.75rem; }
.pt-16 { padding-top: 4rem; }
.pb-1 { padding-bottom: 0.25rem; }
.pt-6 { padding-top: 1.5rem; }
.text-center { text-align: center; }
.text-right { text-align: right; }
.font-sans { font-family: "Hanken Grotesk", sans-serif; }
.font-display { font-family: "Space Grotesk", sans-serif; }
.font-mono { font-family: "JetBrains Mono", monospace; }
.text-\[10px\] { font-size: 10px; }
.text-\[11px\] { font-size: 11px; }
.text-\[12\.5px\] { font-size: 12.5px; }
.text-\[12px\] { font-size: 12px; }
.text-\[13\.5px\] { font-size: 13.5px; }
.text-\[14px\] { font-size: 14px; }
.text-\[15px\] { font-size: 15px; }
.text-\[16\.5px\] { font-size: 16.5px; }
.text-\[16px\] { font-size: 16px; }
.text-\[17px\] { font-size: 17px; }
.text-\[30px\] { font-size: 30px; }
.text-\[32px\] { font-size: 32px; }
.text-\[34px\] { font-size: 34px; }
.text-\[40px\] { font-size: 40px; }
.text-\[9\.5px\] { font-size: 9.5px; }
.text-\[9px\] { font-size: 9px; }
.text-\[14\.5px\] { font-size: 14.5px; }
.text-\[24px\] { font-size: 24px; }
.text-\[10\.5px\] { font-size: 10.5px; }
.text-\[18px\] { font-size: 18px; }
.text-\[28px\] { font-size: 28px; }
.text-\[26px\] { font-size: 26px; }
.font-bold { font-weight: 700; }
.font-medium { font-weight: 500; }
.font-normal { font-weight: 400; }
.font-semibold { font-weight: 600; }
.not-italic { font-style: normal; }
.leading-\[1\.03\] { line-height: 1.03; }
.leading-\[1\.04\] { line-height: 1.04; }
.leading-\[1\.05\] { line-height: 1.05; }
.leading-\[1\.0\] { line-height: 1; }
.leading-relaxed { line-height: 1.625; }
.leading-snug { line-height: 1.375; }
.leading-tight { line-height: 1.25; }
.leading-\[1\.08\] { line-height: 1.08; }
.leading-none { line-height: 1; }
.tracking-\[0\.05em\] { letter-spacing: 0.05em; }
.tracking-tight { letter-spacing: -0.025em; }
.text-amber { --tw-text-opacity: 1; color: rgb(201 136 26 / var(--tw-text-opacity, 1)); }
.text-blue { --tw-text-opacity: 1; color: rgb(47 107 214 / var(--tw-text-opacity, 1)); }
.text-brand { --tw-text-opacity: 1; color: rgb(18 160 106 / var(--tw-text-opacity, 1)); }
.text-branddk { --tw-text-opacity: 1; color: rgb(11 122 80 / var(--tw-text-opacity, 1)); }
.text-coral { --tw-text-opacity: 1; color: rgb(239 96 56 / var(--tw-text-opacity, 1)); }
.text-inksoft { --tw-text-opacity: 1; color: rgb(88 82 73 / var(--tw-text-opacity, 1)); }
.text-inksoft\/75 { color: rgba(88, 82, 73, 0.75); }
.text-muted { --tw-text-opacity: 1; color: rgb(142 135 122 / var(--tw-text-opacity, 1)); }
.text-paper { --tw-text-opacity: 1; color: rgb(251 250 246 / var(--tw-text-opacity, 1)); }
.text-paper\/65 { color: rgba(251, 250, 246, 0.65); }
.text-paper\/90 { color: rgba(251, 250, 246, 0.9); }
.text-violet { --tw-text-opacity: 1; color: rgb(107 77 224 / var(--tw-text-opacity, 1)); }
.text-white { --tw-text-opacity: 1; color: rgb(255 255 255 / var(--tw-text-opacity, 1)); }
.text-paper\/40 { color: rgba(251, 250, 246, 0.4); }
.text-paper\/75 { color: rgba(251, 250, 246, 0.75); }
.text-paper\/85 { color: rgba(251, 250, 246, 0.85); }
.text-ink { --tw-text-opacity: 1; color: rgb(21 20 15 / var(--tw-text-opacity, 1)); }
.text-paper\/45 { color: rgba(251, 250, 246, 0.45); }
.text-white\/55 { color: rgba(255, 255, 255, 0.55); }
.text-white\/60 { color: rgba(255, 255, 255, 0.6); }
.text-white\/70 { color: rgba(255, 255, 255, 0.7); }
.text-white\/80 { color: rgba(255, 255, 255, 0.8); }
.text-white\/85 { color: rgba(255, 255, 255, 0.85); }
.text-white\/95 { color: rgba(255, 255, 255, 0.95); }
.antialiased { -webkit-font-smoothing: antialiased; }
.opacity-\[0\.12\] { opacity: 0.12; }
.shadow-\[0_8px_30px_-18px_rgba\(21\,20\,15\,\.4\)\] { --tw-shadow: 0 8px 30px -18px rgba(21,20,15,.4); --tw-shadow-colored: 0 8px 30px -18px var(--tw-shadow-color); box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); }
.shadow-lg { --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); }
.ring-2 { --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); }
.ring-violet\/30 { --tw-ring-color: rgb(107 77 224 / 0.3); }
.blur-2xl { --tw-blur: blur(40px); filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); }
.backdrop-blur-md { --tw-backdrop-blur: blur(12px); backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); }
.backdrop-blur-sm { --tw-backdrop-blur: blur(4px); backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); }
.transition-colors { transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, -webkit-text-decoration-color; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; }
.transition-transform { transition-property: transform; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; }
.duration-300 { transition-duration: 300ms; }
.\[background-size\:18px_18px\] { background-size: 18px 18px; }
.\[mask-image\:radial-gradient\(ellipse_at_top_left\,\#000\,transparent_65\%\)\] { -webkit-mask-image: radial-gradient(at left top, rgb(0, 0, 0), transparent 65%); mask-image: radial-gradient(at left top, rgb(0, 0, 0), transparent 65%); }
.\[mask-image\:radial-gradient\(ellipse_at_top_right\,\#000_0\%\,transparent_62\%\)\] { -webkit-mask-image: radial-gradient(at right top, rgb(0, 0, 0) 0%, transparent 62%); mask-image: radial-gradient(at right top, rgb(0, 0, 0) 0%, transparent 62%); }
.hover\:border-ink:hover { --tw-border-opacity: 1; border-color: rgb(21 20 15 / var(--tw-border-opacity, 1)); }
.hover\:bg-paper:hover { --tw-bg-opacity: 1; background-color: rgb(251 250 246 / var(--tw-bg-opacity, 1)); }
.hover\:bg-white\/10:hover { background-color: rgba(255, 255, 255, 0.1); }
.hover\:text-ink:hover { --tw-text-opacity: 1; color: rgb(21 20 15 / var(--tw-text-opacity, 1)); }
.hover\:text-paper:hover { --tw-text-opacity: 1; color: rgb(251 250 246 / var(--tw-text-opacity, 1)); }
.group:hover .group-hover\:rotate-0 { --tw-rotate: 0deg; transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); }
@media (min-width: 640px) {
  .sm\:-right-6 { right: -1.5rem; }
  .sm\:col-span-1 { grid-column: span 1 / span 1; }
  .sm\:col-span-9 { grid-column: span 9 / span 9; }
  .sm\:flex { display: flex; }
  .sm\:inline-flex { display: inline-flex; }
  .sm\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0px, 1fr)); }
  .sm\:grid-cols-4 { grid-template-columns: repeat(4, minmax(0px, 1fr)); }
  .sm\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0px, 1fr)); }
  .sm\:flex-row { flex-direction: row; }
  .sm\:p-5 { padding: 1.25rem; }
  .sm\:p-8 { padding: 2rem; }
  .sm\:p-10 { padding: 2.5rem; }
  .sm\:p-9 { padding: 2.25rem; }
  .sm\:p-7 { padding: 1.75rem; }
  .sm\:p-14 { padding: 3.5rem; }
  .sm\:px-5 { padding-left: 1.25rem; padding-right: 1.25rem; }
  .sm\:px-8 { padding-left: 2rem; padding-right: 2rem; }
  .sm\:py-24 { padding-top: 6rem; padding-bottom: 6rem; }
  .sm\:py-28 { padding-top: 7rem; padding-bottom: 7rem; }
  .sm\:pt-36 { padding-top: 9rem; }
  .sm\:pt-20 { padding-top: 5rem; }
  .sm\:text-\[18px\] { font-size: 18px; }
  .sm\:text-\[40px\] { font-size: 40px; }
  .sm\:text-\[44px\] { font-size: 44px; }
  .sm\:text-\[46px\] { font-size: 46px; }
  .sm\:text-\[56px\] { font-size: 56px; }
  .sm\:text-\[36px\] { font-size: 36px; }
  .sm\:text-\[31px\] { font-size: 31px; }
}
@media (min-width: 768px) {
  .md\:col-span-1 { grid-column: span 1 / span 1; }
  .md\:mt-16 { margin-top: 4rem; }
  .md\:flex { display: flex; }
  .md\:hidden { display: none; }
  .md\:grid-cols-5 { grid-template-columns: repeat(5, minmax(0px, 1fr)); }
  .md\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0px, 1fr)); }
  .md\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0px, 1fr)); }
}
@media (min-width: 1024px) {
  .lg\:order-1 { order: 1; }
  .lg\:order-2 { order: 2; }
  .lg\:col-span-6 { grid-column: span 6 / span 6; }
  .lg\:col-span-2 { grid-column: span 2 / span 2; }
  .lg\:col-span-5 { grid-column: span 5 / span 5; }
  .lg\:col-span-7 { grid-column: span 7 / span 7; }
  .lg\:grid-cols-12 { grid-template-columns: repeat(12, minmax(0px, 1fr)); }
  .lg\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0px, 1fr)); }
  .lg\:grid-cols-4 { grid-template-columns: repeat(4, minmax(0px, 1fr)); }
  .lg\:grid-cols-7 { grid-template-columns: repeat(7, minmax(0px, 1fr)); }
  .lg\:gap-10 { gap: 2.5rem; }
  .lg\:border-l { border-left-width: 1px; }
  .lg\:border-t-0 { border-top-width: 0px; }
  .lg\:text-\[60px\] { font-size: 60px; }
}

.whitespace-nowrap { white-space: nowrap; }
@media (min-width: 1024px) {
  .lg\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0px, 1fr)); }
}

  body { background:#FBFAF6; color:#15140F; font-family:"Hanken Grotesk",sans-serif; -webkit-font-smoothing:antialiased; }
  .font-display { letter-spacing:-0.025em; }
  h1,h2,h3 { text-wrap:balance; }
  p { text-wrap:pretty; }
  .eyebrow { font-family:"JetBrains Mono",monospace; font-size:11px; letter-spacing:0.16em; text-transform:uppercase; }
  .ital { font-family:"Newsreader",serif; font-style:italic; font-weight:400; letter-spacing:-0.01em; }
  .pill { font-family:"JetBrains Mono",monospace; font-size:10.5px; letter-spacing:0.1em; text-transform:uppercase; font-weight:500; }

  .reveal { opacity:0; }
  .reveal.in { opacity:1; animation:revealRise .7s cubic-bezier(.2,.7,.2,1); }
  .reveal.in[data-d="1"]{ animation-delay:.08s } .reveal.in[data-d="2"]{ animation-delay:.16s } .reveal.in[data-d="3"]{ animation-delay:.24s }
  @keyframes revealRise { from{ transform:translateY(18px); } to{ transform:none; } }
  @media (prefers-reduced-motion: reduce){ .reveal{ opacity:1; } .reveal.in{ animation:none; } }

  .flow-line { stroke-dasharray:4 5; animation:dashmove 1.1s linear infinite; }
  @keyframes dashmove { to { stroke-dashoffset:-18; } }

  .logrow { opacity:.25; transform:translateX(-4px); transition:opacity .45s ease, transform .45s ease; }
  .in .logrow { opacity:1; transform:none; }
  .in .logrow[data-r="1"]{ transition-delay:.15s } .in .logrow[data-r="2"]{ transition-delay:.3s } .in .logrow[data-r="3"]{ transition-delay:.45s } .in .logrow[data-r="4"]{ transition-delay:.6s }

  .pipe-track .pipe-fill { width:0; transition: width 2s cubic-bezier(.4,0,.2,1); }
  .pipe-track.in .pipe-fill { width:100%; }
  .pipe-node { transition: background-color .4s ease, color .4s ease, border-color .4s ease, transform .35s ease; }

  .card-hover { transition: transform .35s cubic-bezier(.2,.7,.2,1), box-shadow .35s ease; }
  .card-hover:hover { transform:translateY(-4px); box-shadow:0 22px 48px -28px rgba(21,20,15,.4); }

  .btn-brand { background:#12A06A; color:#fff; transition:transform .2s, background-color .2s, box-shadow .2s; box-shadow:0 8px 20px -10px rgba(18,160,106,.7); }
  .btn-brand:hover { background:#0B7A50; transform:translateY(-1px); }
  .link-u { background-image:linear-gradient(currentColor,currentColor); background-size:0% 1.5px; background-position:0 100%; background-repeat:no-repeat; transition:background-size .3s ease; }
  .link-u:hover { background-size:100% 1.5px; }

  .float { animation:floaty 7s ease-in-out infinite; } .float2 { animation:floaty 9s ease-in-out infinite; }
  @keyframes floaty { 0%,100%{transform:translateY(0)} 50%{transform:translateY(-9px)} }
  .blob { filter:blur(48px); border-radius:9999px; }
  .hairline { border:1px solid #E7E1D4; }
  .grain { background-image:radial-gradient(#15140f0a 1px, transparent 1px); background-size:22px 22px; }
  ::selection { background:#12A06A; color:#fff; }

  /* image placeholder */
  .ph { background:repeating-linear-gradient(135deg,#EFEBE0 0 11px,#F6F3EB 11px 22px); position:relative; }
  .ph::after { content:attr(data-label); position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
    font-family:"JetBrains Mono",monospace; font-size:11px; color:#8E877A; background:rgba(251,250,246,.92);
    border:1px solid #E7E1D4; border-radius:7px; padding:5px 10px; white-space:nowrap; }
  .win-shadow { box-shadow:0 34px 80px -42px rgba(21,20,15,.5); }

  /* ---- infinite connector marquee ---- */
  .marquee-wrap { -webkit-mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent); mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent); }
  .marquee { display:flex; width:max-content; gap:12px; animation:marq 40s linear infinite; }
  .marquee.rev { animation-direction:reverse; animation-duration:48s; }
  .marquee-wrap:hover .marquee { animation-play-state:paused; }
  @keyframes marq { to { transform:translateX(-50%); } }
  .chip-logo { display:flex; align-items:center; gap:9px; white-space:nowrap; }

  /* ---- layer-card mini diagrams (play on hover / in-view) ---- */
  .mini .a { animation-play-state:paused; }
  .layer-card:hover .mini .a, .layer-card.playing .mini .a { animation-play-state:running; }
  .layer-card .mini { transition:transform .35s cubic-bezier(.2,.7,.2,1); }
  .layer-card:hover .mini { transform:translateY(-2px); }
  @keyframes growW { 0%,100%{ width:35%; } 50%{ width:92%; } }
  @keyframes barUp { 0%,100%{ height:25%; } 50%{ height:100%; } }
  @keyframes blink { 0%,100%{ opacity:1; } 50%{ opacity:.12; } }
  @keyframes ringp { 0%{ transform:scale(.4); opacity:.7; } 100%{ transform:scale(1.8); opacity:0; } }
  @keyframes bob { 0%,100%{ transform:translateY(0); } 50%{ transform:translateY(-3px); } }
  @keyframes sweep { 0%{ transform:translateX(-160%); } 100%{ transform:translateX(160%); } }

  /* ---- AI cycling widget ---- */
  .ai-panel { display:none; }
  .ai-panel.active { display:block; animation:aifade .5s ease; }
  @keyframes aifade { from{ opacity:0; transform:translateY(8px); } to{ opacity:1; transform:none; } }
  .ai-tab { transition:color .25s, background-color .25s; }

  /* ---- brand grid texture ---- */
  .grid-bg { background-image:linear-gradient(rgba(21,20,15,.05) 1px,transparent 1px),linear-gradient(90deg,rgba(21,20,15,.05) 1px,transparent 1px); background-size:40px 40px; }
  .grid-bg-dark { background-image:linear-gradient(rgba(255,255,255,.06) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.06) 1px,transparent 1px); background-size:40px 40px; }

  /* ---- generic tab system (AI + Industries) ---- */
  .tab-panel { display:none; }
  .tab-panel.active { display:block; animation:aifade .45s ease both; }
  .tab-btn { transition:background-color .25s,color .25s,border-color .25s; }
  .tab-btn[aria-selected="true"] { background:#15140F; color:#FBFAF6; border-color:#15140F; }
  .tab-btn-dark[aria-selected="true"] { background:#12A06A; color:#fff; border-color:#12A06A; }

  /* ---- button arrow nudge ---- */
  .btn-arrow svg { transition:transform .25s; }
  .btn-arrow:hover svg { transform:translateX(3px); }

  /* fixed-nav anchor offset */
  section[id]{ scroll-margin-top:92px; }

  @media (prefers-reduced-motion: reduce){
    .marquee{ animation:none; } .mini .a{ animation:none !important; }
  }

/* ===========================================================================
   VUCI BRAND ALIGNMENT  (overrides the compiled layer — source-order wins)
   Bricolage Grotesque + DM Sans, navy ink (#0d1b2a), signature mint (#ADFFBE)
   and the hard-offset shadow on primary actions.
   =========================================================================== */
html, body, .font-sans { font-family: 'DM Sans', system-ui, sans-serif; }
.font-display { font-family: 'Bricolage Grotesque', system-ui, sans-serif; letter-spacing: -0.02em; }
body { color: #0d1b2a; }
.text-ink { color: #0d1b2a; }
.bg-ink { background-color: #0d1b2a; }
.bg-deep { background-color: #0d1b2a; }          /* AI section → Vuci navy */
.border-ink\/20 { border-color: rgba(13, 27, 42, .2); }
::selection { background: #ADFFBE; color: #0d1b2a; }

/* hard-offset shadow — Vuci's signature on primary actions */
.btn-brand { box-shadow: 3px 3px 0 0 #0d1b2a; }
.btn-brand:hover { box-shadow: 5px 5px 0 0 #0d1b2a; transform: translateY(-1px); }

/* a reusable mint hard-shadow accent for framed surfaces */
.rs-shadow { box-shadow: 6px 6px 0 0 #ADFFBE; }
@media (max-width: 640px) { .rs-shadow { box-shadow: 4px 4px 0 0 #ADFFBE; } }

/* small proof chips in the hero */

/* ===========================================================================
   SWIPER carousels (galleries for case studies / modules / branding)
   =========================================================================== */
/* width:100% + min-width:0 are essential: these swipers live inside flex
   parents whose default min-width:auto would otherwise let the wrapper's
   intrinsic (sum-of-slides) width blow the container out to millions of px. */
.rs-swiper { overflow: hidden; width: 100%; min-width: 0; max-width: 100%; }
.rs-swiper .swiper-slide { height: auto; }
.rs-swiper .swiper-pagination { position: static; margin-top: 16px; display: flex; justify-content: center; gap: 7px; }
.rs-swiper .swiper-pagination-bullet { background: #0d1b2a; opacity: .2; width: 7px; height: 7px; margin: 0 !important; border-radius: 9999px; transition: width .3s ease, opacity .3s ease, background-color .3s ease; }
.rs-swiper .swiper-pagination-bullet-active { background: #12A06A; opacity: 1; width: 22px; }
/* dark variant (on the navy AI / dark surfaces) */
.rs-swiper.on-dark .swiper-pagination-bullet { background: #fff; }
.rs-swiper.on-dark .swiper-pagination-bullet-active { background: #ADFFBE; }

/* fixed-height card gallery (project cards) — pagination overlays the image */
.rs-swiper.cardgal, .rs-swiper.cardgal .swiper-slide, .rs-swiper.cardgal .shot { height: 13rem; }
.rs-swiper.cardgal .swiper-pagination { position: absolute; left: 0; right: 0; bottom: 8px; margin-top: 0; z-index: 2; }
.rs-swiper.cardgal .swiper-pagination-bullet { background: #fff; opacity: .55; box-shadow: 0 1px 3px rgba(0,0,0,.4); }
.rs-swiper.cardgal .swiper-pagination-bullet-active { background: #ADFFBE; opacity: 1; }

/* ===========================================================================
   ████  APPLE REDESIGN LAYER · 2026  ████
   A ground-up visual re-skin authored on top of the approved mockup. Thesis:
   editorial restraint — collapse the five-way accent rainbow to a near-
   monochrome system (warm paper + navy ink) with ONE chromatic accent (brand
   green) and mint as the single spark; bolder fluid typography with far more
   air; calmer surfaces (no grain/grid/stacked blobs — one tasteful wash); and
   cinematic, cohesive motion. Source-order wins, so this governs everything
   above it without touching the working Swiper / tab / reveal machinery.
   =========================================================================== */
:root {
  --rs-paper:   #FBFAF6;   /* warm off-white base                 */
  --rs-surface: #FFFFFF;   /* raised cards                         */
  --rs-mist:    #F3F0E8;   /* section bands                        */
  --rs-tint:    #F1EEE6;   /* unified faint card tint (ex-rainbow) */
  --rs-ink:     #0d1b2a;   /* navy — text + dark surfaces          */
  --rs-ink-2:   #45525f;   /* secondary text                       */
  --rs-muted:   #8a93a0;   /* tertiary / captions                  */
  --rs-line:    rgba(13,27,42,.09);
  --rs-line-2:  rgba(13,27,42,.14);
  --rs-green:   #0e7a3f;   /* Vuci green — legible on light (ex-emerald #12A06A) */
  --rs-green-d: #0e7a3f;   /* contrast-safe green text on light    */
  --rs-mint:    #ADFFBE;   /* Vuci mint — the bright pop           */
  --rs-mint-2:  #81FF94;   /* deeper glow-mint                     */
  --rs-violet:  #6600ff;   /* Vuci violet (wordmark) — co-lead     */
  --rs-violet-d:#4d00cc;   /* violet pressed                       */
  --rs-violet-s:#efe9ff;   /* light violet tint surface            */
  --rs-mint-s:  #e2fbe8;   /* light mint tint surface              */
  --rs-dot:     rgba(13,27,42,.16);  /* window-chrome dots → mono  */
  --rs-ease:    cubic-bezier(.22,.61,.18,1);
  --rs-shadow:  0 40px 80px -52px rgba(13,27,42,.55);
  --rs-shadow-sm: 0 18px 40px -30px rgba(13,27,42,.4);
}

/* ---- 1 · TYPOGRAPHY — bolder, tighter, fluid -------------------------------*/
body { color: var(--rs-ink); letter-spacing: -0.011em; }
.font-display { font-weight: 700; letter-spacing: -0.035em; line-height: 1.02; }
h1.font-display, h2.font-display { letter-spacing: -0.04em; }
.ital { letter-spacing: -0.02em; }
p { color: var(--rs-ink-2); }

/* one fluid hero headline — calmer leading, dramatic size */
.rs-hero-title { font-size: clamp(44px, 6.4vw, 82px) !important; line-height: .98 !important; letter-spacing: -0.045em !important; }
.rs-hero-lede  { font-size: clamp(17px, 1.5vw, 20px) !important; line-height: 1.55 !important; color: var(--rs-ink-2) !important; }

/* lift the section headlines a step, keep them disciplined */
.text-\[34px\], .sm\:text-\[46px\] { letter-spacing: -0.04em; }
@media (min-width:640px){
  .sm\:text-\[46px\] { font-size: 50px; }
  .sm\:text-\[44px\] { font-size: 48px; }
  .sm\:text-\[40px\] { font-size: 44px; }
}

/* eyebrows: bold, branded violet — the section's loud little flag */
.eyebrow { font-size: 11.5px; letter-spacing: .2em; color: var(--rs-violet); font-weight: 700; }
.eyebrow.text-brand { color: var(--rs-violet) !important; }
.pill { letter-spacing: .12em; font-weight: 600; }

/* ---- 2 · EXPRESSIVE VUCI DUOTONE — violet + mint --------------------------*/
/* The brief: bold, expressive, Vuci-branded. Two co-lead colours carry the
   whole page — electric violet (#6600ff) and mint (#ADFFBE) — folding the old
   five-way rainbow into a confident duotone. Cool family (violet/blue/coral)
   → violet; warm/brand family (amber/brand) → mint+green. */

/* soft card tints → violet-tint or mint-tint by family */
.bg-violetsoft, .bg-violetsoft\/40, .bg-violetsoft\/60,
.bg-bluesoft,   .bg-bluesoft\/40,   .bg-bluesoft\/60,
.bg-coralsoft,  .bg-coralsoft\/60 { background-color: var(--rs-violet-s) !important; }
.bg-ambersoft,  .bg-ambersoft\/40, .bg-ambersoft\/60,
.bg-brandsoft,  .bg-brandsoft\/40, .bg-brandsoft\/60, .bg-brandsoft\/70 { background-color: var(--rs-mint-s) !important; }

/* solid mini-viz accents — violet family */
.bg-violet            { background-color: var(--rs-violet) !important; }
.bg-violet\/70        { background-color: rgba(102,0,255,.70) !important; }
.bg-violet\/60        { background-color: rgba(102,0,255,.55) !important; }
.bg-violet\/40        { background-color: rgba(102,0,255,.40) !important; }
.bg-violet\/30        { background-color: rgba(102,0,255,.30) !important; }
.bg-blue              { background-color: var(--rs-violet) !important; }
.bg-blue\/30          { background-color: rgba(102,0,255,.30) !important; }
.bg-coral             { background-color: var(--rs-violet) !important; }
/* solid mini-viz accents — mint/green family */
.bg-amber             { background-color: var(--rs-green) !important; }
.bg-amber\/50         { background-color: rgba(18,160,106,.5) !important; }
.bg-amber\/30         { background-color: rgba(18,160,106,.3) !important; }

/* window-chrome traffic dots → playful violet · mint · green trio */
.bg-coral\/70 { background-color: rgba(102,0,255,.55) !important; }
.bg-amber\/70 { background-color: var(--rs-mint-2) !important; }
.bg-brand\/70 { background-color: var(--rs-green) !important; }

/* accent text / numbers / pills — violet leads, warm family → green */
.text-violet, .text-blue, .text-coral { color: var(--rs-violet) !important; }
.text-amber { color: var(--rs-green-d) !important; }

/* category dots inside module chips inherit the same duotone via the bg rules */

/* brand GREEN → Vuci green system (retire the emerald #12A06A / #0B7A50).
   Mint #ADFFBE stays the signature in hard-shadows, soft tints (brandsoft →
   mint tint) and on the dark sections; green TEXT/FILLS on light use the
   contrast-safe Vuci green so nothing turns illegible. */
.text-brand, .text-branddk { color: var(--rs-green) !important; }
.bg-brand { background-color: var(--rs-green) !important; }
.bg-brand\/20 { background-color: rgba(14,122,63,.2) !important; }
.border-brand { border-color: var(--rs-green) !important; }
.border-brand\/20 { border-color: rgba(14,122,63,.22) !important; }

/* ---- 3 · SURFACES — calmer, cleaner ---------------------------------------*/
/* slightly translucent so the page-wide grid/wash reads through the bands too */
.bg-mist { background-color: rgba(243,240,232,.8) !important; }
.hairline, .border-line { border-color: var(--rs-line) !important; }
.border-line\/70, .border-line\/60 { border-color: var(--rs-line) !important; }

/* kill the layered visual noise — grain, grids, stacked blobs */
.grain { background-image: none !important; }
.grid-bg { background-image: none !important; }
.grid-bg-dark { opacity: .5; }
.blob { display: none !important; }   /* replaced by one controlled wash below */

/* one tasteful hero wash: a single soft mint→transparent bloom, top-right */
#top > section:first-of-type { position: relative; }
/* the hero no longer paints its own wash — the page-wide vuci background
   (see PAGE BACKGROUND below) is the single source, and stacking the two
   double-darkened the top-right corner. */
#top > section:first-of-type::before { content: none; }
#top > section:first-of-type > .max-w-container { position: relative; z-index: 1; }

/* ---- 4 · NAV — see the NAVBAR block at the end of this file ---------------*/
/* The floating translucent pill (and its `.scrolled` tighten) was replaced by
   the flat edge-to-edge bar. Its old selector — `#nav > .max-w-container > div`
   — would now match the new bar's actions cluster, so it is deleted rather
   than overridden. */

/* ---- 5 · BUTTONS / LINKS — vuci.ai/welcome's .lp-btn, ported exactly -------*/
/* Was violet-fill + mint shadow. Now the accent button from the Vuci welcome
   page (podbits/assets/css/landing.css .lp-btn / .lp-btn--accent): mint fill,
   ink text, a 1.5px ink keyline and an ink hard-shadow that grows as the
   button lifts away from it.
   Tokens already line up: --lp-ink === --rs-ink, --lp-accent === --rs-mint.
   The nav CTA is deliberately NOT this (see .rs-nav-cta).

   The transform curve below overshoots slightly — normally a smell, and
   detectors flag it as bounce easing. Kept on purpose: it is Vuci's curve,
   copied verbatim from .lp-btn, and the overshoot is precisely what makes the
   button feel like it lifts off its hard shadow rather than sliding. Scoped to
   transform, 250ms, and only these two buttons. */
.btn-brand {
  background: var(--rs-mint) !important; color: var(--rs-ink) !important;
  border: 1.5px solid var(--rs-ink) !important;
  border-radius: 9999px !important;
  font-weight: 700;
  box-shadow: 3px 3px 0 0 var(--rs-ink) !important;
  transition: transform 250ms cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 250ms ease !important;
}
.btn-brand:hover {
  background: var(--rs-mint) !important; color: var(--rs-ink) !important;
  transform: translate(-3px, -3px) !important;
  box-shadow: 6px 6px 0 0 var(--rs-ink) !important;
}
.btn-brand:active { transform: translate(0, 0) !important; box-shadow: 2px 2px 0 0 var(--rs-ink) !important; }
.link-u:hover { color: var(--rs-violet); }

/* secondary action (the hero's "See our work") → Vuci's .lp-btn--ghost.
   Scoped to <a> so it never touches the hairline CARD frames (Figma window,
   job-queue, floating product card) which share .hairline.bg-surface. */
a.hairline.bg-surface {
  border-radius: 9999px !important;
  background: rgba(255, 255, 255, 0.85) !important;
  border: 1.5px solid rgba(13, 27, 42, 0.14) !important;
  font-weight: 600;
  transition: transform 250ms cubic-bezier(0.34, 1.56, 0.64, 1), background-color 250ms ease, border-color 250ms ease;
}
a.hairline.bg-surface:hover { background: #fff !important; border-color: rgba(13, 27, 42, 0.3) !important; }

/* ---- 6 · CARDS — softer radius, quieter borders, real lift ----------------*/
.card-hover { border-radius: 20px !important; transition: transform .4s var(--rs-ease), box-shadow .4s var(--rs-ease), border-color .4s var(--rs-ease); }
.card-hover:hover { transform: translateY(-5px) !important; box-shadow: var(--rs-shadow) !important; border-color: var(--rs-line-2) !important; }
.layer-card { border-radius: 20px !important; transition: transform .4s var(--rs-ease), box-shadow .35s var(--rs-ease), border-color .35s; }
.layer-card:hover { transform: translateY(-4px); box-shadow: var(--rs-shadow-sm); border-color: var(--rs-line-2) !important; }

/* window frames: cleaner chrome + a single refined shadow */
.win-shadow { box-shadow: var(--rs-shadow) !important; }
.rs-shadow  { box-shadow: 10px 10px 0 0 var(--rs-mint) !important; }
@media (max-width:640px){ .rs-shadow { box-shadow: 6px 6px 0 0 var(--rs-mint) !important; } }

/* ---- 7 · MOTION — one cinematic reveal (blur clears as it rises) ----------*/
.reveal { opacity: 0; transform: translateY(28px); filter: blur(8px);
  transition: opacity .9s var(--rs-ease), transform .9s var(--rs-ease), filter .9s var(--rs-ease);
  animation: none !important; }
.reveal.in { opacity: 1; transform: none; filter: none; }
.reveal.in[data-d="1"]{ transition-delay:.09s } .reveal.in[data-d="2"]{ transition-delay:.18s } .reveal.in[data-d="3"]{ transition-delay:.27s }

/* hero product shot drifts on scroll (JS sets --rs-py) */

/* thin scroll-progress hairline under the nav */
#rs-progress { position: fixed; top: 0; left: 0; height: 2.5px; width: 0; z-index: 60;
  background: linear-gradient(90deg, var(--rs-violet), var(--rs-mint-2), var(--rs-mint)); transition: width .1s linear; }

@media (prefers-reduced-motion: reduce){
  .reveal { opacity: 1 !important; transform: none !important; filter: none !important; }
}

/* ===========================================================================
   ████  EXPRESSIVE LAYER · violet+mint moments + restored motion  ████
   =========================================================================== */

/* ---- 8 · TABS — active light tab goes bold violet; dark tab stays mint -----*/
.tab-btn[aria-selected="true"] { background: var(--rs-violet) !important; color:#fff !important; border-color: var(--rs-violet) !important; }
.tab-btn-dark[aria-selected="true"] { background: var(--rs-mint) !important; color: var(--rs-ink) !important; border-color: var(--rs-mint) !important; }

/* ---- 9 · CONTACT CTA — the big violet→ink moment, mint accents ------------ */
#contact .bg-brand {
  background: linear-gradient(135deg, var(--rs-violet) 0%, #3a0ea8 52%, var(--rs-ink) 100%) !important;
}
#contact .bg-brand a.bg-white { color: var(--rs-violet) !important; }

/* ---- 10 · "HOW WE WORK" PIPELINE — restored, more alive -------------------*/
/* a continuously travelling mint comet rides the rail once the fill lands;
   nodes light in sequence (JS) and the active one pulses violet. */
.pipe-track .pipe-fill { background: linear-gradient(90deg, var(--rs-violet), var(--rs-mint-2)) !important; height: 2px !important; }
.pipe-track .rail-wrap { position: relative; }
.pipe-comet { position: absolute; top: 14px; left: 0; width: 14px; height: 4px; border-radius: 9999px;
  background: linear-gradient(90deg, transparent, var(--rs-mint-2), #fff); box-shadow: 0 0 12px 2px rgba(129,255,148,.8);
  opacity: 0; }
.pipe-track.in .pipe-comet { opacity: 1; animation: cometRun 3.2s 1.6s linear infinite; }
@keyframes cometRun { from { left: -3%; } to { left: 103%; } }
.pipe-node { box-shadow: 0 0 0 0 rgba(102,0,255,0); }
.pipe-node.lit { background: var(--rs-ink) !important; color:#fff !important; border-color: var(--rs-ink) !important; }
.pipe-node.lit.is-key { background: var(--rs-violet) !important; border-color: var(--rs-violet) !important;
  transform: scale(1.14); box-shadow: 0 0 0 6px rgba(102,0,255,.14); }
@media (prefers-reduced-motion: reduce){ .pipe-track.in .pipe-comet { animation: none; } }

/* ---- 11 · MARQUEES — Swiper-driven continuous loop (gap-proof) ------------*/
/* The pure-CSS -50% loop showed blank space whenever one content copy was
   narrower than the viewport (it was). A Swiper marquee (data-marquee) clones
   slides to always fill the row + beyond, so it loops seamlessly at any width.
   delay:0 + a linear wrapper timing-function makes it glide continuously. */
.rs-marquee { width: 100%; overflow: visible; }
.rs-marquee .swiper-wrapper { transition-timing-function: linear !important; }
.rs-marquee .swiper-slide { width: auto !important; display: flex; align-items: center; }
.marquee-wrap:hover .rs-marquee .swiper-wrapper { } /* hover-pause handled in JS */
/* desaturated logo wall, a touch larger, lifts to full colour on hover */
.logo-mark { height: 30px; opacity: .5; transition: opacity .3s ease, filter .3s ease; }
@media (min-width:640px){ .logo-mark { height: 38px; } }
.logo-mark:hover { opacity: 1; }

/* ---- 12 · aligned list "diamonds" (replaces the off-baseline ◆ glyph) -----*/
.diamond { flex: none; width: 9px; height: 9px; margin-top: 6px; border-radius: 2px;
  transform: rotate(45deg); background: var(--rs-violet); }
.diamond.mint { background: var(--rs-green); }

/* ---- 13 · ANIMATED FIGMA CANVAS — collaborative design, live -------------- */
.figma-grid { background-color: #fbfaf6;
  background-image: radial-gradient(rgba(13,27,42,.11) 1px, transparent 1px);
  background-size: 16px 16px; }
.fig-ava { width: 20px; height: 20px; border-radius: 9999px; display: flex; align-items: center;
  justify-content: center; font-family: "JetBrains Mono", monospace; font-size: 9px; font-weight: 700;
  color: #fff; border: 2px solid var(--rs-surface); }
.fig-tool { width: 15px; height: 15px; display: block; }
/* the selection outline around the live-edited button */
.fig-select { position: absolute; border: 1.5px solid var(--rs-violet); border-radius: 7px;
  animation: figSelPulse 2.6s var(--rs-ease) infinite; }
.fig-select b { position: absolute; width: 6px; height: 6px; background: #fff; border: 1.5px solid var(--rs-violet); border-radius: 1px; }
.fig-select b:nth-child(1){ top:-4px; left:-4px } .fig-select b:nth-child(2){ top:-4px; right:-4px }
.fig-select b:nth-child(3){ bottom:-4px; left:-4px } .fig-select b:nth-child(4){ bottom:-4px; right:-4px }
@keyframes figSelPulse { 0%,100%{ box-shadow: 0 0 0 0 rgba(102,0,255,.22) } 50%{ box-shadow: 0 0 0 5px rgba(102,0,255,0) } }
/* a collaborator cursor drifting across the canvas on a loop */
.fig-cursor { position: absolute; top: 0; left: 0; z-index: 3; pointer-events: none;
  animation: figCursor 7s var(--rs-ease) infinite; }
.fig-cursor svg { filter: drop-shadow(0 1px 2px rgba(13,27,42,.35)); }
.fig-cursor span { position: absolute; top: 14px; left: 12px; white-space: nowrap;
  background: var(--rs-violet); color: #fff; font-family: "JetBrains Mono", monospace;
  font-size: 9px; font-weight: 700; padding: 2px 6px; border-radius: 6px; border-bottom-left-radius: 1px; }
@keyframes figCursor {
  0%   { transform: translate(26px, 150px); }
  22%  { transform: translate(150px, 64px); }
  44%  { transform: translate(196px, 120px); }
  66%  { transform: translate(110px, 154px); }
  88%  { transform: translate(58px, 92px); }
  100% { transform: translate(26px, 150px); }
}
/* a component "ghost" that drops into place, then resets */
.fig-drop { animation: figDrop 7s var(--rs-ease) infinite; }
@keyframes figDrop { 0%,8%{ opacity:0; transform: translateY(8px) scale(.96) } 16%,70%{ opacity:1; transform:none } 84%,100%{ opacity:0; transform: translateY(8px) scale(.96) } }
@media (prefers-reduced-motion: reduce){
  .fig-cursor, .fig-select, .fig-drop { animation: none !important; }
  .fig-cursor { transform: translate(150px, 64px); }
}

/* ---- 14 · WHAT-WE-DO unified panel (artifact-style) + richer AI anim -------*/
/* one white panel with hairline dividers instead of five floating tinted cards;
   cells stay flat (no per-card lift), the mini-animations are preserved. */
.layer-panel { box-shadow: var(--rs-shadow); }
.layer-panel .layer-card { border-radius: 0 !important; box-shadow: none !important;
  background: transparent !important; transition: background-color .3s var(--rs-ease); }
.layer-panel .layer-card:hover { transform: none !important; box-shadow: none !important;
  background: rgba(102,0,255,.035) !important; border-color: var(--rs-line) !important; }
/* fixed mini height (the h-12 utility isn't in the compiled subset, so without
   this the boxes collapse to content height and the titles misalign) */
.layer-panel .mini { height: 48px; flex: none; transition: transform .35s var(--rs-ease); }
.layer-panel .layer-card:hover .mini { transform: translateY(-2px); }

/* AI cell — a mint satellite orbiting the violet node (plays in view / on hover) */
.ai-orbit { position: absolute; top: 50%; left: 50%; width: 30px; height: 30px;
  margin: -15px 0 0 -15px; animation: aiSpin 3.2s linear infinite; }
.ai-dot { position: absolute; top: -2px; left: 50%; margin-left: -3px; width: 6px; height: 6px;
  border-radius: 9999px; background: var(--rs-mint-2); box-shadow: 0 0 7px 1px rgba(129,255,148,.9); }
@keyframes aiSpin { to { transform: rotate(360deg); } }
/* data bars scale (percentage heights don't resolve inside the flex mini) */
@keyframes barScale { 0%,100% { transform: scaleY(.42); } 50% { transform: scaleY(1); } }
.mini .ai-orbit { animation-play-state: paused; }
.layer-card:hover .mini .ai-orbit, .layer-card.playing .mini .ai-orbit { animation-play-state: running; }
@media (prefers-reduced-motion: reduce){ .ai-orbit { animation: none !important; } }

/* ---- 15 · PAGE-WIDE DYNAMIC BACKDROP — one continuous faded canvas ---------*/
/* ===========================================================================
   PAGE BACKGROUND — ported verbatim from vuci.ai/welcome
   (podbits/assets/css/landing.css .lp-root + .lp-bg + @keyframes lp-bgShift)

   Replaces the old warm-paper canvas with alternating mint/lavender bands and
   a fixed multi-radial wash that drifts on a 28s loop. The faint 62px square
   grid that used to sit here is gone with it — a tiled hairline line-field is
   a generated-UI signature, and this wash does the job without it.
   =========================================================================== */
body {
  position: relative;
  background: linear-gradient(180deg, #e9fff0 0%, #eef0ff 15%, #eafef2 30%, #f1ecff 47%,
                                      #e9fff1 63%, #efeaff 80%, #eafff0 100%);
}
body::before {
  content: ""; position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(40% 38% at 12% 18%, rgba(173, 255, 190, 0.55), transparent 62%),
    radial-gradient(42% 40% at 88% 12%, rgba(197, 182, 255, 0.50), transparent 62%),
    radial-gradient(46% 44% at 80% 78%, rgba(173, 255, 190, 0.42), transparent 62%),
    radial-gradient(44% 42% at 18% 86%, rgba(197, 182, 255, 0.45), transparent 62%);
  background-size: 160% 160%, 160% 160%, 160% 160%, 160% 160%;
  animation: rsBgShift 28s ease-in-out infinite;
}
@keyframes rsBgShift {
  0%, 100% { background-position: 0% 0%, 100% 0%, 100% 100%, 0% 100%; }
  50%      { background-position: 40% 35%, 55% 45%, 45% 60%, 30% 50%; }
}
@media (prefers-reduced-motion: reduce) { body::before { animation: none; } }

/* lift content above the backdrop (NOT the fixed nav/progress, which keep their
   own stacking so they stay pinned) */
main, footer { position: relative; z-index: 1; }
/* the old per-section wrapper is now just a transparent passthrough */
.rs-grid-canvas { position: relative; }

/* ---- 16 · SOLUTIONS — four capabilities + hover-driven stage + callout -----*/
/* Four cards on the left drive one stage on the right. The stage is a single
   grid cell with all four scenes stacked in it, so its height is the tallest
   scene and nothing below shifts as the active card changes. Scenes are the
   placeholder artwork: each animates only while `.is-active`, so three of the
   four are fully idle at any moment. */
.rs-caps { display: grid; gap: 1rem; }
@media (min-width: 900px) {
  .rs-caps { grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); gap: 1.25rem; align-items: start; }
}
.rs-caps-list { display: grid; gap: .6rem; order: 2; }
/* Same 3D language as the project deck: one perspective on the column, the
   cards posed inside it. The active card comes forward and squares up to the
   viewer; the rest sit back and stay turned slightly away, so the column reads
   as a physical stack rather than four flat rectangles. Desktop only — the
   perspective needs the hover to make sense. */
@media (min-width: 900px) {
  .rs-caps-list { order: 0; gap: .55rem; perspective: 1400px; perspective-origin: 0% 50%; }
}

.rs-cap {
  display: flex; gap: 1rem; align-items: flex-start; text-align: left; width: 100%;
  padding: 1.15rem 1.25rem; border-radius: 16px; position: relative; overflow: hidden;
  background: var(--rs-surface); border: 1px solid var(--rs-line);
  transition: border-color .3s var(--rs-ease), background-color .3s var(--rs-ease),
    transform .3s var(--rs-ease), box-shadow .3s var(--rs-ease);
}
/* the violet edge that marks the active card */
.rs-cap::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
  background: var(--rs-violet); transform: scaleY(0); transform-origin: top;
  transition: transform .3s var(--rs-ease);
}
/* Opaque tint, not a 3.5%-alpha violet: the resting card is solid white, so an
   almost-transparent active state let the page's animated mint/lavender
   backdrop wash straight through the card and run under the text. */
.rs-cap.is-active { border-color: var(--rs-line-2); background: #f7f4ff; }
.rs-cap.is-active::before { transform: scaleY(1); }
@media (min-width: 900px) {
  .rs-cap {
    transform: translate3d(0, 0, -34px) rotateY(-5deg);
    box-shadow: 0 14px 30px -22px rgba(13, 27, 42, .5);
    transition: border-color .3s var(--rs-ease), background-color .3s var(--rs-ease),
      transform .45s var(--rs-ease), box-shadow .45s var(--rs-ease);
  }
  .rs-cap.is-active {
    transform: translate3d(10px, 0, 34px) rotateY(0deg);
    box-shadow: 0 34px 60px -30px rgba(13, 27, 42, .55), 0 4px 10px -6px rgba(13, 27, 42, .12);
  }
}
@media (prefers-reduced-motion: reduce) {
  .rs-cap, .rs-cap.is-active { transform: none; }
}
.rs-cap:focus-visible { outline: 2px solid var(--rs-violet); outline-offset: 2px; }

/* Under 900px the column becomes a swipeable rail: one card per screen with the
   next peeking, so the stage above changes with the swipe instead of the reader
   scrolling past four full-width cards. */
@media (max-width: 899px) {
  .rs-caps-list {
    grid-auto-flow: column; grid-auto-columns: 84%;
    gap: .7rem; overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory; scroll-padding: 0 1.25rem;
    padding-bottom: 2px;
    scrollbar-width: none; -ms-overflow-style: none;
  }
  .rs-caps-list::-webkit-scrollbar { display: none; }
  .rs-cap { scroll-snap-align: center; height: 100%; }
  .rs-caps-dots { order: 3; }
}

/* Shared rail position indicator (walkthrough + capabilities). Mobile only:
   above the breakpoint the rails are columns again and the dots would be
   describing a scroll that no longer exists. */
.rs-swipe-dots { display: none; justify-content: center; gap: 7px; margin-top: 14px; }
.rs-swipe-dots button {
  width: 7px; height: 7px; padding: 0; border: 0; border-radius: 999px; cursor: pointer;
  background: var(--rs-line-2); transition: background-color .25s var(--rs-ease), width .25s var(--rs-ease);
}
.rs-swipe-dots button.is-on { width: 20px; background: var(--rs-violet); }
@media (max-width: 899px) { .rs-caps-dots { display: flex; } }
@media (max-width: 1023px) { .rs-flow-grid > .rs-swipe-dots { display: flex; } }
@media (max-width: 767px) { [data-rail-dots] { display: flex; } }

.rs-cap-n { flex: none; font-family: "JetBrains Mono", monospace; font-size: 12px; font-weight: 700;
  color: var(--rs-violet); padding-top: 3px; }
.rs-cap-body { min-width: 0; }
.rs-cap h3 { font-family: "Bricolage Grotesque", system-ui, sans-serif; font-weight: 600;
  font-size: 16.5px; letter-spacing: -0.02em; color: var(--rs-ink); }
.rs-cap p { margin-top: 5px; font-size: 13.5px; line-height: 1.45; color: var(--rs-muted); }
.rs-cap-arrow { flex: none; margin-top: 3px; color: var(--rs-violet);
  opacity: 0; transform: translateX(-6px);
  transition: opacity .3s var(--rs-ease), transform .3s var(--rs-ease); }
.rs-cap.is-active .rs-cap-arrow { opacity: 1; transform: none; }

.rs-caps-stage {
  position: relative; display: grid; order: 1; overflow: hidden;
  min-height: 240px; border-radius: 20px;
  background:
    radial-gradient(120% 130% at 100% 0%, rgba(102,0,255,.10), transparent 60%),
    var(--rs-surface);
  border: 1px solid var(--rs-line-2); box-shadow: var(--rs-shadow-sm);
}
@media (min-width: 900px) { .rs-caps-stage { order: 0; min-height: 380px; position: sticky; top: 96px; } }
/* faint grid so an empty-ish scene still reads as a surface */
.rs-caps-stage::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image: linear-gradient(rgba(13,27,42,.045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(13,27,42,.045) 1px, transparent 1px);
  background-size: 32px 32px;
  -webkit-mask-image: radial-gradient(ellipse at 50% 40%, #000, transparent 78%);
  mask-image: radial-gradient(ellipse at 50% 40%, #000, transparent 78%);
}
.rs-cap-scene {
  grid-area: 1 / 1; min-width: 0; display: flex; padding: 1.5rem;
  opacity: 0; visibility: hidden; transform: scale(1.02) translateY(6px);
  transition: opacity .4s var(--rs-ease), transform .5s var(--rs-ease), visibility 0s linear .4s;
}
.rs-cap-scene.is-active { opacity: 1; visibility: visible; transform: none;
  transition: opacity .4s var(--rs-ease), transform .5s var(--rs-ease), visibility 0s; }
/* a real screenshot can be dropped straight into a scene */
.rs-cap-scene img { width: 100%; height: 100%; object-fit: contain; }

.rs-art { position: relative; flex: 1 1 auto; min-width: 0; display: flex;
  flex-direction: column; justify-content: center; }
.rs-art svg { width: 100%; display: block; }
.rs-art-caption { position: absolute; left: 0; bottom: 0; display: flex; align-items: center; gap: .45rem;
  font-family: "JetBrains Mono", monospace; font-size: 11px; letter-spacing: .02em; color: var(--rs-muted); }
.rs-art-caption i { width: 6px; height: 6px; border-radius: 50%; background: var(--rs-green);
  box-shadow: 0 0 0 0 rgba(14,122,63,.5); }
.rs-cap-scene.is-active .rs-art-caption i { animation: rsCapBlip 2.2s var(--rs-ease) infinite; }
@keyframes rsCapBlip {
  0%, 100% { box-shadow: 0 0 0 0 rgba(14,122,63,.45); }
  60%      { box-shadow: 0 0 0 7px rgba(14,122,63,0); }
}

/* 01 · agents — a hub fanning work out to tools and pulling it back */
.rs-art-agents svg { max-height: 210px; }
.rs-art-wires path { fill: none; stroke: var(--rs-line-2); stroke-width: 1.5;
  stroke-dasharray: 5 7; stroke-linecap: round; }
.rs-cap-scene.is-active .rs-art-wires path { animation: rsCapWire 1.5s linear infinite; }
@keyframes rsCapWire { to { stroke-dashoffset: -24; } }
.rs-art-hub { fill: var(--rs-violet); }
.rs-art-ring { fill: none; stroke: var(--rs-violet); stroke-width: 1.5; opacity: 0; transform-origin: 160px 110px; }
.rs-cap-scene.is-active .rs-art-ring { animation: rsCapPulse 2.8s var(--rs-ease) infinite; }
.rs-cap-scene.is-active .rs-art-ring.rs-d2 { animation-delay: 1.4s; }
@keyframes rsCapPulse {
  0%   { opacity: .55; transform: scale(.75); }
  100% { opacity: 0;   transform: scale(1.6); }
}
.rs-art-nodes circle { fill: var(--rs-surface); stroke: var(--rs-violet); stroke-width: 2; }
.rs-cap-scene.is-active .rs-art-nodes circle { animation: rsCapNode 2.8s var(--rs-ease) infinite; }
.rs-cap-scene.is-active .rs-art-nodes .rs-d1 { animation-delay: .35s; }
.rs-cap-scene.is-active .rs-art-nodes .rs-d2 { animation-delay: .7s; }
.rs-cap-scene.is-active .rs-art-nodes .rs-d3 { animation-delay: 1.05s; }
@keyframes rsCapNode {
  0%, 70%, 100% { fill: var(--rs-surface); }
  20%, 45%      { fill: var(--rs-mint); }
}

/* 02 · automation — three lanes of work converging on one hub */
.rs-art-flow { gap: .9rem; padding-right: 96px; }
.rs-lane { position: relative; display: flex; align-items: center; gap: .6rem; }
.rs-lane-box { flex: none; font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--rs-ink-2);
  background: var(--rs-tint); border: 1px solid var(--rs-line); border-radius: 8px; padding: .3rem .5rem; }
.rs-lane-track { flex: 1 1 auto; height: 2px; border-radius: 2px;
  background: repeating-linear-gradient(90deg, var(--rs-line-2) 0 6px, transparent 6px 12px); }
.rs-dot { position: absolute; right: 0; width: 8px; height: 8px; border-radius: 50%;
  background: var(--rs-violet); opacity: 0; }
.rs-cap-scene.is-active .rs-dot { animation: rsCapTravel 2.6s var(--rs-ease) infinite; }
.rs-cap-scene.is-active .rs-dot.rs-d1 { animation-delay: .5s; }
.rs-cap-scene.is-active .rs-dot.rs-d2 { animation-delay: 1s; }
@keyframes rsCapTravel {
  0%       { transform: translateX(-100%); opacity: 0; }
  15%, 80% { opacity: 1; }
  100%     { transform: translateX(28px); opacity: 0; }
}
.rs-flow-hub { position: absolute; right: 0; top: 50%; transform: translateY(-50%);
  display: flex; flex-direction: column; align-items: center; gap: .4rem; width: 84px;
  font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--rs-muted); text-align: center; }
.rs-flow-hub span { width: 44px; height: 44px; border-radius: 14px; background: var(--rs-violet);
  box-shadow: 0 0 0 6px rgba(102,0,255,.10); }
.rs-cap-scene.is-active .rs-flow-hub span { animation: rsCapHub 2.6s var(--rs-ease) infinite; }
@keyframes rsCapHub {
  0%, 100% { box-shadow: 0 0 0 6px rgba(102,0,255,.10); }
  50%      { box-shadow: 0 0 0 12px rgba(102,0,255,.04); }
}

/* 03 · platforms — layers of one system, breathing under load */
/* every slab is absolute, so the scene needs its own height to sit in */
.rs-art-stack { align-items: center; min-height: 200px; }
.rs-slab { position: absolute; left: 50%; width: min(260px, 80%); height: 108px; border-radius: 14px;
  transform: translateX(-50%); border: 1px solid var(--rs-line-2); background: var(--rs-surface); }
/* stacked from the middle out, so the trio reads as centred in the stage */
.rs-slab-3 { top: calc(50% - 88px); opacity: .45; transform: translateX(-50%) scale(.86); }
.rs-slab-2 { top: calc(50% - 68px); opacity: .7;  transform: translateX(-50%) scale(.93); }
.rs-slab-1 { top: calc(50% - 48px); display: flex; flex-direction: column; gap: .75rem;
  padding: .8rem 1rem 1rem; box-shadow: var(--rs-shadow-sm); }
.rs-slab-head { display: flex; gap: 5px; }
.rs-slab-head i { width: 7px; height: 7px; border-radius: 50%; background: var(--rs-dot); }
.rs-slab-bars { flex: 1 1 auto; display: flex; align-items: flex-end; justify-content: center; gap: .5rem; }
.rs-cap-scene.is-active .rs-slab { animation: rsCapLift 3.4s var(--rs-ease) infinite; }
.rs-cap-scene.is-active .rs-slab-2 { animation-delay: .18s; }
.rs-cap-scene.is-active .rs-slab-1 { animation-delay: .36s; }
@keyframes rsCapLift {
  0%, 100% { margin-top: 0; }
  50%      { margin-top: -8px; }
}
.rs-slab-bar { width: 20px; border-radius: 4px; background: var(--rs-violet-s); transform-origin: bottom; }
.rs-slab-bar:nth-child(1) { height: 22px; }
.rs-slab-bar:nth-child(2) { height: 38px; }
.rs-slab-bar:nth-child(3) { height: 52px; background: var(--rs-violet); }
.rs-slab-bar:nth-child(4) { height: 34px; }
.rs-slab-bar:nth-child(5) { height: 46px; background: var(--rs-mint-2); }
.rs-cap-scene.is-active .rs-slab-bar { animation: rsCapBar 2.2s var(--rs-ease) infinite alternate; }
.rs-cap-scene.is-active .rs-slab-bar:nth-child(2) { animation-delay: .18s; }
.rs-cap-scene.is-active .rs-slab-bar:nth-child(3) { animation-delay: .36s; }
.rs-cap-scene.is-active .rs-slab-bar:nth-child(4) { animation-delay: .54s; }
.rs-cap-scene.is-active .rs-slab-bar:nth-child(5) { animation-delay: .72s; }
@keyframes rsCapBar { from { transform: scaleY(.55); } to { transform: scaleY(1); } }

/* 04 · data — a dashboard drawing itself in */
.rs-art-data { justify-content: center; padding-bottom: 1.6rem; }
/* the trend line is laid over the bars, not stacked under them, so both read as
   one chart however tall the stage gets */
.rs-chart { position: relative; }
.rs-bars { display: flex; align-items: flex-end; gap: .55rem; height: 120px; }
.rs-bars i { flex: 1 1 0; border-radius: 6px 6px 3px 3px; background: var(--rs-violet-s);
  transform-origin: bottom; transform: scaleY(.12); }
.rs-bars i:nth-child(2n) { background: var(--rs-mint-2); }
.rs-bars i:nth-child(1) { height: 38%; } .rs-bars i:nth-child(2) { height: 58%; }
.rs-bars i:nth-child(3) { height: 46%; } .rs-bars i:nth-child(4) { height: 78%; }
.rs-bars i:nth-child(5) { height: 62%; } .rs-bars i:nth-child(6) { height: 92%; }
.rs-bars i:nth-child(7) { height: 70%; }
.rs-cap-scene.is-active .rs-bars i { animation: rsCapGrow .9s var(--rs-ease) forwards; }
.rs-cap-scene.is-active .rs-bars i:nth-child(2) { animation-delay: .07s; }
.rs-cap-scene.is-active .rs-bars i:nth-child(3) { animation-delay: .14s; }
.rs-cap-scene.is-active .rs-bars i:nth-child(4) { animation-delay: .21s; }
.rs-cap-scene.is-active .rs-bars i:nth-child(5) { animation-delay: .28s; }
.rs-cap-scene.is-active .rs-bars i:nth-child(6) { animation-delay: .35s; }
.rs-cap-scene.is-active .rs-bars i:nth-child(7) { animation-delay: .42s; }
@keyframes rsCapGrow { to { transform: scaleY(1); } }
/* the line is revealed with a clip, not a stroke-dash: the viewBox is stretched
   non-uniformly, so dash lengths there don't map to the drawn length and the
   tail of the line never appears. */
.rs-spark { position: absolute; inset: 0; height: 100%; pointer-events: none;
  clip-path: inset(0 100% 0 0); }
.rs-spark path { fill: none; stroke: var(--rs-violet); stroke-width: 2.5; stroke-linecap: round;
  stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.rs-cap-scene.is-active .rs-spark { animation: rsCapDraw 1.4s var(--rs-ease) .3s forwards; }
@keyframes rsCapDraw { to { clip-path: inset(0 0 0 0); } }

@media (prefers-reduced-motion: reduce) {
  .rs-caps-stage *, .rs-cap-scene * { animation: none !important; }
  .rs-cap-scene { transition: opacity .2s linear, visibility 0s; transform: none; }
  .rs-bars i { transform: scaleY(1); }
  .rs-spark { clip-path: none; }
  .rs-dot { opacity: 1; }
}

.sol-callout { position: relative; overflow: hidden; color: var(--rs-paper);
  background: radial-gradient(120% 150% at 100% 0%, rgba(102,0,255,.5), transparent 55%), var(--rs-ink);
  transition: transform .35s var(--rs-ease), box-shadow .35s var(--rs-ease); }
.sol-callout::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image: linear-gradient(rgba(255,255,255,.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,.05) 1px, transparent 1px);
  background-size: 40px 40px;
  -webkit-mask-image: radial-gradient(ellipse at 100% 0%, #000, transparent 70%); mask-image: radial-gradient(ellipse at 100% 0%, #000, transparent 70%); }
.sol-callout > * { position: relative; z-index: 1; }
.sol-callout:hover { transform: translateY(-3px); box-shadow: var(--rs-shadow); }
.sol-callout .btn-arrow { transition: transform .25s var(--rs-ease); }
.sol-callout:hover .btn-arrow { transform: translateY(-1px); }

/* ---- 17 · HEADLINE MARK — retires the serif-italic split clause ------------*/
/* Headlines are now solid Bricolage throughout. At most ONE phrase per section
   carries the mark: a mint block with the design system's hard-offset shadow
   (ds-shadow) applied to type — the same signature the buttons and framed
   surfaces already wear. Em-based so it scales with the heading. */
.rs-mark {
  display: inline-block; padding: .01em .16em .07em;
  background: var(--rs-mint); color: var(--rs-ink);
  border-radius: .12em;
  box-shadow: .07em .07em 0 0 var(--rs-ink);
}
/* on navy / violet surfaces the ink shadow disappears — the block alone pops */
.bg-deep .rs-mark, #contact .rs-mark { box-shadow: none; }

/* ---- 18 · WORK — trailing project cards ride one carousel ------------------*/
/* internal padding keeps the card-hover lift + shadow inside the swiper's
   overflow clip; flex slides equalise card heights across the row */
.work-swiper { padding: 10px 8px 4px; }
.work-swiper .swiper-slide { display: flex; }
.work-swiper .swiper-slide > article { width: 100%; }

/* ---- 19 · APPLIED AI — flat navy band → blended wash canvas ----------------*/
/* The section paints the same kind of drifting violet/mint/green washes as the
   page-wide backdrop, over navy — and its top/bottom edges feather out so the
   dark block melts into the paper instead of cutting the page in two. */
#ai { background: transparent !important; }
#ai::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(44% 58% at 88% 6%,  rgba(102,0,255,.42),   transparent 62%),
    radial-gradient(38% 50% at 4% 24%,  rgba(129,255,148,.14), transparent 60%),
    radial-gradient(42% 56% at 94% 78%, rgba(14,122,63,.38),   transparent 62%),
    radial-gradient(40% 52% at 10% 96%, rgba(102,0,255,.28),   transparent 60%),
    var(--rs-ink);
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 64px, #000 calc(100% - 64px), transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0, #000 64px, #000 calc(100% - 64px), transparent 100%);
}

/* ===========================================================================
   ████  NAVBAR · flat application-chrome bar  ████
   Replaces the floating translucent pill. The thesis (borrowed from Ashby):
   the bar is INERT — edge-to-edge, solid, no border, no blur, no shadow and
   no scroll state — so it reads as chrome and the page does the moving.
   Everything expressive now lives in the mega-menu panel instead.

   Colours are ours (warm paper, navy ink, Vuci violet); only the geometry and
   the flatness are borrowed. The nav CTA drops the mint hard-shadow for a
   tighter 8px gradient chip — the mint pill still owns the hero and the page.

   Appended last on purpose: source order beats the earlier `#nav` rules.
   =========================================================================== */
/* Floating glass pill, same shape as vuci.ai's landing nav (podbits
   `assets/css/landing.css` → `.lp-nav__pill`): the strip itself is transparent
   and click-through, and the pill inside it carries the glass, the hairline and
   the shadow. Light glass here rather than vuci's dark, because this page is a
   pale mint/lavender wash. */
.rs-nav {
  position: fixed; top: 12px; left: 0; right: 0; z-index: 50;
  padding: 0 12px;
  background: transparent; border: 0; box-shadow: none;
  -webkit-backdrop-filter: none; backdrop-filter: none;
  pointer-events: none;
}
.rs-nav-inner {
  pointer-events: auto;
  display: flex; align-items: center; gap: 12px;
  height: 58px;
  /* overrides the px-5/sm:px-8 utilities on the element — the pill wants its own
     asymmetric padding (roomy at the wordmark, tight at the CTA) */
  padding-left: 18px; padding-right: 10px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.72);
  -webkit-backdrop-filter: saturate(1.7) blur(16px);
          backdrop-filter: saturate(1.7) blur(16px);
  border: 1px solid rgba(13, 27, 42, .08);
  box-shadow: 0 18px 40px -24px rgba(13, 27, 42, .55), 0 2px 6px -4px rgba(13, 27, 42, .12);
}

/* ---- brand ---------------------------------------------------------------*/
.rs-nav-brand {
  display: inline-flex; align-items: center; gap: 9px;
  font-weight: 700; font-size: 17px; letter-spacing: -.035em;
  color: var(--rs-ink); text-decoration: none; flex: none;
}
.rs-nav-brand-sub { color: var(--rs-muted); font-weight: 500; }

/* ---- centre link row -----------------------------------------------------*/
.rs-nav-links {
  display: none; align-items: center; gap: 2px;
  flex: 1 1 auto; justify-content: center;
}
@media (min-width: 980px) { .rs-nav-links { display: flex; } }

.rs-nav-trigger,
.rs-nav-link-top {
  display: inline-flex; align-items: center; gap: 4px;
  height: 32px; padding: 0 10px; border: 0; border-radius: 8px;
  background: transparent; cursor: pointer;
  font-family: inherit; font-size: 15px; font-weight: 550; letter-spacing: -.012em;
  color: var(--rs-ink-2); text-decoration: none; white-space: nowrap;
  transition: background-color .18s var(--rs-ease), color .18s var(--rs-ease);
}
.rs-nav-trigger:hover, .rs-nav-link-top:hover,
.rs-nav-trigger:focus-visible, .rs-nav-link-top:focus-visible {
  background: rgba(13,27,42,.055); color: var(--rs-ink);
}
.rs-nav-group[data-open] > .rs-nav-trigger { background: rgba(13,27,42,.055); color: var(--rs-ink); }
.rs-nav-chev { transition: transform .22s var(--rs-ease); opacity: .65; }
.rs-nav-group[data-open] .rs-nav-chev,
.rs-nav-mobile-trigger[aria-expanded="true"] .rs-nav-chev { transform: rotate(180deg); }

/* ---- mega-menu panel -----------------------------------------------------*/
.rs-nav-group { position: static; }
.rs-nav-panel {
  /* clears the floating pill (12px offset + 58px tall) with a small gap */
  position: absolute; top: 70px; left: 50%; transform: translate(-50%, -6px);
  pointer-events: none;
  width: min(760px, calc(100vw - 40px));
  background: var(--rs-surface);
  border: 1px solid var(--rs-line);
  border-radius: 18px; padding: 22px;
  box-shadow: 0 28px 60px -34px rgba(13,27,42,.55), 0 2px 6px -2px rgba(13,27,42,.06);
  /* Closed state uses visibility, not [hidden]/display:none — it still animates,
     but (unlike opacity alone) it drops the panel's links out of the tab order
     and out of the accessibility tree. The delayed visibility transition lets
     the fade-out finish before the panel is pulled. */
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .2s var(--rs-ease), transform .2s var(--rs-ease), visibility 0s linear .2s;
}
.rs-nav-group[data-open] .rs-nav-panel {
  opacity: 1; visibility: visible; transform: translate(-50%, 0); pointer-events: auto;
  transition: opacity .2s var(--rs-ease), transform .2s var(--rs-ease), visibility 0s;
}
.rs-nav-panel-grid { display: grid; grid-template-columns: 1fr 236px; gap: 22px; }
.rs-nav-col-aside { border-left: 1px solid var(--rs-line); padding-left: 22px; }
.rs-nav-col-title {
  font-size: 11px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: var(--rs-muted); margin: 0 0 10px 2px;
}

.rs-nav-col:first-child { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; }
.rs-nav-col:first-child .rs-nav-col-title { grid-column: 1 / -1; }

.rs-nav-card {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 9px 10px; border-radius: 12px; text-decoration: none;
  transition: background-color .18s var(--rs-ease);
}
.rs-nav-card:hover, .rs-nav-card:focus-visible { background: var(--rs-violet-s); }

/* ---- icon tiles ----------------------------------------------------------*/
/* The sprite itself never renders — only its <symbol>s, via <use>. */
.rs-nav-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.rs-nav-ico {
  width: 17px; height: 17px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 1.5;
  stroke-linecap: round; stroke-linejoin: round;
}
.rs-nav-ico-sm { width: 15px; height: 15px; }
.rs-nav-tile {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 9px; margin-top: 1px;
  color: var(--rs-violet);
  background-image: linear-gradient(150deg, var(--rs-mint-s), var(--rs-violet-s));
  box-shadow: inset 0 0 0 1px rgba(13,27,42,.06);
  transition: color .2s var(--rs-ease), background-image .2s var(--rs-ease),
              box-shadow .2s var(--rs-ease);
}
.rs-nav-card:hover .rs-nav-tile, .rs-nav-card:focus-visible .rs-nav-tile,
.rs-nav-mobile-link:active .rs-nav-tile, .rs-nav-mobile-sub-inner a:active .rs-nav-tile {
  color: #fff;
  background-image: linear-gradient(150deg, #7a26ff, var(--rs-violet));
  box-shadow: inset 0 0 0 1px rgba(13,27,42,.18), inset 0 1px 2px 0 rgba(255,255,255,.26);
}
.rs-nav-card-name {
  display: block; font-family: 'Bricolage Grotesque', system-ui, sans-serif;
  font-weight: 600; font-size: 14.5px; letter-spacing: -.02em; color: var(--rs-ink);
}
.rs-nav-card-desc { display: block; font-size: 12.5px; line-height: 1.35; color: var(--rs-muted); margin-top: 1px; }

.rs-nav-link {
  display: flex; align-items: center; gap: 9px; padding: 7px 10px; border-radius: 9px;
  font-size: 14px; font-weight: 500; color: var(--rs-ink-2); text-decoration: none;
  transition: background-color .18s var(--rs-ease), color .18s var(--rs-ease);
}
.rs-nav-link .rs-nav-ico { color: var(--rs-violet); opacity: .8; transition: opacity .18s var(--rs-ease); }
.rs-nav-link:hover .rs-nav-ico { opacity: 1; }
.rs-nav-link:hover, .rs-nav-link:focus-visible { background: rgba(13,27,42,.05); color: var(--rs-ink); }
.rs-nav-aside-cta {
  display: inline-flex; align-items: center; gap: 6px; margin-top: 14px; padding: 0 10px;
  font-size: 13.5px; font-weight: 600; color: var(--rs-violet); text-decoration: none;
}

/* ---- right-hand actions --------------------------------------------------*/
.rs-nav-actions { display: flex; align-items: center; gap: 8px; flex: none; margin-left: auto; }

/* The nav CTA is the brand button, full stop: mint face, ink keyline, hard
   offset shadow — the same object as the hero and footer CTAs. It used to be a
   bespoke violet gradient chip, which made the one button every visitor sees
   first the only button on the site that wasn't on-brand. */
.rs-nav-cta {
  display: none; align-items: center; gap: 6px;
  height: 38px; padding: 0 17px; border-radius: 999px;
  background: var(--rs-mint); color: var(--rs-ink); text-decoration: none;
  border: 1.5px solid var(--rs-ink);
  font-size: 14.5px; font-weight: 700; letter-spacing: -.012em; white-space: nowrap;
  box-shadow: 2px 2px 0 0 var(--rs-ink);
  transition: transform 250ms cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 250ms ease;
}
.rs-nav-cta:hover { transform: translate(-2px, -2px); box-shadow: 4px 4px 0 0 var(--rs-ink); }
.rs-nav-cta:active { transform: translate(0, 0); box-shadow: 1px 1px 0 0 var(--rs-ink); }
@media (min-width: 640px) { .rs-nav-cta { display: inline-flex; } }

/* ---- burger + mobile sheet ----------------------------------------------*/
.rs-nav-burger {
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px;
  width: 36px; height: 36px; margin-right: -6px; border: 0; background: transparent; cursor: pointer;
}
.rs-nav-burger span { display: block; width: 18px; height: 1.5px; background: var(--rs-ink); border-radius: 2px; }
@media (min-width: 980px) { .rs-nav-burger { display: none; } }

/* The sheet and its sub-list both animate to their natural height via
   grid-template-rows 0fr→1fr — no hard-coded max-height to outgrow, and no
   layout thrash. `visibility` (delayed on close) keeps the closed sheet out of
   the tab order and the a11y tree, the same contract as the desktop panel. */
.rs-nav-mobile,
.rs-nav-mobile-sub {
  display: grid; grid-template-rows: 0fr;
  /* the strip above is click-through so the pill can float; the sheet has to
     opt back in or its links are dead */
  pointer-events: auto;
  visibility: hidden;
  transition: grid-template-rows .38s var(--rs-ease), visibility 0s linear .38s;
}
.rs-nav-mobile[data-open],
.rs-nav-mobile-sub[data-open] {
  grid-template-rows: 1fr; visibility: visible;
  transition: grid-template-rows .42s var(--rs-ease), visibility 0s;
}
.rs-nav-mobile-clip { overflow: hidden; min-height: 0; }

/* Border + shadow live on the inner, so nothing shows as a stray hairline
   while the sheet is collapsed to zero height. */
/* a floating card under the floating pill, not a full-bleed drawer welded to a
   bar that no longer touches the top of the viewport */
.rs-nav-mobile-inner {
  margin-top: 8px; padding-top: 14px; padding-bottom: 20px;
  background: rgba(255, 255, 255, .92);
  -webkit-backdrop-filter: saturate(1.7) blur(16px);
          backdrop-filter: saturate(1.7) blur(16px);
  border: 1px solid rgba(13, 27, 42, .08); border-radius: 20px;
  box-shadow: 0 24px 46px -28px rgba(13,27,42,.55);
}
.rs-nav-mobile-trigger,
.rs-nav-mobile-link {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 9px 0; border: 0; background: transparent; cursor: pointer;
  font-family: inherit; font-size: 16px; font-weight: 550; text-align: left;
  color: var(--rs-ink); text-decoration: none;
  /* staggered entrance — see the nth-child delays below */
  opacity: 0; transform: translateY(-6px);
  transition: opacity .3s var(--rs-ease), transform .3s var(--rs-ease);
}
.rs-nav-mobile-trigger { justify-content: space-between; }
.rs-nav-mobile-label { display: flex; align-items: center; gap: 12px; }
.rs-nav-mobile .rs-nav-chev { transition: transform .3s var(--rs-ease); }
.rs-nav-mobile-trigger[aria-expanded="true"] .rs-nav-chev { transform: rotate(180deg); }

.rs-nav-mobile-sub-inner { padding: 2px 0 6px 6px; }
.rs-nav-mobile-sub-inner a {
  display: flex; align-items: center; gap: 12px; padding: 7px 0;
  font-size: 15px; font-weight: 500; color: var(--rs-ink-2); text-decoration: none;
}
.rs-nav-cta-block {
  display: flex; justify-content: center; height: 46px; margin-top: 16px; font-size: 15.5px;
  opacity: 0; transform: translateY(-6px);
  transition: opacity .3s var(--rs-ease), transform .3s var(--rs-ease);
}

/* Rows fade+drop in sequence once the sheet is open. The 0.10s base delay lets
   the height transition get underway first, so items never appear to lead it. */
.rs-nav-mobile[data-open] .rs-nav-mobile-inner > * { opacity: 1; transform: none; }
.rs-nav-mobile[data-open] .rs-nav-mobile-inner > :nth-child(1) { transition-delay: .10s; }
.rs-nav-mobile[data-open] .rs-nav-mobile-inner > :nth-child(2) { transition-delay: .14s; }
.rs-nav-mobile[data-open] .rs-nav-mobile-inner > :nth-child(3) { transition-delay: .18s; }
.rs-nav-mobile[data-open] .rs-nav-mobile-inner > :nth-child(4) { transition-delay: .22s; }
.rs-nav-mobile[data-open] .rs-nav-mobile-inner > :nth-child(5) { transition-delay: .26s; }
.rs-nav-mobile[data-open] .rs-nav-mobile-inner > :nth-child(6) { transition-delay: .30s; }
.rs-nav-mobile[data-open] .rs-nav-mobile-inner > :nth-child(7) { transition-delay: .34s; }

/* burger morphs into a close cross */
.rs-nav-burger span { transition: transform .32s var(--rs-ease), opacity .2s var(--rs-ease); }
.rs-nav-burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.rs-nav-burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; transform: scaleX(.4); }
.rs-nav-burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

/* the bar is 64px now, not a 92px floating card */
section[id] { scroll-margin-top: 84px; }

@media (prefers-reduced-motion: reduce) {
  .rs-nav-panel,
  .rs-nav-mobile, .rs-nav-mobile-sub,
  .rs-nav-mobile-trigger, .rs-nav-mobile-link, .rs-nav-cta-block,
  .rs-nav-burger span, .rs-nav-chev, .rs-nav-tile { transition: none !important; }
  /* no stagger — rows are simply present the moment the sheet opens */
  .rs-nav-mobile-trigger, .rs-nav-mobile-link, .rs-nav-cta-block { opacity: 1; transform: none; }
}


/* ===========================================================================
   ████  HERO · compacted + tabbed client showcase  ████
   Thesis: the fold sells one claim and four proofs. The copy column is short
   by construction; the showcase folds four builds into the footprint of one.

   Motion has a single authored moment — the showcase switch. One indicator
   travels between tabs (FLIP, measured in JS) while the outgoing shot lifts and
   the incoming one settles in behind it. Everything else is quiet feedback.
   The copy entrance is CSS-only so a failed script can never blank the fold.
   =========================================================================== */

/* ---- geometry ------------------------------------------------------------*/
.rs-hero-pad { padding-top: 104px; padding-bottom: 56px; }
@media (min-width: 640px) { .rs-hero-pad { padding-top: 120px; padding-bottom: 64px; } }
@media (min-width: 1024px) { .rs-hero-pad { padding-top: 128px; } }

/* Headline: one clause, two lines. Tracking sits at the -0.04em floor rather
   than the -0.045em it used to run, which was over-tight at display size. */
.rs-hero-title {
  font-size: clamp(40px, 4.4vw, 62px) !important;
  line-height: 1.02 !important;
  letter-spacing: -0.04em !important;
}
.rs-hero-title .rs-line { display: block; }
.rs-hero-lede {
  margin-top: 18px;
  font-size: clamp(16px, 1.15vw, 17.5px) !important;
  line-height: 1.6 !important;
  color: var(--rs-ink-2) !important;
  max-width: 31rem;
  /* balance, not pretty: at three lines this evens the measure instead of only
     fixing the last-line orphan, which left line 2 running to the column edge
     and crowding the showcase beside it. */
  text-wrap: balance;
}
.rs-hero-actions { margin-top: 26px; display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }

/* The three claims that used to be a 3-up grid of icon+two-line chips. Same
   words, one row, ~90px less height. */
.rs-hero-proof {
  margin: 22px 0 0; padding: 0; list-style: none;
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 18px;
  /* ink-2, not muted: --rs-muted on paper is 2.97:1 and fails at 13px. */
  font-size: 13px; color: var(--rs-ink-2);
}
.rs-hero-proof li { display: flex; align-items: center; gap: 7px; }
.rs-hero-proof li::before {
  content: ""; width: 5px; height: 5px; border-radius: 50%;
  background: var(--rs-green); flex: none;
}

/* ---- showcase shell ------------------------------------------------------*/
/* min-width:0 all the way down. Grid items and flex items both default to
   min-width:auto, so the nowrap tab row's min-content width propagated up and
   widened the whole hero track past the viewport — the lede, the proof row and
   the frame all overflowed, invisibly, behind the section's overflow-hidden. */
.rs-hero-copy, .rs-hero-stage { min-width: 0; }
.rs-show { position: relative; min-width: 0; }
.rs-show-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-bottom: 14px; min-width: 0;
}
/* One row that scrolls, never a row that wraps. Wrapping put the four tabs on
   three rows at 390px and left the travelling indicator on the wrong one. */
.rs-show-tabs {
  position: relative; display: flex; align-items: center; gap: 2px;
  flex-wrap: nowrap; overflow-x: auto; overscroll-behavior-x: contain;
  scrollbar-width: none; -ms-overflow-style: none;
  scroll-snap-type: x proximity; padding-bottom: 1px;
  /* Load-bearing: a flex item defaults to min-width:auto, so this row sized to
     its content (436px inside a 390px screen) and never scrolled — the hero's
     overflow-hidden simply clipped the fourth tab out of reach. */
  min-width: 0; flex: 1 1 auto;
}
.rs-show-tabs::-webkit-scrollbar { display: none; }
.rs-show-tab { scroll-snap-align: start; }

/* The single travelling indicator — position/size written by JS.
   Animating the box width here is deliberate, and exempt from the usual
   don't-animate-layout-properties rule: the element is position:absolute, so
   it is out of flow and cannot reflow anything else. The alternative, scaleX
   on a fixed box, visibly squashes the 10px corner radius. Measured across a
   switch: median frame 8.3ms, worst 11.6ms, zero frames over 20ms. */
.rs-show-ind {
  position: absolute; top: 0; left: 0; height: 34px;
  /* mint + ink keyline, matching the Vuci button language the CTAs now use —
     the bar was a flat ink pill, which belonged to no part of the brand. */
  border-radius: 999px; background: var(--rs-mint); z-index: 0;
  box-shadow: inset 0 0 0 1.5px var(--rs-ink);
  transform: translate3d(var(--ind-x, 0), var(--ind-y, 0), 0); width: var(--ind-w, 0);
  transition: transform .42s var(--rs-ease), width .42s var(--rs-ease), opacity .2s;
  opacity: 0;
}
.rs-show-ind.is-ready { opacity: 1; }

.rs-show-tab {
  position: relative; z-index: 1;
  display: inline-flex; align-items: center; gap: 7px;
  height: 34px; padding: 0 13px; border: 0; border-radius: 999px;
  background: transparent; cursor: pointer;
  font-family: inherit; font-size: 13.5px; font-weight: 550; letter-spacing: -.012em;
  color: var(--rs-ink-2); white-space: nowrap;
  transition: color .28s var(--rs-ease);
}
.rs-show-tab .rs-nav-ico { color: var(--rs-violet); transition: color .28s var(--rs-ease); }
.rs-show-tab:hover { color: var(--rs-ink); }
.rs-show-tab[aria-selected="true"] { color: var(--rs-ink); font-weight: 700; }
.rs-show-tab[aria-selected="true"] .rs-nav-ico { color: var(--rs-ink); }

.rs-show-nav { display: flex; gap: 6px; flex: none; }
.rs-show-arrow {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 50%; cursor: pointer;
  border: 1px solid var(--rs-line-2); background: var(--rs-surface); color: var(--rs-ink-2);
  transition: background-color .2s var(--rs-ease), color .2s var(--rs-ease),
              border-color .2s var(--rs-ease), transform .2s var(--rs-ease);
}
.rs-show-arrow:hover { background: var(--rs-ink); border-color: var(--rs-ink); color: var(--rs-paper); }
.rs-show-arrow:active { transform: scale(.92); }

/* ---- 3D deck -------------------------------------------------------------*/
/* The showcase sits on a perspective stage as the front card of a deck — the
   same object language as the "Things I've built" deck, at rest rather than
   draggable. The wrapper takes its height from the frame's aspect-ratio, so the
   ghosts can just inset:0 onto it. Hovering anywhere in the showcase squares
   the deck up to the viewer, which is also what makes the tab row feel live.
   Flat below 1024px: at phone width a tilt only costs legibility. */
.rs-show-deck { position: relative; }
.rs-show-ghost { display: none; }
@media (min-width: 1024px) {
  .rs-show-deck {
    perspective: 1800px; perspective-origin: 72% 45%;
    transform-style: preserve-3d;
  }
  .rs-show-deck > .rs-show-frame {
    transform: rotateY(-7deg) rotateX(2deg);
    transform-origin: 100% 50%;
    transition: transform .6s var(--rs-ease), box-shadow .6s var(--rs-ease);
    will-change: transform;
    /* the mint hard-offset shadow is a flat-art signature — rotated in 3D it
       skews into a green smear, so while the deck is tilted the depth comes
       from a plain drop shadow and the mint returns when it squares up */
    box-shadow: 0 40px 80px -40px rgba(13, 27, 42, .55);
  }
  .rs-show-ghost {
    display: block; position: absolute; inset: 0;
    border-radius: 22px; background: var(--rs-surface);
    border: 1px solid var(--rs-line-2);
    transform-origin: 100% 50%;
    transition: transform .6s var(--rs-ease), opacity .6s var(--rs-ease);
    pointer-events: none;
  }
  .rs-show-ghost--1 { opacity: .55; transform: translate3d(2.5%, -3.5%, -90px) rotateY(-7deg) rotateX(2deg); }
  .rs-show-ghost--2 { opacity: .3;  transform: translate3d(5%, -7%, -180px) rotateY(-7deg) rotateX(2deg); }

  .rs-show:hover > .rs-show-deck > .rs-show-frame,
  .rs-show:focus-within > .rs-show-deck > .rs-show-frame {
    transform: rotateY(0deg) rotateX(0deg);
    box-shadow: var(--rs-shadow), 10px 10px 0 0 var(--rs-mint);
  }
  .rs-show:hover .rs-show-ghost--1,
  .rs-show:focus-within .rs-show-ghost--1 { transform: translate3d(1.5%, -2.5%, -70px); }
  .rs-show:hover .rs-show-ghost--2,
  .rs-show:focus-within .rs-show-ghost--2 { transform: translate3d(3%, -5%, -140px); }
}
@media (prefers-reduced-motion: reduce) {
  .rs-show-ghost { display: none; }
  .rs-show-deck > .rs-show-frame { transform: none; }
}

/* ---- frame ---------------------------------------------------------------*/
/* Fixed aspect: the four screenshots have ratios from 0.65 to 1.93, so the
   frame — not the image — owns the height. Switching tabs cannot shift layout. */
.rs-show-frame {
  position: relative;
  aspect-ratio: 16 / 11;
  border-radius: 22px;
  background: var(--rs-surface);
  border: 1px solid var(--rs-line-2);
  box-shadow: var(--rs-shadow), 10px 10px 0 0 var(--rs-mint);
  overflow: hidden;
}
@media (max-width: 640px) { .rs-show-frame { box-shadow: var(--rs-shadow-sm), 6px 6px 0 0 var(--rs-mint); } }
/* Tablet stacks copy above the frame while the frame is still full-width, which
   pushed the hero just past the fold (1057px at 768). A wider ratio buys it back. */
@media (min-width: 641px) and (max-width: 1023px) { .rs-show-frame { aspect-ratio: 16 / 9; } }

.rs-show-panel {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  opacity: 0; visibility: hidden;
  transition: opacity .34s var(--rs-ease), visibility 0s linear .34s;
}
.rs-show-panel.is-active { opacity: 1; visibility: visible; transition: opacity .34s var(--rs-ease), visibility 0s; }
.rs-show-panel[hidden] { display: flex; }   /* JS drives visibility; keep it animatable */

.rs-show-chrome {
  flex: none; display: flex; align-items: center; gap: 6px;
  height: 32px; padding: 0 12px;
  border-bottom: 1px solid var(--rs-line); background: var(--rs-paper);
}
.rs-show-chrome span { width: 8px; height: 8px; border-radius: 50%; background: var(--rs-dot); }
.rs-show-chrome em {
  margin-left: 8px; font-style: normal;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  /* 10.5px on ink-2 (7.7:1); --rs-muted here measured 2.97:1 and failed. */
  font-size: 10.5px; color: var(--rs-ink-2);
}

/* Authored focus ring — the UA default (outline: 1px auto) all but disappears
   against the dark active tab. */
.rs-show-tab:focus-visible,
.rs-show-arrow:focus-visible {
  outline: 2px solid var(--rs-violet);
  outline-offset: 2px;
  border-radius: 999px;
}
.rs-show-tab[aria-selected="true"]:focus-visible { outline-color: var(--rs-ink); }
.rs-show-shot { position: relative; flex: 1 1 auto; overflow: hidden; background: var(--rs-mist); }
.rs-show-shot img {
  width: 100%; height: 100%; display: block;
  object-fit: cover; object-position: top center;
  transform-origin: top left;
}
/* On a phone the whole dashboard shrinks to unreadable texture. Crop into the
   top-left instead, so what's on screen is legible product rather than a
   thumbnail of one. */
@media (max-width: 640px) { .rs-show-shot img { --shot-zoom: 1.45; object-position: top left; } }
.rs-show-cap {
  flex: none; margin: 0; padding: 11px 14px;
  border-top: 1px solid var(--rs-line); background: var(--rs-surface);
  font-size: 13px; line-height: 1.45; color: var(--rs-ink-2) !important;
}
.rs-show-cap strong { color: var(--rs-ink); font-weight: 600; }

/* The authored moment: the outgoing shot lifts away as the incoming one
   settles down into the frame, so the switch reads as one physical exchange
   rather than two independent fades. */
/* Composed with --shot-zoom (the mobile crop) so the two never fight over
   `transform`: the exchange is a delta on top of whatever zoom is in force. */
.rs-show-panel .rs-show-shot img {
  transform: scale(calc(var(--shot-zoom, 1) * 1.04)) translateY(-1.5%);
  transition: transform .55s var(--rs-ease);
}
.rs-show-panel.is-active .rs-show-shot img { transform: scale(var(--shot-zoom, 1)); }
.rs-show-panel .rs-show-cap { opacity: 0; transform: translateY(6px); transition: opacity .3s var(--rs-ease) .08s, transform .3s var(--rs-ease) .08s; }
.rs-show-panel.is-active .rs-show-cap { opacity: 1; transform: none; }

/* ---- copy entrance (CSS-only, so a dead script never blanks the fold) -----*/
@keyframes rsHeroLine { from { opacity: 0; transform: translateY(14px); clip-path: inset(0 0 105% 0); }
                          to { opacity: 1; transform: none;             clip-path: inset(0 0 -20% 0); } }
@keyframes rsHeroRise { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@keyframes rsHeroStage { from { opacity: 0; transform: translateY(18px) scale(.985); } to { opacity: 1; transform: none; } }

.rs-hero-title .rs-line { animation: rsHeroLine .8s var(--rs-ease) both; }
.rs-hero-title .rs-line:nth-child(2) { animation-delay: .08s; }
.rs-hero-title .rs-line:nth-child(3) { animation-delay: .16s; }
.rs-hero-lede    { animation: rsHeroRise .6s var(--rs-ease) .28s both; }
.rs-hero-actions { animation: rsHeroRise .6s var(--rs-ease) .36s both; }
.rs-hero-proof   { animation: rsHeroRise .6s var(--rs-ease) .44s both; }
.rs-hero-stage   { animation: rsHeroStage .75s var(--rs-ease) .16s both; }

@media (prefers-reduced-motion: reduce) {
  .rs-hero-title .rs-line, .rs-hero-lede, .rs-hero-actions,
  .rs-hero-proof, .rs-hero-stage { animation: none !important; }
  .rs-show-ind, .rs-show-panel, .rs-show-arrow,
  .rs-show-panel .rs-show-shot img, .rs-show-panel .rs-show-cap { transition: none !important; }
  .rs-show-panel .rs-show-shot img { transform: scale(var(--shot-zoom, 1)) !important; }
  .rs-show-panel .rs-show-cap { opacity: 1 !important; transform: none !important; }
}

/* ---- typed headline accent ------------------------------------------------*/
/* The second headline line types through the service range. Two nested spans
   are load-bearing:
     .rs-type       the slot — JS locks its min-width to the widest word so the
                    headline never reflows mid-type;
     .rs-type-word  the text itself — the waveform underline is drawn on this,
                    so the rule tracks the *typed* width, not the locked slot.

   The underline is the design system's accent (podbits-base.css --ds-wave-*):
   ten rounded bars used as a repeating mask. Deliberately NOT the cursive
   mint→violet gradient from vuci.ai/welcome — podbits deprecates that as an
   AI-tell and points at this instead. */
:root {
  /* A hand-drawn squiggle: two mirrored quadratic curves per tile, so the
     repeat joins on the baseline and the wave reads as continuous rather than
     as a row of arcs. Replaces the design system's ten-bar waveform strip,
     which at this size read as a dotted rule instead of an accent.

     The stroke is scaled non-uniformly (preserveAspectRatio: none), so the
     viewBox ratio and the unit/height ratio below are kept close — otherwise
     the line thins out at the crests. */
  --rs-wave-svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 8' preserveAspectRatio='none'%3E%3Cpath d='M0 5.6 Q3 0.4 6 4 T12 4 T18 4 T24 5.6' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round'/%3E%3C/svg%3E");
  --rs-wave-unit: 0.78em;
  --rs-wave-height: 0.22em;
  --rs-wave-gap: 0.04em;
}

.rs-type {
  display: inline-block; text-align: left; white-space: nowrap;
  padding-bottom: calc(var(--rs-wave-gap) + var(--rs-wave-height));
}
.rs-type-word {
  position: relative; display: inline-block;
  color: var(--rs-violet);
}
.rs-type-word::after {
  content: ""; position: absolute;
  left: 0.04em; right: 0.06em; bottom: calc(-1 * var(--rs-wave-gap));
  height: var(--rs-wave-height); background: var(--rs-violet);
  -webkit-mask-image: var(--rs-wave-svg);          mask-image: var(--rs-wave-svg);
  -webkit-mask-repeat: repeat-x;                   mask-repeat: repeat-x;
  -webkit-mask-size: var(--rs-wave-unit) 100%;     mask-size: var(--rs-wave-unit) 100%;
  -webkit-mask-position: left center;              mask-position: left center;
}
/* Empty between words — no bare underline floating on its own. */
.rs-type-word:empty::after { display: none; }

.rs-type-caret {
  display: inline-block; width: 0; height: 0.72em;
  border-right: 0.055em solid var(--rs-violet);
  margin-left: 0.04em; vertical-align: -0.02em;
  animation: rsCaret 1.05s step-end infinite;
}
@keyframes rsCaret { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }

/* Visually hidden, still announced. The cycling word is aria-hidden, so this
   carries the real sentence for assistive tech. */
.rs-sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

@media (prefers-reduced-motion: reduce) {
  /* JS leaves the first word static; kill the caret blink too. */
  .rs-type-caret { animation: none; opacity: 0; }
}

/* ===========================================================================
   FLOW — sticky scroll-driven walkthrough
   Pattern from vorrio.onrender.com's "One day with Vorrio": one sticky visual
   stage beside a column of steps. As each step reaches the middle of the
   viewport it becomes active, the stage swaps scene, and the other steps dim.

   This section absorbs four that used to be separate — the design row, the
   internal-tools row, the AI teaser, and "How we work" — so the page tells one
   continuous story instead of four disconnected pitches.
   =========================================================================== */
.rs-flow-grid { display: grid; gap: 28px; }
@media (min-width: 1024px) {
  /* stage gets the wider track — it holds 16:10 screenshots */
  .rs-flow-grid { grid-template-columns: minmax(0, 1.18fr) minmax(0, 1fr); gap: 52px; align-items: start; }
}

/* Sticky only where the grid is actually two columns (1024px up). Below that
   the section is one column, so a pinned stage just ate a quarter of the
   viewport for 2,500px of scroll while the steps filed past underneath it —
   there the steps become a swipeable rail under a static stage instead. */
.rs-flow-sticky { position: static; z-index: 1; }
@media (min-width: 1024px) { .rs-flow-sticky { position: sticky; top: 96px; } }

.rs-flow-stage {
  position: relative; overflow: hidden;
  height: 224px; border-radius: 20px;
  background: var(--rs-surface); border: 1px solid var(--rs-line-2);
  box-shadow: var(--rs-shadow), 8px 8px 0 0 var(--rs-mint);
}
@media (min-width: 1024px) { .rs-flow-stage { height: 428px; border-radius: 22px; box-shadow: var(--rs-shadow), 10px 10px 0 0 var(--rs-mint); } }

.rs-flow-scene {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  opacity: 0; visibility: hidden;
  transition: opacity .45s var(--rs-ease), visibility 0s linear .45s, transform .55s var(--rs-ease);
  transform: scale(1.03) translateY(-1.2%);
}
.rs-flow-scene.is-active {
  opacity: 1; visibility: visible; transform: none;
  transition: opacity .45s var(--rs-ease), visibility 0s, transform .55s var(--rs-ease);
}
.rs-flow-scene > .shot, .rs-flow-scene > .rs-flow-fill { flex: 1 1 auto; min-height: 0; }
/* Top-left, not top-centre: these are 16:10 screenshots in a near-square stage,
   so centring crops both edges and beheads the app's own left nav. Anchoring
   left keeps the part of the UI that identifies the product. */
.rs-flow-scene img { width: 100%; height: 100%; object-fit: cover; object-position: top left; }

/* scene chrome, same language as the hero showcase */
.rs-flow-chrome {
  flex: none; display: flex; align-items: center; gap: 6px; height: 32px; padding: 0 12px;
  border-bottom: 1px solid var(--rs-line); background: var(--rs-paper);
}
.rs-flow-chrome span { width: 8px; height: 8px; border-radius: 50%; background: var(--rs-dot); }
.rs-flow-chrome em {
  margin-left: 8px; font-style: normal; font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 10.5px; color: var(--rs-ink-2);
}

/* progress rail — which step of four, mirrored from vorrio's dot row */
.rs-flow-rail { display: flex; gap: 5px; padding: 10px 14px; border-top: 1px solid var(--rs-line); background: var(--rs-surface); flex: none; }
.rs-flow-rail i { height: 3px; flex: 1; border-radius: 2px; background: var(--rs-line-2); transition: background-color .4s var(--rs-ease); }
.rs-flow-rail i.on { background: var(--rs-violet); }

/* ---- steps ---------------------------------------------------------------*/
.rs-flow-steps { display: flex; flex-direction: column; }
.rs-flow-step {
  padding: 40px 0;
  opacity: .5; transition: opacity .45s var(--rs-ease);
}
.rs-flow-step.is-active { opacity: 1; }

/* Below the two-column breakpoint: one step per screen on a snap rail, driven
   by trackSwipe. Cards are equal height (align-items: stretch) so the rail
   doesn't jump as it pages. */
@media (max-width: 1023px) {
  .rs-flow-steps {
    flex-direction: row; align-items: stretch; gap: 12px;
    margin-top: 20px; padding-bottom: 2px;
    overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scrollbar-width: none; -ms-overflow-style: none;
  }
  .rs-flow-steps::-webkit-scrollbar { display: none; }
  .rs-flow-step {
    flex: 0 0 86%; scroll-snap-align: center;
    padding: 18px; border-radius: 16px;
    background: var(--rs-surface); border: 1px solid var(--rs-line);
    opacity: 1;
    transition: border-color .3s var(--rs-ease), box-shadow .3s var(--rs-ease);
  }
  .rs-flow-step.is-active { border-color: var(--rs-line-2); box-shadow: var(--rs-shadow-sm); }
  .rs-flow-step h3 { font-size: 22px; }
  .rs-flow-step > p { margin-top: 10px; font-size: 15px; }
  .rs-flow-list { margin-top: 14px; gap: 10px; }
  .rs-flow-list li { font-size: 13.5px; }
}
@media (min-width: 1024px) {
  /* Tall enough that one step owns the viewport while the stage holds its scene.
     Top-aligned, not centred: the steps column starts level with the stage, so
     centring inside a 78vh block dropped step 01's heading a third of a screen
     below the top of the image it sits beside. */
  .rs-flow-step { min-height: 78vh; display: flex; flex-direction: column; justify-content: flex-start; padding: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .rs-flow-step { opacity: 1; }
  .rs-flow-scene { transition: none; transform: none; }
}

.rs-flow-idx {
  display: inline-flex; align-items: center; gap: 10px; margin-bottom: 14px;
  font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 11px;
  letter-spacing: .12em; text-transform: uppercase; color: var(--rs-ink-2);
}
.rs-flow-idx b { color: var(--rs-violet); font-weight: 600; }
.rs-flow-step h3 {
  font-family: 'Bricolage Grotesque', system-ui, sans-serif; font-weight: 700;
  font-size: clamp(26px, 3vw, 38px); line-height: 1.06; letter-spacing: -0.035em; color: var(--rs-ink);
}
.rs-flow-step > p { margin-top: 14px; font-size: 16px; line-height: 1.6; color: var(--rs-ink-2); max-width: 34rem; }
/* The rotated-square bullet was a shape, not a sign — it said the same nothing
   twelve times. Each item now carries an authored icon on one 24 grid at 1.7
   stroke with round joins, seated in a token that matches the card language. */
.rs-flow-list { margin: 20px 0 0; padding: 0; list-style: none; display: grid; gap: 12px; }
.rs-flow-list li {
  display: flex; align-items: flex-start; gap: 12px;
  font-size: 14.5px; line-height: 1.5; color: var(--rs-ink-2);
}
.rs-ic {
  flex: none; width: 30px; height: 30px; margin-top: -2px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 9px; background: var(--rs-surface);
  border: 1px solid var(--rs-line-2); color: var(--rs-violet);
  box-shadow: 0 1px 2px rgba(13, 27, 42, .05);
  transition: color .3s var(--rs-ease), border-color .3s var(--rs-ease),
              background-color .3s var(--rs-ease), transform .3s var(--rs-ease);
}
.rs-ic svg { width: 16px; height: 16px; }
/* the active step's icons come up to full strength with it */
.rs-flow-step.is-active .rs-ic { border-color: rgba(102, 0, 255, .28); background: var(--rs-violet-s); }
.rs-flow-list li:hover .rs-ic { transform: translateY(-1px); border-color: var(--rs-violet); }
@media (prefers-reduced-motion: reduce) { .rs-ic { transition: none; } }


/* ===========================================================================
   PRICING CARDS — ported from podbits' ds_pricing_card (.dpc) contract
   Alignment rules kept verbatim from assets/css/_dpc.css:
     - flex column so the CTA sits at margin-top:auto
     - .rs-pc-sub has a min-height so the price blocks line up across cards
       regardless of how long each subtitle runs
     - featured card gets a mint outline + badge (never violet — that is
       reserved for data highlights in the source system)
   =========================================================================== */
.rs-pricing { display: grid; gap: 18px; }
@media (min-width: 860px) { .rs-pricing { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; } }

.rs-pc {
  position: relative; display: flex; flex-direction: column;
  border-radius: 20px; padding: 1.5rem;
  background: var(--rs-surface);
  border: 1.5px solid var(--rs-line-2);
  transition: transform .3s var(--rs-ease), box-shadow .3s var(--rs-ease);
}
.rs-pc:hover { transform: translateY(-3px); box-shadow: var(--rs-shadow-sm); }
.rs-pc--featured {
  outline: 2.5px solid var(--rs-mint); outline-offset: -2px; border-color: transparent;
  box-shadow: 6px 6px 0 0 var(--rs-ink);
}
.rs-pc--featured:hover { box-shadow: 9px 9px 0 0 var(--rs-ink); transform: translate(-3px, -3px); }

.rs-pc-badge {
  position: absolute; top: -11px; left: 1.5rem;
  background: var(--rs-mint); color: var(--rs-ink);
  border: 1.5px solid var(--rs-ink); border-radius: 999px;
  padding: 2px 11px; font-size: 11px; font-weight: 700; letter-spacing: .04em;
}
.rs-pc-name { font-family: 'Bricolage Grotesque', system-ui, sans-serif; font-weight: 700; font-size: 19px; letter-spacing: -.02em; color: var(--rs-ink); }
.rs-pc-sub { margin-top: 6px; font-size: 13.5px; line-height: 1.45; color: var(--rs-ink-2); min-height: 3.2em; }
.rs-pc-price { margin-top: 14px; display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; min-height: 2.4em; }
.rs-pc-price b { font-family: 'Bricolage Grotesque', system-ui, sans-serif; font-weight: 800; font-size: 30px; letter-spacing: -.035em; color: var(--rs-ink); }
.rs-pc-price span { font-size: 13.5px; color: var(--rs-ink-2); }
.rs-pc-rule { height: 1px; background: var(--rs-line); margin: 16px 0 14px; }
.rs-pc-list { margin: 0; padding: 0; list-style: none; display: grid; gap: 9px; }
.rs-pc-list li { display: flex; align-items: flex-start; gap: 9px; font-size: 13.5px; line-height: 1.45; color: var(--rs-ink-2); }
.rs-pc-list li svg { flex: none; margin-top: 2px; color: var(--rs-green); }
.rs-pc-cta { margin-top: auto; padding-top: 20px; }
.rs-pc-cta a { display: flex; justify-content: center; }
.rs-pc-note { margin-top: 18px; font-size: 13px; color: var(--rs-ink-2); }

/* ---- inline booking ------------------------------------------------------ */
/* one centred column: heading, the widget, the write-instead line */
.rs-book { max-width: 1040px; margin: 0 auto; padding: 4rem 0 5rem; }
@media (min-width: 640px) { .rs-book { padding: 5rem 0 6rem; } }
.rs-book-embed {
  margin-top: 26px; border-radius: 20px; overflow: hidden; background: var(--rs-surface);
  border: 1.5px solid var(--rs-line-2); box-shadow: var(--rs-shadow);
  min-height: 560px;
  /* the widget reports its own height and cal.com will happily ask for 1600px+
     on a narrow month view; cap the card and let the iframe scroll inside it so
     the booking flow never dwarfs the rest of the page */
  max-height: 720px;
}
.rs-book-embed > div { min-height: 560px; max-height: 720px; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.rs-book-alt { margin-top: 20px; text-align: center; font-size: 15px; color: var(--rs-ink-2); }

/* brand work, folded in as the work section's closing row */
.rs-work-brand { margin-top: 2.5rem; padding-top: 2.5rem; border-top: 1px solid var(--rs-line); }

/* Scene 1 is the Figma canvas, which brings its own title bar and fills the
   stage rather than sitting inside a .shot frame. */
.rs-flow-scene--fig { background: var(--rs-surface); }
.rs-flow-scene--fig .figma-grid { min-height: 0; }

/* ---- connectors marquee, folded into Solutions -------------------------- */
/* Was a full-bleed page-wide band with its own heading. It now sits directly
   above the solutions grid at the width of the content, so it reads as part of
   that section. The mask feathers both ends so the loop has no hard cut. */
.rs-conn {
  margin: 0 0 1.25rem; border-radius: 16px; overflow: hidden;
  background: rgba(255, 255, 255, 0.5);
  border: 1px solid var(--rs-line);
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
}
.rs-conn .marquee-wrap { padding: 12px 0; }


/* ---- BOOK — responsive -------------------------------------------------- */
/* The cal.com iframe reports a desktop-width layout and was overflowing its
   container on phones. Clip at the container and let the widget scroll inside
   its own box rather than pushing the page sideways. */
.rs-book-embed { overflow: hidden; max-width: 100%; }
.rs-book-embed > div { max-width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.rs-book-embed iframe { max-width: 100% !important; }
@media (max-width: 640px) {
  .rs-book-embed, .rs-book-embed > div { min-height: 460px; }
  .rs-book-embed { border-radius: 16px; }
}

/* ===========================================================================
   WORK — the project deck
   Copy on the left, a 3D deck of the real screenshots on the right, paged with
   the arrows, a drag, or the arrow keys. Replaced two full-width alternating
   articles plus a five-card carousel.

   The deck is finite, not looping: it dead-ends at both edges and the arrows
   disable there. Wrapping around would have to fly the front card back through
   the stack to reach the last slot, which reads as a glitch at this depth.
   =========================================================================== */

.rs-deck { display: grid; gap: 2.5rem; padding: 3.5rem 0 4rem; align-items: center; }
@media (min-width: 1024px) {
  .rs-deck { grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr); gap: 4rem; padding: 4.5rem 0 4.5rem; }
}
/* both children must opt out of the implicit min-width:auto, or the deck's
   absolutely-positioned cards inflate the track and push the page sideways */
.rs-deck-copy, .rs-deck-stage { min-width: 0; }

/* ---- left column -------------------------------------------------------- */
/* The panels are stacked in the same grid cell so the column does not resize
   as projects change; the tallest sets the height once and it stays put. */
/* All panels share one grid cell, so the cell keeps the height of the TALLEST
   and the arrows below it never move as projects change. Inactive panels are
   hidden with visibility rather than display — display:none would collapse the
   cell back to the active panel's height and reintroduce the jump. visibility
   also takes them out of the tab order, which display:none did for free. */
.rs-deck-panels { display: grid; margin-top: 1.75rem; }
.rs-deck-panel { grid-area: 1 / 1; visibility: hidden; }
.rs-deck-panel.is-on { visibility: visible; }

.rs-deck-title {
  font-family: 'Bricolage Grotesque', system-ui, sans-serif;
  font-weight: 700; font-size: clamp(22px, 2.1vw, 28px); line-height: 1.12;
  letter-spacing: -0.035em; color: var(--rs-ink); text-wrap: balance;
}
.rs-deck-body { margin-top: 0.85rem; font-size: 15px; line-height: 1.6; color: var(--rs-ink-2); max-width: 34rem; }
.rs-deck-link {
  margin-top: 1.1rem; display: inline-flex; align-items: center; gap: 6px;
  font-size: 13.5px; font-weight: 700; color: var(--rs-violet); text-decoration: none;
}
.rs-deck-link svg { transition: transform .3s var(--rs-ease); }
.rs-deck-link:hover svg { transform: translateX(3px); }

/* the copy exchange: the outgoing panel is replaced, not cross-faded, so the
   two never overlap mid-swap and the text is never briefly doubled */
.rs-deck-panel.is-on { animation: rsDeckIn .45s var(--rs-ease) both; }
@keyframes rsDeckIn {
  from { opacity: 0; transform: translateY(9px); }
  to   { opacity: 1; transform: none; }
}

/* ---- controls ----------------------------------------------------------- */
.rs-deck-nav { display: flex; align-items: center; gap: 10px; margin-top: 2rem; }
.rs-deck-arrow {
  width: 42px; height: 42px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px; border: 1.5px solid var(--rs-ink);
  background: var(--rs-surface); color: var(--rs-ink); cursor: pointer;
  transition: background-color .25s var(--rs-ease), color .25s var(--rs-ease),
              transform .25s var(--rs-ease), opacity .25s var(--rs-ease);
}
.rs-deck-arrow:hover:not(:disabled) { background: var(--rs-mint); transform: translateY(-2px); }
.rs-deck-arrow:active:not(:disabled) { transform: translateY(0); }
.rs-deck-arrow:disabled { opacity: .3; cursor: default; }
.rs-deck-arrow:focus-visible { outline: 2px solid var(--rs-violet); outline-offset: 3px; }
.rs-deck-count {
  margin: 0 0 0 6px; font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 12px; color: var(--rs-ink-2); font-variant-numeric: tabular-nums;
}

/* ---- the deck ----------------------------------------------------------- */
.rs-deck-stage {
  /* tuned to the card stack, not a round number: the front card is 81% of the
     stage width at 16/10 plus a 30px chrome bar, and the deck steps upward, so
     anything taller leaves dead space under the cards */
  position: relative; aspect-ratio: 16 / 9.4;
  perspective: 1500px; perspective-origin: 65% 50%;
  touch-action: pan-y;            /* horizontal drags are ours, vertical scroll is the page's */
  cursor: grab;
}
.rs-deck-stage:active { cursor: grabbing; }
.rs-deck-stage:focus-visible { outline: 2px solid var(--rs-violet); outline-offset: 8px; border-radius: 20px; }

.rs-deck-card {
  position: absolute; inset: 0 auto auto 0; width: 81%;
  border-radius: 16px; overflow: hidden;
  background: var(--rs-surface); border: 1px solid var(--rs-line-2);
  box-shadow: 0 18px 45px -18px rgba(13, 27, 42, .38);
  transform-origin: 50% 100%;
  will-change: transform, opacity;
  /* .62s here is mirrored by SWAP in rbns_studio.js — the re-seat that makes
     the loop invisible is scheduled off it */
  transition: transform .62s var(--rs-ease), opacity .42s var(--rs-ease),
              box-shadow .62s var(--rs-ease);
}
/* transform is composed from custom properties so the drag can nudge the front
   card live without fighting the resting transform the controller wrote */
.rs-deck-card {
  transform:
    translate3d(calc(var(--dx, 0%) + var(--drag, 0px)), var(--dy, 0%), var(--dz, 0px))
    rotateY(calc(var(--ry, -14deg) + var(--dragrot, 0deg)))
    scale(var(--sc, 1));
}
.rs-deck-card.is-front { box-shadow: 0 30px 70px -22px rgba(13, 27, 42, .5); }
.rs-deck-card.is-gone { pointer-events: none; }
.rs-deck-card.is-dragging { transition: none; }

.rs-deck-chrome {
  display: flex; align-items: center; gap: 6px; height: 30px; padding: 0 13px;
  border-bottom: 1px solid var(--rs-line); background: var(--rs-paper);
}
.rs-deck-chrome i { width: 8px; height: 8px; border-radius: 999px; background: var(--rs-line-2); }
.rs-deck-chrome i:first-child { background: var(--rs-violet); opacity: .55; }
.rs-deck-chrome span {
  margin-left: 6px; font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 9.5px; color: var(--rs-ink-2);
}
.rs-deck-card .shot { aspect-ratio: 16 / 10; }
/* belt and braces with the dragstart handler: the native image drag otherwise
   cancels the pointer gesture a few pixels in */
.rs-deck-card img { -webkit-user-drag: none; user-select: none; pointer-events: none; }
.rs-deck-stage { user-select: none; }

@media (max-width: 1023px) {
  .rs-deck-stage { aspect-ratio: 16 / 10.2; perspective-origin: 50% 50%; }
  .rs-deck-card { width: 78%; }
}

@media (prefers-reduced-motion: reduce) {
  .rs-deck-card { transition: opacity .2s linear; }
  .rs-deck-panel { animation: none; }
  .rs-deck-arrow { transition: none; }
}

/* ===========================================================================
   BENTO — "Design, build, data, AI…"
   Two rows, five cells: a wide image pair, then three working cells sharing
   the second row. Design and Data run at full bleed with no caption; the
   section heading already names them and a labelled screenshot was the page
   captioning its own picture.

   The AI marks are hand-authored SVG approximations of the four models, not
   official brand assets.
   =========================================================================== */

.rs-bento { display: grid; gap: 10px; grid-template-columns: 1fr; }
@media (min-width: 640px) {
  .rs-bento { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  /* 3-3 over 2-2-2 on a six-track grid, with the row heights pinned so the
     block stays compact regardless of how the copy sets */
    /* row 2 is taller than the art row: these cells carry a label pair as well as
     a visual, and the labels were being squeezed to fit rather than sized to
     read */
  .rs-bento { grid-template-columns: repeat(6, minmax(0, 1fr)); grid-template-rows: 196px 200px; gap: 12px; }
  .rs-bento-cell--d  { grid-column: span 3; }
  .rs-bento-cell--b  { grid-column: span 3; }
  .rs-bento-cell--dt { grid-column: span 2; }
  .rs-bento-cell--ai { grid-column: span 2; }
  .rs-bento-cell--r  { grid-column: span 2; }
}

.rs-bento-cell {
  display: flex; flex-direction: column; min-width: 0; overflow: hidden;
  padding: 12px; border-radius: 16px;
  background: #fff; border: 1px solid var(--rs-line);
  transition: transform .4s var(--rs-ease), box-shadow .4s var(--rs-ease),
              border-color .4s var(--rs-ease);
}
.rs-bento-cell:hover { transform: translateY(-3px); box-shadow: var(--rs-shadow-sm); border-color: var(--rs-line-2); }

/* ---- full-bleed image cells --------------------------------------------- */
.rs-bento-cell--shot { padding: 0; margin: 0; }
.rs-bento-cell--shot img {
  display: block; width: 100%; object-fit: cover;
  transform-origin: center;
}
@media (max-width: 1023px) { .rs-bento-cell--shot { height: 168px; } }
/* full cover, anchored high: the lockup sits in the top ~72% of the art and
   the rest is empty ground, so cropping from the bottom loses nothing */
.rs-bento-cell--d img { object-position: center 22%; animation: rsDriftA 20s ease-in-out infinite alternate; }

/* a slow crawl, not a zoom — it should read as alive on a second look, never
   as movement competing with the copy beside it */
/* barely a move: the row already fits the art exactly, so anything more than a
   few percent starts eating the lettering */
@keyframes rsDriftA {
  from { transform: scale(1) translate3d(0, 0, 0); }
  to   { transform: scale(1.035) translate3d(-0.8%, 0, 0); }
}

/* ---- the working cells --------------------------------------------------- */
.rs-bento-viz {
  position: relative; overflow: hidden; flex: 1 1 auto; min-height: 0;
  border-radius: 11px; padding: 12px 14px;
  background: #fff;
  display: flex; align-items: center; justify-content: center; gap: 10px;
}
/* The label pair is the only text in the block, so it carries the section's
   voice. It was set at 14.5/12 — smaller than the page's own small print. */
.rs-bento-foot { flex: none; padding: 15px 4px 2px; }
.rs-bento-name {
  font-family: 'Bricolage Grotesque', system-ui, sans-serif; font-weight: 700;
  font-size: 20px; line-height: 1.1; letter-spacing: -.035em; color: var(--rs-ink);
}
.rs-bento-desc {
  margin-top: 5px; font-size: 14px; line-height: 1.45; color: var(--rs-ink-2);
  text-wrap: pretty;
}
@media (max-width: 639px) {
  .rs-bento-foot { padding: 13px 2px 2px; }
  .rs-bento-name { font-size: 18px; }
  .rs-bento-desc { font-size: 13.5px; }
}

/* ---- Build: modules landing one after another --------------------------- */
.rs-build { padding: 12px; }
.rs-build-frame {
  flex: 1 1 auto; min-width: 0; height: 100%;
  display: flex; flex-direction: column; border-radius: 9px; overflow: hidden;
  background: var(--rs-paper); border: 1px solid var(--rs-line);
}
.rs-build-bar { flex: none; display: flex; align-items: center; gap: 5px; height: 20px; padding: 0 9px; border-bottom: 1px solid var(--rs-line); }
.rs-build-bar i { width: 6px; height: 6px; border-radius: 999px; background: var(--rs-line-2); }
.rs-build-bar i:first-child { background: rgba(102, 0, 255, .45); }
.rs-build-body { flex: 1; display: flex; flex-direction: column; justify-content: center; gap: 8px; padding: 10px 14px; }
.rs-build-mod {
  display: block; height: 9px; width: 62%; border-radius: 3px;
  background: rgba(102, 0, 255, .3);
  animation: rsBuildIn 3.4s var(--rs-ease) infinite;
}
.rs-build-mod:nth-child(2) { width: 88%; }
.rs-build-mod:nth-child(3) { width: 48%; }
.rs-build-mod--cta { width: 42% !important; height: 17px !important; background: var(--rs-mint) !important; }
@keyframes rsBuildIn {
  0%        { opacity: 0; transform: translateX(-16px); }
  15%, 80%  { opacity: 1; transform: none; }
  93%, 100% { opacity: 0; transform: translateX(7px); }
}

/* ---- Data: bars rising under a trend line ------------------------------- */
.rs-chart { position: relative; padding: 14px 14px 12px; align-items: flex-end; }
.rs-chart-grid { position: absolute; inset: 14px 14px 22px; display: flex; flex-direction: column; justify-content: space-between; }
.rs-chart-grid i { display: block; height: 1px; background: rgba(13, 27, 42, .07); }
.rs-chart-bars {
  position: relative; z-index: 1; flex: 1 1 auto;
  display: flex; align-items: flex-end; justify-content: space-between; gap: 6px; height: 100%;
}
/* scaleY off a bottom origin — animating height would relayout seven bars on
   every frame */
.rs-chart-bars i {
  flex: 1; height: var(--h); border-radius: 3px 3px 1px 1px;
  background: linear-gradient(180deg, var(--rs-violet), rgba(102, 0, 255, .45));
  transform-origin: bottom; transform: scaleY(0);
  animation: rsChartGrow 4.4s var(--rs-ease) infinite;
}
.rs-chart-bars i:nth-child(6) { background: linear-gradient(180deg, var(--rs-mint-2, #81FF94), rgba(14, 122, 63, .55)); }
@keyframes rsChartGrow {
  0%        { transform: scaleY(0); }
  18%, 78%  { transform: scaleY(1); }
  92%, 100% { transform: scaleY(0); }
}
.rs-chart-line { position: absolute; inset: 14px 14px 22px; width: auto; height: auto; z-index: 2; overflow: visible; }
.rs-chart-line path {
  stroke-dasharray: 240; stroke-dashoffset: 240;
  filter: drop-shadow(0 1px 2px rgba(102, 0, 255, .25));
  animation: rsChartDraw 4.4s var(--rs-ease) infinite;
}
@keyframes rsChartDraw {
  0%        { stroke-dashoffset: 240; }
  30%, 78%  { stroke-dashoffset: 0; }
  92%, 100% { stroke-dashoffset: 240; }
}

/* ---- AI: the models taking turns at the front --------------------------- */
.rs-models { gap: 0; }
.rs-model {
  width: 56px; height: 56px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px; background: #fff; border: 0;
  box-shadow: 0 2px 10px rgba(13, 27, 42, .1);
  margin-left: -15px;
  animation: rsModelTurn 5.2s var(--rs-ease) infinite;
}
.rs-model:first-child { margin-left: 0; }
.rs-model img { width: 28px; height: 28px; display: block; }
/* each chip rises and comes forward in turn; z-index steps rather than tweens,
   which is what keeps the overlap order honest mid-cycle */
@keyframes rsModelTurn {
  0%,  100% { transform: translateY(0) scale(1);     z-index: 1; }
  8%        { transform: translateY(-9px) scale(1.1); z-index: 5; }
  22%       { transform: translateY(-9px) scale(1.1); z-index: 5; }
  32%       { transform: translateY(0) scale(1);      z-index: 1; }
}

/* ---- Run: the cell that carries colour ---------------------------------- */
/* One card in the grid gets the signature mint, and it is this one: "someone is
   watching it" is the claim the section closes on. The inner panel drops its
   own surface so the gradient reads as a single field rather than a box in a
   box. */
.rs-bento-cell--r {
  background: linear-gradient(135deg, #fff 0%, #fff 28%, var(--rs-mint-s) 62%, var(--rs-mint) 100%);
  border-color: rgba(13, 27, 42, .1);
}
.rs-bento-cell--r .rs-bento-viz { background: transparent; border: 0; padding: 6px 4px; }
.rs-bento-cell--r:hover { box-shadow: var(--rs-shadow); border-color: rgba(13, 27, 42, .16); }

.rs-run { flex-direction: column; gap: 4px; justify-content: center; }
.rs-run-ecg { width: 100%; height: 74px; overflow: visible; }
/* a short lit segment running the same path as the ghost trace */
.rs-run-trace {
  stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 58 520; stroke-dashoffset: 58;
  filter: drop-shadow(0 2px 5px rgba(102, 0, 255, .35));
  animation: rsRunTrace 2.6s linear infinite;
}
@keyframes rsRunTrace { to { stroke-dashoffset: -520; } }
.rs-run-chip {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 10.5px;
  color: var(--rs-ink); opacity: .72;
}
.rs-run-chip i {
  width: 7px; height: 7px; border-radius: 999px; background: var(--rs-violet);
  animation: rsRunPulse 2.6s ease-in-out infinite;
}
@keyframes rsRunPulse { 0%, 100% { opacity: .25; transform: scale(.85); } 50% { opacity: 1; transform: scale(1); } }

/* ---- the person ---------------------------------------------------------- */
.rs-nav-face {
  width: 34px; height: 34px; flex: none; border-radius: 999px; object-fit: cover;
  border: 1.5px solid var(--rs-line-2); background: var(--rs-surface);
  transition: border-color .3s var(--rs-ease), transform .3s var(--rs-ease);
}
.rs-nav-face:hover { border-color: var(--rs-violet); transform: translateY(-1px); }
/* the burger takes over below this, and the bar has no room for both */
@media (max-width: 900px) { .rs-nav-face { display: none; } }

.rs-intro { margin-top: 1.5rem; display: flex; align-items: flex-start; gap: 16px; }
.rs-intro-face {
  width: 76px; height: 76px; flex: none; border-radius: 999px; object-fit: cover;
  border: 2px solid #fff; box-shadow: 0 6px 18px -6px rgba(13, 27, 42, .35);
}
.rs-intro-copy { margin: 0; font-size: 16.5px; line-height: 1.6; color: var(--rs-ink-2); max-width: 32rem; }
@media (max-width: 520px) {
  .rs-intro { gap: 13px; }
  .rs-intro-face { width: 58px; height: 58px; }
  .rs-intro-copy { font-size: 15.5px; }
}
@keyframes rsRunPulse { 0%, 100% { opacity: .3; } 50% { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .rs-bento-cell { transition: none; }
  .rs-bento-cell:hover { transform: none; }
  .rs-bento-cell--shot img,
  .rs-build-mod, .rs-model, .rs-run-trace, .rs-run-chip i,
  .rs-chart-bars i, .rs-chart-line path { animation: none; }
  .rs-chart-bars i { transform: scaleY(1); }
  .rs-chart-line path { stroke-dashoffset: 0; }
  .rs-nav-face { transition: none; }
  .rs-bento-cell--d img { transform: none; }
}

/* ===========================================================================
   WORK — the project deck
   Copy on the left, a 3D deck of the real screenshots on the right, paged with
   the arrows, a drag, or the arrow keys. Replaced two full-width alternating
   articles plus a five-card carousel.

   The deck is finite, not looping: it dead-ends at both edges and the arrows
   disable there. Wrapping around would have to fly the front card back through
   the stack to reach the last slot, which reads as a glitch at this depth.
   =========================================================================== */

.rs-deck { display: grid; gap: 2.5rem; padding: 3.5rem 0 4rem; align-items: center; }
@media (min-width: 1024px) {
  .rs-deck { grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr); gap: 4rem; padding: 4.5rem 0 4.5rem; }
}
/* both children must opt out of the implicit min-width:auto, or the deck's
   absolutely-positioned cards inflate the track and push the page sideways */
.rs-deck-copy, .rs-deck-stage { min-width: 0; }

/* ---- left column -------------------------------------------------------- */
/* The panels are stacked in the same grid cell so the column does not resize
   as projects change; the tallest sets the height once and it stays put. */
/* All panels share one grid cell, so the cell keeps the height of the TALLEST
   and the arrows below it never move as projects change. Inactive panels are
   hidden with visibility rather than display — display:none would collapse the
   cell back to the active panel's height and reintroduce the jump. visibility
   also takes them out of the tab order, which display:none did for free. */
.rs-deck-panels { display: grid; margin-top: 1.75rem; }
.rs-deck-panel { grid-area: 1 / 1; visibility: hidden; }
.rs-deck-panel.is-on { visibility: visible; }

.rs-deck-title {
  font-family: 'Bricolage Grotesque', system-ui, sans-serif;
  font-weight: 700; font-size: clamp(22px, 2.1vw, 28px); line-height: 1.12;
  letter-spacing: -0.035em; color: var(--rs-ink); text-wrap: balance;
}
.rs-deck-body { margin-top: 0.85rem; font-size: 15px; line-height: 1.6; color: var(--rs-ink-2); max-width: 34rem; }
.rs-deck-link {
  margin-top: 1.1rem; display: inline-flex; align-items: center; gap: 6px;
  font-size: 13.5px; font-weight: 700; color: var(--rs-violet); text-decoration: none;
}
.rs-deck-link svg { transition: transform .3s var(--rs-ease); }
.rs-deck-link:hover svg { transform: translateX(3px); }

/* the copy exchange: the outgoing panel is replaced, not cross-faded, so the
   two never overlap mid-swap and the text is never briefly doubled */
.rs-deck-panel.is-on { animation: rsDeckIn .45s var(--rs-ease) both; }
@keyframes rsDeckIn {
  from { opacity: 0; transform: translateY(9px); }
  to   { opacity: 1; transform: none; }
}

/* ---- controls ----------------------------------------------------------- */
.rs-deck-nav { display: flex; align-items: center; gap: 10px; margin-top: 2rem; }
.rs-deck-arrow {
  width: 42px; height: 42px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px; border: 1.5px solid var(--rs-ink);
  background: var(--rs-surface); color: var(--rs-ink); cursor: pointer;
  transition: background-color .25s var(--rs-ease), color .25s var(--rs-ease),
              transform .25s var(--rs-ease), opacity .25s var(--rs-ease);
}
.rs-deck-arrow:hover:not(:disabled) { background: var(--rs-mint); transform: translateY(-2px); }
.rs-deck-arrow:active:not(:disabled) { transform: translateY(0); }
.rs-deck-arrow:disabled { opacity: .3; cursor: default; }
.rs-deck-arrow:focus-visible { outline: 2px solid var(--rs-violet); outline-offset: 3px; }
.rs-deck-count {
  margin: 0 0 0 6px; font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 12px; color: var(--rs-ink-2); font-variant-numeric: tabular-nums;
}

/* ---- the deck ----------------------------------------------------------- */
.rs-deck-stage {
  /* tuned to the card stack, not a round number: the front card is 81% of the
     stage width at 16/10 plus a 30px chrome bar, and the deck steps upward, so
     anything taller leaves dead space under the cards */
  position: relative; aspect-ratio: 16 / 9.4;
  perspective: 1500px; perspective-origin: 65% 50%;
  touch-action: pan-y;            /* horizontal drags are ours, vertical scroll is the page's */
  cursor: grab;
}
.rs-deck-stage:active { cursor: grabbing; }
.rs-deck-stage:focus-visible { outline: 2px solid var(--rs-violet); outline-offset: 8px; border-radius: 20px; }

.rs-deck-card {
  position: absolute; inset: 0 auto auto 0; width: 81%;
  border-radius: 16px; overflow: hidden;
  background: var(--rs-surface); border: 1px solid var(--rs-line-2);
  box-shadow: 0 18px 45px -18px rgba(13, 27, 42, .38);
  transform-origin: 50% 100%;
  will-change: transform, opacity;
  /* .62s here is mirrored by SWAP in rbns_studio.js — the re-seat that makes
     the loop invisible is scheduled off it */
  transition: transform .62s var(--rs-ease), opacity .42s var(--rs-ease),
              box-shadow .62s var(--rs-ease);
}
/* transform is composed from custom properties so the drag can nudge the front
   card live without fighting the resting transform the controller wrote */
.rs-deck-card {
  transform:
    translate3d(calc(var(--dx, 0%) + var(--drag, 0px)), var(--dy, 0%), var(--dz, 0px))
    rotateY(calc(var(--ry, -14deg) + var(--dragrot, 0deg)))
    scale(var(--sc, 1));
}
.rs-deck-card.is-front { box-shadow: 0 30px 70px -22px rgba(13, 27, 42, .5); }
.rs-deck-card.is-gone { pointer-events: none; }
.rs-deck-card.is-dragging { transition: none; }

.rs-deck-chrome {
  display: flex; align-items: center; gap: 6px; height: 30px; padding: 0 13px;
  border-bottom: 1px solid var(--rs-line); background: var(--rs-paper);
}
.rs-deck-chrome i { width: 8px; height: 8px; border-radius: 999px; background: var(--rs-line-2); }
.rs-deck-chrome i:first-child { background: var(--rs-violet); opacity: .55; }
.rs-deck-chrome span {
  margin-left: 6px; font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 9.5px; color: var(--rs-ink-2);
}
.rs-deck-card .shot { aspect-ratio: 16 / 10; }
/* belt and braces with the dragstart handler: the native image drag otherwise
   cancels the pointer gesture a few pixels in */
.rs-deck-card img { -webkit-user-drag: none; user-select: none; pointer-events: none; }
.rs-deck-stage { user-select: none; }

@media (max-width: 1023px) {
  .rs-deck-stage { aspect-ratio: 16 / 10.2; perspective-origin: 50% 50%; }
  .rs-deck-card { width: 78%; }
}

@media (prefers-reduced-motion: reduce) {
  .rs-deck-card { transition: opacity .2s linear; }
  .rs-deck-panel { animation: none; }
  .rs-deck-arrow { transition: none; }
}

/* ===========================================================================
   ████  PHONE PASS  ████
   Appended last on purpose: several components above are declared twice in
   this file (the mockup export plus later rewrites), so source order is the
   only reliable way to win without an !important arms race.

   The thesis for every rule here: a phone gets ONE thing per screen. Anything
   that was a two-column relationship on desktop becomes either a rail you
   swipe or a thing that isn't shown at all — not a stack of everything.
   =========================================================================== */
@media (max-width: 767px) {

  /* ---- rhythm ------------------------------------------------------------ */
  /* Sections were carrying desktop padding (80–96px top and bottom), so the
     page read as a series of far-apart islands and ran to 9,700px. */
  section, .rs-book { padding-top: 56px !important; padding-bottom: 56px !important; }
  #top > section:first-of-type { padding-top: 0 !important; }
  section h2 { font-size: 30px !important; }

  /* ---- hero -------------------------------------------------------------- */
  /* The four tabs sat hard against the "Book a free call" button, so the CTA
     and a row of secondary chips read as one control cluster — and at this
     width the row had to scroll to reach the fourth anyway. The arrows page the
     same four projects in a fraction of the space, and the caption under each
     shot already names the project the tab label was naming. */
  /* Centred on a phone: the copy column is the full width here, so the ragged
     left-aligned block a two-column desktop layout wants reads as off-centre
     with nothing beside it. The arrows centre with it — they belong to the
     showcase below them, not to the edge of the screen. */
  .rs-hero-copy { text-align: center; }
  .rs-hero-lede { margin-left: auto; margin-right: auto; }
  .rs-hero-actions { justify-content: center; }
  .rs-hero-stage { margin-top: 36px; }
  .rs-show-tabs { display: none; }
  .rs-show-bar { margin-bottom: 12px; justify-content: center; }
  .rs-show-nav { display: flex; }
  .rs-hero-pad { padding-bottom: 28px !important; }

  /* ---- bento ------------------------------------------------------------- */
  /* Five stacked cells were five screens of scroll for what is one glance on
     desktop, so the grid becomes a rail like every other group on this page.
     Cards are top-aligned rather than stretched: only one is on screen at a
     time, so equal heights buy nothing and would re-crop the art. */
  .rs-bento {
    display: flex !important; flex-direction: row; align-items: flex-start; gap: 12px;
    overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory; scroll-padding: 0 1.25rem;
    padding-bottom: 4px;
    scrollbar-width: none; -ms-overflow-style: none;
  }
  .rs-bento::-webkit-scrollbar { display: none; }
  .rs-bento-cell { flex: 0 0 86%; scroll-snap-align: center; }
  /* The viz is `flex: 1 1 auto; min-height: 0` against a cell that has a fixed
     height on desktop and none here, so the Data cell's chart — whose bars are
     percentages of it — collapsed to nothing and left a labelled empty box. */
  .rs-bento-viz { min-height: 120px; }
  /* the art cell is sized BY its image here (desktop crops it to a 168px band
     to hold the grid row) — on a card of its own there's no row to keep */
  .rs-bento-cell--shot { height: auto; }
  .rs-bento-cell--shot img { height: auto; object-fit: contain; }

  /* ---- the walkthrough --------------------------------------------------- */
  .rs-flow-grid { gap: 0; margin-top: 28px !important; }
  .rs-flow-stage { height: 200px; box-shadow: var(--rs-shadow-sm), 6px 6px 0 0 var(--rs-mint); }

  /* ---- the project deck -------------------------------------------------- */
  /* Seven projects × (title + paragraph + link) is seven screens of copy for a
     visual section. On a phone the deck IS the content: the screenshots stay,
     the per-project prose goes, and the arrows go with it — the deck is
     already draggable and the counter says where you are. */
  .rs-deck { gap: 1.25rem; padding: 0; }
  .rs-deck-panels { display: none; }
  .rs-deck-arrow { display: none; }
  .rs-deck-nav { margin-top: .75rem; justify-content: flex-start; }
  .rs-deck-count { margin-left: 0; }
  .rs-deck-copy > p { font-size: 15.5px; }

  /* ---- pricing ----------------------------------------------------------- */
  /* Three stacked cards were 1,400px of scroll to compare three options — the
     one thing this section exists to let you do. Now one card per screen with
     the next peeking, so the comparison is a thumb-flick. */
  .rs-pricing {
    display: flex !important; flex-direction: row; align-items: stretch; gap: 12px;
    overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory; scroll-padding: 0 1.25rem;
    /* the featured card's badge sits above its top edge and its keyline outside
       its box — the rail needs headroom or it clips both */
    padding: 14px 0 6px;
    scrollbar-width: none; -ms-overflow-style: none;
  }
  .rs-pricing::-webkit-scrollbar { display: none; }
  .rs-pc { flex: 0 0 86%; scroll-snap-align: center; margin-top: 0 !important; }
  .rs-pc-note { margin-top: 18px; }

  /* ---- booking ----------------------------------------------------------- */
  /* The desktop height cap makes the widget scroll inside its own box. On touch
     that's a scroll trap in the middle of the page, and the widget is already
     one column here — so let it be as tall as it wants. */
  .rs-book-embed { max-height: none; }
  .rs-book-embed > div { max-height: none; overflow-y: visible; }
  .rs-book-embed, .rs-book-embed > div { min-height: 440px; }
}

/* The nav pill's link row is hidden below 980px, which left the wordmark and
   the burger with a wide empty gap between them. */
@media (max-width: 979px) {
  .rs-nav-inner { height: 54px; padding-left: 16px; padding-right: 8px; }
}

/* The capabilities stage is a diagram drawn for a wide box — squeezed onto a
   phone it's decoration competing with the cards that carry the actual claims.
   The cards are the section there; the scenes wait for a wider screen. (Here
   rather than in the capabilities block because `.rs-caps-stage`'s own
   `display: grid` is declared after it and would otherwise win.) */
@media (max-width: 899px) {
  .rs-caps-stage { display: none; }
}
