/* ---------------------------------------------------------------------------
 * Your stylesheet. Loaded last on every page, so these rules win.
 *
 * This is the right place to change layout and styling. The mirrored pages are
 * minified build output — editing them directly is impractical and, if you
 * reformat them, breaks the site. Restyle from here instead.
 *
 * Edit, save, refresh. No restart needed.
 *
 * Finding a selector: right-click the element in the browser, Inspect, and read
 * the class list. Class names are content-hashed (e.g. `_hero_1abcd_12`), so
 * they change if you ever re-run the mirror. Prefer stable hooks where you can:
 * element types, ARIA attributes, data attributes, or structural selectors.
 * ------------------------------------------------------------------------- */

/* Design tokens the site already uses. Overriding these is the broadest lever
   you have — one change here restyles every component that references them.
   Inspect :root in devtools to see the full list. */
:root {
  /* --color-brand: #006bff; */
  /* --radius-md: 8px; */
}

/* Example: widen the page container.
.container,
[class*="container"] {
  max-width: 1400px;
}
*/

/* Example: hide a section you do not want.
section[aria-label="Testimonials"] {
  display: none;
}
*/

/* Example: restyle every primary button by shape rather than hashed class.
a[href*="/signup"] {
  border-radius: 999px;
}
*/

/* Add a `?debug` outline to any page to see element boundaries while working.
   Toggle it from overrides/custom.js. */
html[data-debug-layout] * {
  outline: 1px solid rgba(255, 0, 90, 0.35);
}

/* Text stand-in for the "Cypher LM" wordmark SVG, swapped in by custom.js.
   custom.js sets font-size/line-height/color per instance to match the
   original vector wordmark's rendered box; this just fixes the box model. */
[data-cypher-wordmark] {
  display: inline-block;
  font-weight: 700;
  white-space: nowrap;
}

/* The raw wordmark SVG (Cypher LM's own letterform paths — see custom.js
   fixLogos()) is unavoidably in the server-rendered HTML, since it isn't
   text and server/lib/html.js can't touch it. This stylesheet is
   render-blocking (a plain <link>, loaded before first paint), so hiding it
   here means the browser never paints the original wordmark at all — it
   stays invisible until custom.js replaces the element outright with the
   `[data-cypher-wordmark]` text span above, which has no opacity rule and
   is visible immediately. Scoped to the icon+wordmark pair fixLogos()
   itself targets (a 32x32 `<svg>` followed by a wide one inside a
   `[role="img"]` container) so it doesn't hide unrelated icons. */
[role="img"] > svg:nth-of-type(2) {
  opacity: 0;
}

/* Slow zoom in/out loop for the static image standing in for the Scheduling
   tab's Rive animation, so it reads as alive rather than a flat screenshot. */
@keyframes cypher-kenburns {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.08); }
}
[data-cypher-hero-visual] {
  animation: cypher-kenburns 10s ease-in-out infinite;
  will-change: transform;
}

/* Nav "Go to Dashboard" (custom.js fixNavCtas() only ever sets this attr
   for that link) — a pill container everywhere: transparent with a thin
   navy border by default, and solid navy (matching "Build Your Agent")
   only on the homepage, where fixNavCtas() adds the -solid attribute.
   !important overrides the site's own utility classes on the element. */
[data-cypher-navlink] {
  border: 1px solid rgb(7, 26, 49) !important;
  outline: none !important;
  box-shadow: none !important;
  background: transparent !important;
  background-image: none !important;
  padding: 12px 16px !important;
  border-radius: 16px !important;
  color: rgb(7, 26, 49) !important;
  -webkit-text-fill-color: rgb(7, 26, 49) !important;
  display: inline-flex !important;
  align-items: center !important;
}
[data-cypher-navlink-solid] {
  border: 2px solid transparent !important;
  background: rgb(7, 26, 49) !important;
  color: rgb(252, 251, 248) !important;
  -webkit-text-fill-color: rgb(252, 251, 248) !important;
}
[data-cypher-navlink-bordered] {
  outline: none !important;
  box-shadow: none !important;
  background: transparent !important;
  background-image: none !important;
  color: rgb(7, 26, 49) !important;
  -webkit-text-fill-color: rgb(7, 26, 49) !important;
  border: 1px solid rgb(7, 26, 49) !important;
  border-radius: 16px !important;
  /* Match the native nav link's own padding (12px 16px) so this button is
     the same height as its neighbors ("Build Your Agent") instead of
     sitting shorter/misaligned in the flex row. */
  padding: 12px 16px !important;
  display: inline-flex !important;
  align-items: center !important;
}
[data-cypher-navlink]:hover,
[data-cypher-navlink]:focus,
[data-cypher-navlink]:active {
  outline: none !important;
  box-shadow: none !important;
  background: rgba(7, 26, 49, 0.06) !important;
  color: rgb(7, 26, 49) !important;
  -webkit-text-fill-color: rgb(7, 26, 49) !important;
}
[data-cypher-navlink-solid]:hover,
[data-cypher-navlink-solid]:focus,
[data-cypher-navlink-solid]:active {
  background: rgb(7, 26, 49) !important;
  color: rgb(252, 251, 248) !important;
  -webkit-text-fill-color: rgb(252, 251, 248) !important;
  opacity: 0.9;
}

/* Homepage hero heading — the shared max-w-subhead utility (640px) forces
   "Voice AI that speaks / your language." into 3 lines at desktop widths.
   max-width alone isn't enough: the heading's flex-column ancestor
   (hero-section's direct child) shrink-wraps to 640px regardless, so the
   fix has to set a hard width on both that wrapper and the heading itself
   — widening just this heading (not the shared class site-wide) so it
   wraps to 2 lines at full font-size instead of shrinking the type. */
[data-testid="hero-section"] > div {
  width: 820px !important;
}
[data-testid="hero-section"] h1.max-w-subhead {
  max-width: 820px !important;
  width: 820px !important;
}

/* Contact / "Talk to sales" forms — built by fixContactForms() in
   custom.js to replace the permanently-stuck Marketo loading skeleton.
   Sits inside that skeleton's own card (border/shadow/padding already
   applied by its existing classes), so this only styles the fields. */
[data-cypher-contact-form] {
  font-family: var(--font-sans, 'Geist', sans-serif);
}
[data-cypher-contact-form] .cy-contact-fields {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 20px;
}
[data-cypher-contact-form] .cy-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
[data-cypher-contact-form] .cy-field-row {
  display: flex;
  gap: 16px;
}
[data-cypher-contact-form] .cy-field-row .cy-field {
  flex: 1;
  min-width: 0;
}
[data-cypher-contact-form] .cy-label {
  font-size: 13px;
  font-weight: 600;
  color: rgb(7, 26, 49);
}
[data-cypher-contact-form] input,
[data-cypher-contact-form] textarea,
[data-cypher-contact-form] select {
  font-family: inherit;
  font-size: 14px;
  color: rgb(7, 26, 49);
  background: #fff;
  border: 1.5px solid rgba(7, 26, 49, 0.15);
  border-radius: 10px;
  padding: 11px 14px;
  outline: none;
  transition: border-color 0.15s;
  resize: vertical;
}
[data-cypher-contact-form] input:focus,
[data-cypher-contact-form] textarea:focus,
[data-cypher-contact-form] select:focus {
  border-color: rgba(72, 144, 227, 0.6);
}
[data-cypher-contact-form] .cy-submit {
  margin-top: 4px;
  padding: 13px 20px;
  border-radius: 10px;
  border: none;
  background: rgb(7, 26, 49);
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  transition: opacity 0.15s;
}
[data-cypher-contact-form] .cy-submit:hover {
  opacity: 0.88;
}
[data-cypher-contact-form] .cy-submit:disabled {
  opacity: 0.6;
  cursor: default;
}
[data-cypher-contact-form] .cy-form-error {
  font-size: 13px;
  color: #c0392b;
  margin: -6px 0 0;
}
[data-cypher-contact-form] .cy-success-desc {
  font-size: 14px;
  color: rgba(7, 26, 49, 0.65);
  margin-top: 6px;
}

/* Card 1's split action row: Submit Ticket | Talk to Sales Agent. */
[data-cypher-contact-form] .cy-btn-row {
  display: flex;
  gap: 12px;
  margin-top: 4px;
}
[data-cypher-contact-form] .cy-btn-row .cy-submit {
  flex: 1;
  margin-top: 0;
}
[data-cypher-contact-form] .cy-sales-agent-btn {
  flex: 1;
  padding: 13px 20px;
  border-radius: 10px;
  border: 1.5px solid rgb(7, 26, 49);
  background: #fff;
  color: rgb(7, 26, 49);
  font-size: 14px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
[data-cypher-contact-form] .cy-sales-agent-btn:hover {
  background: rgb(7, 26, 49);
  color: #fff;
}

/* The sky gradient the agent takeover fades in over the section's own
   purple gradient — matched to the /demo "Hey, I'm Cypher" page (deep
   blue top, pale green-cream horizon at the bottom). It stays mounted as
   the agent view's background. */
.cy-agent-veil {
  position: absolute;
  inset: 0;
  z-index: 20;
  opacity: 0;
  transition: opacity 0.8s ease;
  pointer-events: none;
  border-radius: inherit;
  background: linear-gradient(180deg,
    #3d7dc4 0%, #5695d3 30%, #7db4de 55%,
    #a9cfdf 75%, #d3e5d2 92%, #e9eed3 100%);
}
.cy-agent-veil-in {
  opacity: 1;
}

/* Agent view: covers the whole block on top of the veil — title up top,
   blob center, talk pill at the bottom. */
.cy-agent-stage {
  position: absolute;
  inset: 0;
  z-index: 30;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  text-align: center;
  padding: 56px 24px 44px;
  font-family: var(--font-sans, 'Geist', sans-serif);
}
.cy-agent-stage-out {
  opacity: 0;
  transition: opacity 0.45s ease;
}
.cy-agent-back {
  position: absolute;
  top: 32px;
  left: 44px;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.55);
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.15s;
  animation: cy-agent-fade-up 0.6s ease 0.15s backwards;
}
.cy-agent-back:hover {
  background: rgba(255, 255, 255, 0.28);
}
.cy-agent-head {
  animation: cy-agent-fade-up 0.6s ease 0.1s backwards;
}
.cy-agent-title {
  font-family: var(--font-sans, 'Geist', sans-serif);
  font-size: 44px;
  font-weight: 600;
  color: #fff;
  margin: 8px 0 6px;
  letter-spacing: -0.6px;
}
.cy-agent-sub {
  font-size: 14px;
  color: rgba(255, 255, 255, 0.8);
  margin: 0;
}

/* The Cypher orb — a WebGL canvas running the app's own GradientOrb shader
   (see initCypherOrb in custom.js), so this is pixel-identical to the /demo
   and agent-page blobs. Wrapper matches DemoPage exactly: 56vmin square,
   0.8→1 scale-in over 0.5s ease-out, static (no float) while idle. */
.cy-agent-blob {
  position: relative;
  width: min(56vmin, 430px);
  height: min(56vmin, 430px);
  margin: 12px 0;
  animation: cy-agent-blob-reveal 0.5s ease-out 0.3s backwards;
}
.cy-agent-orb {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 50%;
}
.cy-agent-foot {
  animation: cy-agent-fade-up 0.6s ease 0.55s backwards;
}
.cy-agent-talk {
  padding: 13px 34px;
  border-radius: 999px;
  border: 1.5px solid rgba(255, 255, 255, 0.75);
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
  font-size: 15px;
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.2s;
}
.cy-agent-talk:hover {
  background: rgba(255, 255, 255, 0.28);
}
.cy-agent-powered {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.65);
  margin: 10px 0 0;
}

@keyframes cy-agent-fade-up {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes cy-agent-blob-reveal {
  from { opacity: 0; transform: scale(0.8); }
  to   { opacity: 1; transform: scale(1); }
}

/* Homepage hero product tabs (Voice Agent/Meet Cypher/Notetaker/Payments)
   — confirmed root cause by rendering this exact page in real headless
   Chrome (not guesswork): the icon's wrapper,
   `<span class="relative z-20 !size-[85.7%]">`, sits inside a
   `<button class="grid ... place-items-center">`, which is meant to
   center it. But a completely unrelated component elsewhere on the
   page dynamically injects a global `<style>` tag containing the rule
   `button[role="tab"] > span[class*="z-20"] { position: absolute
   !important; inset: 0 !important; width: auto !important; height:
   auto !important; }` — written for some other "z-20" element, but
   its selector happens to also match this icon wrapper (any span with
   "z-20" in its class list, directly under any `button[role="tab"]`).
   That forces `position:absolute`, which removes the span from grid-
   item flow entirely — `place-items:center` has no effect on
   absolutely positioned children — so it anchors flush to `top:0;
   left:0` instead of centering, with the leftover ~8px space (56px
   button − 47.98px wrapper) dumped entirely on the bottom-right. This
   HTML/CSS is byte-identical to the pre-rebrand source (verified by
   diff), so the stray rule itself isn't something introduced by this
   project — it's a pre-existing selector collision between two
   components that both use a generic "z-20" utility class name.
   Fix: restore the intended `position:relative` with higher
   specificity than the stray rule (which has 2 attribute-selectors;
   this one has 3, so it wins outright — no !important tie/source-order
   gamble needed for that property; !important is still used since the
   stray rule sets it too). Once relative, place-items-center on the
   button naturally centers it, exactly as authored. Scoped tightly to
   this tablist so nothing else on the page is touched. */
[role="tablist"][aria-label="Cypher LM products"] span[class*="!size-[85.7%]"] {
  position: relative !important;
}

/* Nudge the combined navbar logo up slightly so it sits optically level
   with the nav links (the image's own bottom padding makes it ride low).
   Header only — the footer logo's baseline is fine. */
header [aria-label="Cypher LM"] img,
nav [aria-label="Cypher LM"] img {
  transform: translateY(-2px);
}

/* Anti-flash: fixLogos() swaps the original two-SVG logo (old "C" mark +
   wordmark) for the combined logo <img> only after JS runs, so the OLD
   logo used to paint for a moment on every load. Hide the SVGs from
   first paint instead — a brief blank slot until the <img> lands, but
   never the old branding. Same idea for the Log In link, which
   fixNavCtas() removes after paint. */
/* visibility (not display): fixLogos() sizes the replacement <img> from
   these SVGs' live getBoundingClientRect(), which display:none would
   zero out — visibility keeps the layout box while painting nothing. */
[role="img"][aria-label*="Calendly"] > svg,
[role="img"][aria-label*="Cypher"] > svg {
  visibility: hidden !important;
}
a[href="/login"] {
  display: none !important;
}

/* /pricing grid: the 3 real plan cards (Basic/Premium/Enterprise — the
   astro-island's props were already fixed to these) were still sitting
   in a leftover `ui-dsk:grid-cols-4` class from the original 4-plan
   layout. That correction used to happen in custom.js's
   fixPricingGrid(), applied via JS after first paint — so the page
   visibly rendered the OLD 4-column layout for a frame, then snapped
   to the correct 3-column centered one once the script ran: exactly
   the "old page flashes before the new one" glitch reported. Moving
   the fix here means it's applied at CSS-parse time, before anything
   paints — there's no frame where the wrong layout is ever visible.
   Same breakpoint scoping as the original Tailwind utility
   (`@media (width>=1280px)`), so smaller viewports (which use
   different column classes entirely) are untouched. */
@media (width >= 1280px) {
  [data-testid="section-pricing-plans"] .grid.ui-dsk\:grid-cols-4 {
    grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
    width: fit-content !important;
    margin-inline: auto !important;
  }
}

/* Live call state on the /contact sales-agent pill (Connecting / End call). */
.cy-agent-talk.cy-agent-talk-live {
  background: rgba(255, 255, 255, 0.92) !important;
  color: #071a31 !important;
  border-color: rgba(255, 255, 255, 0.95) !important;
  box-shadow: 0 0 0 6px rgba(255, 255, 255, 0.18);
  animation: cy-agent-live-pulse 1.8s ease-in-out infinite;
}
@keyframes cy-agent-live-pulse {
  0%, 100% { box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.16); }
  50% { box-shadow: 0 0 0 10px rgba(255, 255, 255, 0.06); }
}
@media (prefers-reduced-motion: reduce) {
  .cy-agent-talk.cy-agent-talk-live { animation: none; }
}

/* Blog post video slots: videos aren't recorded yet, so every embed on a blog
   post shows a branded "Coming soon" panel instead of an empty/broken player.
   Swap in real Wistia URLs later and delete this block. */
[data-testid="template-blog-post"] [data-testid="wistia-embed"] {
  background:
    radial-gradient(60% 80% at 85% 110%, rgba(122, 213, 210, .75), rgba(122, 213, 210, 0) 70%),
    radial-gradient(50% 60% at 10% 0%, rgba(120, 170, 232, .55), rgba(120, 170, 232, 0) 70%),
    linear-gradient(160deg, #0c2d54 0%, #2a70b2 55%, #6aa9e2 100%);
}
[data-testid="template-blog-post"] [data-testid="wistia-embed"] > div:first-child,
[data-testid="template-blog-post"] [data-testid="wistia-embed"] wistia-player,
[data-testid="template-blog-post"] [data-testid="wistia-embed"] iframe {
  display: none !important;
}
[data-testid="template-blog-post"] [data-testid="wistia-embed"]::after {
  content: "Coming soon";
  position: absolute; inset: 0; z-index: 11;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 600; letter-spacing: -0.02em;
  font-size: clamp(22px, 3vw, 34px);
  text-shadow: 0 2px 18px rgba(4, 22, 52, .35);
}

/* Footer "Downloads" icon row (Edge/Safari/Chrome/Firefox/Outlook) - never paint it. */
footer div.flex.flex-col.gap-md:has(> ul > li > a > img),
footer div.flex.flex-col.gap-md:has(> ul > li > span > img) { display: none !important; }

/* "Beta" badge for Cypher S, N and P (and C in the Product menu), built from
   the exact utilities the site uses for Cypher M's badge (bg-badge-neutral-bg,
   text-badge-neutral-text, rounded-ui-xxs, font-geist font-medium), so it
   also flips to the light-on-dark variant on dark heroes like Cypher M's.
   Pure CSS: there from first paint and survives island hydration. */
a[href="/scheduling"] span.flex.min-w-0.items-center.gap-1\.5::after,
a[href="/notetaker"] span.flex.min-w-0.items-center.gap-1\.5::after,
a[href="/payments"] span.flex.min-w-0.items-center.gap-1\.5::after,
a[href="/contacts"] span.flex.min-w-0.items-center.gap-1\.5::after,
[role="img"]:is([aria-label="Cypher LM Scheduling"], [aria-label="Cypher LM Notetaker"], [aria-label="Cypher LM Payments"],
  [aria-label="Cypher LM Cypher S"], [aria-label="Cypher LM Cypher N"], [aria-label="Cypher LM Cypher P"])::after {
  content: "Beta";
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; width: fit-content;
  border-radius: calc(2 * var(--radius-ui-xxs));
  font-family: var(--font-geist); font-weight: 500; font-style: normal; text-transform: none;
  letter-spacing: var(--tracking-ui-none-fixed);
  background-color: var(--lightningcss-light, var(--color-midnight-a05)) var(--lightningcss-dark, var(--color-magnolia-a20));
  color: var(--lightningcss-light, var(--color-ramp-neutral-700)) var(--lightningcss-dark, var(--color-magnolia));
  /* Product menu: py-[2px] px-xs-fixed type-body-xs-fixed, 6px after the name (the row's gap). */
  padding: 2px var(--spacing-xs-fixed);
  font-size: var(--text-ui-body-xs-fixed); line-height: var(--leading-ui-body-xs);
}
/* Logo lockups: badge 12px from the lockup (gap-sm) like Cypher M's; the
   lockup's own gap (gap-xxs on 24px lockups, gap-xs on 32px ones) is part of
   that. Section headers, page heroes and product cards use the sm badge
   (py-xxs-fixed px-sm-fixed type-body-sm-fixed)... */
[role="img"]:is([aria-label="Cypher LM Scheduling"], [aria-label="Cypher LM Notetaker"], [aria-label="Cypher LM Payments"],
  [aria-label="Cypher LM Cypher S"], [aria-label="Cypher LM Cypher N"], [aria-label="Cypher LM Cypher P"])::after {
  padding: var(--spacing-xxs-fixed) var(--spacing-sm-fixed);
  font-size: var(--text-ui-body-sm-fixed); line-height: var(--leading-ui-body-sm);
  margin-left: calc(var(--spacing-sm) - var(--spacing-xxs));
}
[role="img"].gap-xs:is([aria-label="Cypher LM Scheduling"], [aria-label="Cypher LM Notetaker"], [aria-label="Cypher LM Payments"],
  [aria-label="Cypher LM Cypher S"], [aria-label="Cypher LM Cypher N"], [aria-label="Cypher LM Cypher P"])::after {
  margin-left: calc(var(--spacing-sm) - var(--spacing-xs));
}
/* ...while the homepage hero's product tabs use the xs one (py-xxs-fixed px-xs-fixed type-body-xs-fixed). */
[data-testid="multi-product-hero-stage-host"] [role="img"]:is([aria-label="Cypher LM Cypher S"], [aria-label="Cypher LM Cypher N"], [aria-label="Cypher LM Cypher P"])::after {
  padding: var(--spacing-xxs-fixed) var(--spacing-xs-fixed);
  font-size: var(--text-ui-body-xs-fixed); line-height: var(--leading-ui-body-xs);
}
/* Cypher S, N and P lockups also carried the original "New" badge (a sibling
   span after the lockup); with Beta added they showed both. Only Beta stays.
   Cypher C keeps its "New" (it has no Beta outside the Product menu). */
:is(div:has(> [role="img"]), div:has(> div > [role="img"])):has([role="img"]:is([aria-label="Cypher LM Scheduling"], [aria-label="Cypher LM Notetaker"], [aria-label="Cypher LM Payments"], [aria-label="Cypher LM Cypher S"], [aria-label="Cypher LM Cypher N"], [aria-label="Cypher LM Cypher P"])) > span.rounded-ui-xxs.inline-flex { display: none !important; }

/* ---------------------------------------------------------------------------
 * Homepage product hero: scroll behaviour (paired with heroScroll() in
 * custom.js and the `static` mode edit in server/lib/hero5.js).
 *
 * The original component pinned the box by making it position:fixed from page
 * load and re-positioning it from a scroll handler full of timers; fast wheel
 * flicks, PageDown, scrollbar drags and reloads all left it out of sync with
 * the page (blank track, skipped products, the box jumping back). Now the
 * component renders a plain in-flow box and this layer pins it with CSS
 * sticky, so the browser holds it on the compositor thread; every other value
 * (size, backdrop, gradient offset, active product) is a function of the
 * scroll position, set by custom.js through the --cy-hero-* variables below.
 * All of it is keyed on data-cy-hero attributes, so with the script inactive
 * (phones, reduced motion) nothing here applies.
 * ------------------------------------------------------------------------- */
[data-cy-hero-track] {
  height: var(--cy-hero-track-h) !important;
}
[data-testid="multi-product-hero-stage-host"][data-cy-hero] {
  position: sticky !important;
  inset: auto !important;
  top: var(--cy-hero-top, 24px) !important;
  height: var(--cy-hero-max-h);
}
/* Pinned: same stacking as the original (host above everything, backdrop just
   under it), and the box sizes from the script instead of the component. */
[data-testid="multi-product-hero-stage-host"][data-cy-hero="on"] {
  z-index: 2147483647 !important;
}
[data-testid="multi-product-hero-stage-host"][data-cy-hero] > div {
  --multi-product-hero-stage-position: relative !important;
  --multi-product-hero-stage-top: auto !important;
  --multi-product-hero-stage-left: auto !important;
  --multi-product-hero-stage-width: var(--cy-hero-w, auto) !important;
  --multi-product-hero-stage-height: var(--cy-hero-h, auto) !important;
  --multi-product-hero-stage-margin-left: var(--cy-hero-ml, auto) !important;
  --multi-product-hero-stage-margin-right: var(--cy-hero-mr, auto) !important;
}
/* While pinned the original switched the box to a centred flex layout with
   48px padding (the tabs + panel sit in the middle of the full-screen box). */
[data-testid="multi-product-hero-stage-host"][data-cy-hero="on"] > div {
  --multi-product-hero-stage-max-width: none !important;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 48px !important;
  contain: layout paint;
}
/* The gradient slides continuously with the scroll while pinned: the script
   sets --cy-hero-gx on the track, and the component's own per-tab image
   offset is overridden (it keeps animating underneath, so it is correct
   again on release, when this rule stops applying). */
[data-testid="multi-product-hero-stage-host"][data-cy-hero="on"] [data-testid="multi-product-hero-gradient-track"] img {
  transform: var(--cy-hero-gx, none) !important;
}
/* Full-screen off-white backdrop behind the pinned box (the original's
   multi-product-hero-backdrop: fades in once the expand finishes, out as soon
   as the collapse starts). */
[data-cy-hero-backdrop] {
  position: fixed;
  inset: 0;
  background: var(--color-magnolia, #fcfbf8);
  opacity: 0;
  transition: opacity 0.3s ease-in-out;
  pointer-events: none;
  z-index: 2147483646;
}
[data-cy-hero-backdrop="on"] {
  opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
  [data-cy-hero-backdrop] { transition: none; }
}

/* ---------------------------------------------------------------------------
 * Homepage hero: the two live GPU filters, replaced.
 *
 * 1. The gradient behind the box was the SVG stretched to 500% of the box
 *    with `filter: blur(90px)`, re-blurred by the GPU on every frame (and at
 *    every size step while the box grows). On integrated graphics that alone
 *    halved the frame rate. custom.js swaps the src for a pre-blurred render
 *    of exactly that element (cypher/cdn.cypher.com/home-visuals/
 *    hero-gradient-{rest,expanded}.webp, verified within 3/255 of the live
 *    filter) and drops the filter. Each render carries a 100px transparent
 *    margin for the blur bleed, hence the offsets. While the box expands the
 *    `expanded` render (a second <img>) fades in over the `rest` one, so both
 *    end states are exact and the fade band never stretches.
 * 2. The triple drop-shadow filter around the tabs + panel was recomputed
 *    30x per second because the video repaints under it. The same three
 *    shadows as a box-shadow on the panel (which is what casts them; the tab
 *    buttons are drawn as SVG petals and cast nothing visible) measure within
 *    0.85/255 of the filter and cost nothing per frame.
 * ------------------------------------------------------------------------- */
[data-testid="multi-product-hero-gradient-track"] img[data-cy-hero-gradient] {
  filter: none !important;
  left: -100px !important;
  top: -100px !important;
  width: calc(var(--multi-product-hero-gradient-track-width, 500%) + 200px) !important;
  height: calc(100% + 200px) !important;
  max-width: none !important;
}
[data-testid="multi-product-hero-gradient-track"] img[data-cy-hero-gradient="expanded"] {
  position: absolute;
  opacity: var(--cy-hero-x, 0);
  pointer-events: none;
}
[data-testid="multi-product-hero-stage-host"] div[style*="drop-shadow"] {
  filter: none !important;
}
[data-testid="multi-product-hero-stage-host"] div[style*="drop-shadow"] > div:last-child {
  box-shadow:
    0 4px 5px rgba(95, 109, 119, 0.04),
    0 10px 15px rgba(95, 109, 119, 0.04),
    0 40px 50px rgba(95, 109, 119, 0.1);
}

/* ---------------------------------------------------------------------------
 * Nav bar: Product/Solutions/Resources rendered dimmer than Pricing/Talk to
 * sales — confirmed root cause by finding the exact matching CSS rule via
 * the CSSOM (not guesswork): some unrelated component elsewhere on the page
 * injects a global, unscoped `<style>` tag at runtime containing
 * `[aria-expanded="false"] { opacity: .5 }`, written for whatever that
 * component is (an accordion/FAQ toggle, going by the pattern), but a bare
 * attribute selector with no class/id scoping matches every element site-
 * wide carrying that attribute — including these three nav buttons, which
 * only have aria-expanded because they open a dropdown, unrelated to
 * whatever the rule's author actually meant to dim. Same bug shape as the
 * tab-icon centering fix above (button[role="tab"] > span[class*="z-20"]);
 * scoped narrowly to the header so whatever the stray rule is actually
 * for, elsewhere on the page, is untouched. */
#site-header button[aria-expanded] {
  opacity: 1 !important;
}

/* ---------------------------------------------------------------------------
 * Nav bar sliding highlight (see fixNavPill in custom.js): one pill that
 * glides between Product / Solutions / Resources / Pricing, same colour and
 * radius as the items' own hover background, which is turned off here so
 * there's never a second, static background under the moving one. The
 * easing overshoots slightly, like the spring in the 21st.dev component it's
 * modelled on. isolation keeps the pill (z-index -1) above the header's
 * background but under the item labels. The nav is deliberately NOT made
 * position:relative: that changes the buttons' offsetParent, which the
 * header uses to place the dropdowns (they stopped opening under Product).
 * ------------------------------------------------------------------------- */
#site-header nav:has(> .cy-nav-pill) { isolation: isolate; }
#site-header nav:has(> .cy-nav-pill) > div { background-color: transparent !important; }
.cy-nav-pill {
  position: absolute; left: 0; top: 0; z-index: -1;
  border-radius: 16px; background: #F5F3EE;
  opacity: 0; pointer-events: none; will-change: transform, width;
  transition:
    transform 0.38s cubic-bezier(0.3, 1.25, 0.55, 1),
    width 0.38s cubic-bezier(0.3, 1.25, 0.55, 1),
    height 0.38s cubic-bezier(0.3, 1.25, 0.55, 1),
    opacity 0.18s ease;
}
.cy-nav-pill.is-on { opacity: 1; }
/* Chevron flips on hover as well as when its menu is open (21st.dev
 * component); the header's open state uses the `rotate` property. */
#site-header nav > div .tabler-icon-chevron-down { transition-duration: 0.3s; }
#site-header nav > div:hover .tabler-icon-chevron-down { rotate: 180deg; }
/* Menu morph (fixNavMenuMorph in custom.js): the ghost card carries the
 * panel's white background and shadow and resizes between menus; the panel
 * itself keeps its position and contents. */
.Sp-BGW_dropdownOuter.cy-morph > .Sp-BGW_dropdownPanel { background-color: transparent !important; box-shadow: none !important; }
.cy-menu-ghost { position: absolute; z-index: -1; pointer-events: none; }
.Sp-BGW_dropdownOuter { animation: cy-menu-in 0.2s ease-out; }
@keyframes cy-menu-in { from { opacity: 0; transform: translateY(-4px); } }
@media (prefers-reduced-motion: reduce) {
  .Sp-BGW_dropdownOuter { animation: none; }
  .cy-menu-ghost, .Sp-BGW_dropdownPanel { transition: none !important; }
}
@media (prefers-reduced-motion: reduce) {
  .cy-nav-pill { transition: opacity 0.01s linear; }
}
