/* ============================================================================
   Video Skills page chrome — the vocabulary shared by every /video-skills/*
   page: the stripped-down nav and marquee, the type scale, the gradient hero
   wash and its blurred timeline strip, the content bands, the FAQ accordion,
   and the orbiting skill tiles that close the page.

   Extracted from the inline styles on /video-skills/cutdown rather than
   retyped, so the values are the ones already shipping. Class names are kept
   exactly as that page has them, so pointing it at this file is a matter of
   deleting its <style> block and adding a <link>.

   ⚠️ /video-skills/cutdown still carries its own copy. Until it's switched over
   there are two sources for these rules — change both, or do the switch first.

   Loaded AFTER global.css (fonts and the --bg / --ink / --accent tokens) and
   alongside nav.css + chrome.css (the shared nav, marquee and footer). Pages
   that use the split rows or the media frame also want marketing.css +
   use-case.css; the play button and lightbox want video.css + video.js.

   Anything specific to one page — /cutdown's prompt dock, email gate and agent
   composer — stays inline on that page.
   ============================================================================ */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* ── STRIPPED-DOWN CHROME ──
   Ported from /lp/video-skills: a landing page, so the shared nav is reduced to
   the logo + one button — no section links, no "Sign in", no mobile
   hamburger/overlay. nav.js still injects the full markup; hiding it here keeps
   the shared component untouched.
   ⚠️ These selectors mirror nav.css — if the nav markup changes, revisit. */

#site-nav .nav-links,
#site-nav .nav-actions .btn-outline,
#site-nav .nav-burger,
#site-nav .nav-menu { display: none !important; }

/* nav.css lays the bar out as [1fr | auto | 1fr] for logo / links / actions.
   With the links gone, .nav-actions auto-places into that middle column and the
   button sits centered — collapse the grid to two columns so it stays right. */

#site-nav .nav { grid-template-columns: 1fr auto; }

/* nav.css drops .nav-actions into the hamburger menu at ≤700px; this page has no
   menu, so keep the button in the bar at every width. */

@media (max-width: 700px) {
  #site-nav .nav-actions { display: flex !important; }
}

/* "Book a Skill-building Session" is a long label for a phone-width bar, so the
   button carries both and CSS picks one. The script below <body> is what puts
   them there — nav.js owns the button's default "Book a demo". */

#site-nav .nav-cta-short { display: none; }

@media (max-width: 620px) {
  #site-nav .nav-cta-long  { display: none; }
  #site-nav .nav-cta-short { display: inline; }
}

/* Remove the shared "Book a demo" marquee but KEEP the curved footer transition.
   The curve isn't its own element — it's the .marquee-strip's rounded bottom
   corners plus the footer's -72px overlap letting the green peek through. So the
   strip stays as a slim curved cap and only its scrolling text + custom cursor
   are hidden (which also disables the marquee's hover/click). Same treatment as
   /lp/video-skills, and it's what the design draws: a 176px-tall blank band
   with a 72px rounded bottom. Scoped to this page so chrome.css is untouched. */

#site-marquee .marquee-hover,
#site-marquee .marquee-cursor { display: none !important; }

#site-marquee .marquee-strip {
  padding: 0 !important;
  height: 176px;   /* per Figma; the 72px rounded bottom stays */
}

/* ── SHARED TYPE ── */

/* The page headline. 80/80 with no tracking, as drawn — the section headings
   below step down to 56/64 and pick up the -0.75px the rest of the marketing
   pages use at that size. */

.headline {
  font-weight: 400;
  font-size: 80px;
  line-height: 80px;
  color: #080808;
  text-align: center;
  text-wrap: balance;
}

.section-headline {
  font-weight: 400;
  font-size: 56px;
  line-height: 64px;
  letter-spacing: -0.75px;
  color: #080808;
  text-align: center;
  text-wrap: balance;
}

/* Designer line breaks, kept at desktop widths and dropped on phones where a
   forced break leaves a short ragged line. Each <br class="lb"> is preceded by a
   space in the markup — collapsed while the break is visible, and the word
   separator once it's hidden. */

@media (max-width: 768px) {
  br.lb { display: none; }
}

.lede {
  font-size: 20px;
  line-height: 26px;
  color: #707070;
  text-align: center;
  text-wrap: pretty;
}

/* mix-blend-multiply lets the muted copy sink into the gradient wash behind it
   in the hero and the closing section (a no-op on the flat bands between). */

.lede-blend { mix-blend-mode: multiply; }

.lede p + p { margin-top: 26px; }

/* the design's blank line between paragraphs */

/* Buttons — .cta / .cta-lime / .cta-dark live in the shared /blog/nav.css. */

/* ── HERO ── */

.hero {
  position: relative;
  /* Horizontal only. The wash is 803px tall from the hero's top, which is BELOW
     the sticky nav's 86px of flow — so it runs ~110px past the hero's bottom
     edge, and clipping both axes cut it off in a hard line straight across the
     page. Letting it run vertically means the tail lands on the flat band below,
     which is what the design draws. The bands below carry no background of their
     own (see .band), so the tail stays visible under them, and paint order keeps
     their text on top of it. Still horizontal-only, because .hero-bg is drawn
     at 120% width from -10%: it has to be cut off at the side edges, and must
     not be cut off at the bottom. */
  overflow-x: clip;
}

/* The gradient wash — the same asset as /lp/video-skills, drawn past both side
   edges so it never ends inside the viewport.

   Height 100% rather than the design's fixed 803px, and that's the fix for the
   hard line this used to cut across the page. The file carries its Gaussian
   blur's falloff as ~22% of padding at the top and bottom (the shapes only
   occupy the middle 56%), and preserveAspectRatio="none" means those bands
   stretch with the element — so sizing it to the hero puts the falloff exactly
   at the hero's edges and the wash fades to nothing on its own, whatever the
   hero's height. A fixed 803px overshot a 692px desktop hero by 110px and a
   560px phone one by 240px, and got sheared off at the bottom in both. */

.hero-bg {
  position: absolute;
  top: 0;
  left: -10%;
  width: 120%;
  height: 100%;
  pointer-events: none;
}

.hero-inner {
  /* position:relative (no z-index) keeps this above the absolute .hero-bg via
     paint order WITHOUT creating a stacking context — so the copy's
     mix-blend-mode:multiply can still blend with the gradient behind it. */
  position: relative;
  max-width: 1440px;
  margin: 0 auto;
  /* 80px below the 80px-tall sticky nav lands the script wordmark on the
     design's 160px. The bottom padding used to be the room the timeline strip
     occupied — with the strip gone it's just the hero's own air, and it still
     sets the gradient's height: .hero-bg is 100% of the hero and fades out
     within its own top and bottom 22%, so the wash ends wherever this does. */
  padding: 80px 60px 120px;
}

.hero-head {
  position: relative;
  max-width: 1098px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 32px;
}

/* The "Video Skills" script wordmark, already Capsule blue in the file — the
   same asset the live-demo event page sets its headline in. */

.headline-script {
  display: block;
  width: 266px;
  height: auto;
  max-width: 100%;
}

.hero-head .lede { max-width: 688px; }
/* Two pages carry a noticeably longer lede than the rest of the family, and at
   688px each one broke to three, the last line a stub. 800px is measured, not
   picked: /article-to-video needs 776px to hold two lines and
   /real-estate-listing needs 784px, so this clears both with room for a copy
   edit. It still sits inside the headline above it — the widest h1 line is
   877px and 846px — so the hierarchy holds. */
.hero-head .lede--wide { max-width: 800px; }

/* ── CONTENT BANDS ── */

.band {
  position: relative;
  /* No background: body's is already var(--bg), and an opaque one here would
     paint over the washes that bleed in from the sections either side — the
     hero's from above, the closing section's own from below. */
  padding: 80px 60px;
  /* Horizontal only, for the same reason as the hero: the closing section's
     glows are ~1733px wide and reach ~90px above its top edge, and clipping
     vertically ended them in a line across the page. Their bleed lands in the
     80px of padding above, well clear of the FAQ rows. */
  overflow-x: clip;
}

.band-inner {
  max-width: 652px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 40px;
}

/* ── FAQ ── */

/* The rows are wider than the 652px measure the copy bands are set to — 1080px,
   which is 1440 less the 60px page margins and the design's 120px inset — so the
   FAQ section opens its .band-inner up and the heading stays centred inside it. */

.band-inner.is-wide { max-width: 1080px; gap: 80px; }

/* The rows ARE /use-case's accordion — .uc-faq in use-case.css, linked by every
   page in this family. This page used to carry its own copy with inverted
   colours (full-strength question, muted answer, grey card); it now takes that
   sheet's as-is: white card, muted question that goes to full ink on hover and
   while open, full-ink answer. Nothing about the mechanics is duplicated here.

   Two adjustments, both about the band this sits in rather than the accordion:
   .band-inner is a centred flex column, so the list has to claim the full width
   or it shrinks to its longest question; and .band-inner's own 80px gap is
   already the space under the heading, so .uc-faq's top margin would double it. */
.band-inner .uc-faq {
  width: 100%;
  margin-top: 0;
}

/* ── CLOSING SECTION (skill-tile cluster + CTAs) ── */

.closer .band-inner { max-width: 874px; gap: 80px; }

/* The copy block keeps the design's tighter 40px internal rhythm inside the
   section's 80px. */

.closer-copy {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 40px;
}

/* The cluster of skill tiles, exported from the design as one graphic: eight
   blurred gradient tiles at assorted rotations and blur radii, which is a lot
   of atmosphere to rebuild in CSS for something purely decorative. The two
   washes behind it ship as their own SVGs so they can bleed past the graphic
   (they're 230–270% of its width) instead of being baked into an opaque
   rectangle that would show its edges against the page. */

.closer-art {
  position: relative;
  width: min(643px, 86%);
  margin: 0 auto;
}

/* ── THE ORBIT ──
   The tiles used to be one flat PNG exported from the cluster group. They're
   five vector icons now, each ~1KB, riding a tilted elliptical path — so the
   whole graphic is 5KB of SVG instead of 314KB of PNG, and it scales cleanly.

   The path is the design's own: fitting an ellipse to the eight tile centres in
   the Figma cluster gives a tilt of 8.5 degrees, semi-axes of 269 x 106px, and
   tiles running 94px at the far point to 180px at the near one. Those numbers
   are what the keyframes below are generated from, so the ring passes through
   the arrangement the static frame draws.

   Everything is expressed as a PERCENTAGE of a slot's own width, which is in
   turn a percentage of the container — so the orbit scales with the section
   instead of needing a breakpoint. 164.1% of a 164px tile is the 269px
   semi-major axis. The one exception is the blur, since CSS has no relative
   blur; it steps down on phones, where the whole graphic is smaller.

   One @keyframes drives all eight. --phase offsets each into the cycle via a
   negative animation-delay, which is what makes them a ring rather than a
   convoy, and z-index rides along in the keyframes so the near tiles paint over
   the far ones without any of it being managed in script. */

@property --orbit-blur {
  syntax: "<number>";
  inherits: false;
  initial-value: 0;
}

.orbit {
  position: relative;
  /* Contains the tiles' z-index. The keyframes ride z-index from 0 to 100 so
     the near tiles paint over the far ones, and .orbit had no stacking context
     of its own — so those numbers competed in the ROOT context, where they beat
     /cutdown's prompt box at 90 and painted over it. Measured at scrollY 3261:
     five tiles across the prompt, two of them at 92 and 98.

     isolate rather than a z-index here, because it scopes the tiles without
     giving .orbit a depth of its own to keep in step with anything else. The
     glows are earlier siblings, so they still sit under the tiles. */
  isolation: isolate;
  width: 100%;
  /* One full revolution. The knob for the whole thing's pace — a tile crosses
     the front every eighth of this. */
  --orbit-dur: 28s;
  /* The natural box of the group this replaces, so the section's rhythm and the
     washes' placement carry over untouched. */
  aspect-ratio: 643 / 366;
}

.orbit-slot {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 25.5%;            /* 164 / 643 — the base tile; scale() does the rest */
  aspect-ratio: 1;
  margin: -12.75% 0 0 -12.75%;
  animation: orbit var(--orbit-dur, 40s) linear infinite;
  /* Negative delay starts each slot part-way through, so they're spread around
     the ring from the first frame rather than filing in. */
  animation-delay: calc(var(--phase, 0) * var(--orbit-dur, 40s) * -1);
  /* CSS has no relative blur, and a fixed px radius that looks right on a 164px
     tile turns a 49px one to mush on a phone. So the keyframes carry a unitless
     depth number and --orbit-blur-px scales it to the graphic's size — one knob
     per breakpoint instead of a second copy of the keyframes.
     The @property registration above is what makes it interpolate; without it
     (older Safari, older Firefox) the substitution still works and the blur
     simply steps through the 24 stops instead of easing between them. */
  filter: blur(calc(var(--orbit-blur, 0) * var(--orbit-blur-px, 1px)));
  will-change: transform, filter;
}

/* Each tile sits 12 degrees clockwise, individually — the rotation the Figma
   cluster gives every tile, which the single-icon exports don't carry. It's on
   the image rather than the slot so it stays put while the slot orbits: one
   static declaration instead of a repeat in all 25 keyframe stops. The rounded
   corners are transparent, so the wider bounding box costs nothing. */

.orbit-slot img {
  display: block;
  width: 100%;
  height: 100%;
  transform: rotate(12deg);
}

/* Paused rather than removed: each slot freezes at its own --phase offset, which
   is a snapshot of the ring — so a visitor who asked for no motion still gets
   the arrangement the design draws, not a stack of eight tiles in one spot. The
   script below <body> pauses it the same way when the section is off screen. */

@media (prefers-reduced-motion: reduce) {
  .orbit-slot { animation-play-state: paused; }
}

.orbit.is-idle .orbit-slot { animation-play-state: paused; }

@keyframes orbit {
  0%        { transform: translate(162.09%, 5.91%) scale(0.8340); --orbit-blur: 2.50; opacity: 0.925; z-index: 50; }
  4.16667%  { transform: translate(154.09%, 21.57%) scale(0.9016); --orbit-blur: 1.85; opacity: 0.944; z-index: 63; }
  8.33333%  { transform: translate(135.58%, 34.50%) scale(0.9645); --orbit-blur: 1.25; opacity: 0.963; z-index: 75; }
  12.5%     { transform: translate(107.81%, 43.83%) scale(1.0186); --orbit-blur: 0.73; opacity: 0.978; z-index: 85; }
  16.6667%  { transform: translate(72.68%, 48.91%) scale(1.0600); --orbit-blur: 0.33; opacity: 0.990; z-index: 93; }
  20.8333%  { transform: translate(32.59%, 49.41%) scale(1.0861); --orbit-blur: 0.09; opacity: 0.997; z-index: 98; }
  25%       { transform: translate(-9.74%, 45.29%) scale(1.0950); --orbit-blur: 0.00; opacity: 1.000; z-index: 100; }
  29.1667%  { transform: translate(-51.42%, 36.83%) scale(1.0861); --orbit-blur: 0.09; opacity: 0.997; z-index: 98; }
  33.3333%  { transform: translate(-89.61%, 24.60%) scale(1.0600); --orbit-blur: 0.33; opacity: 0.990; z-index: 93; }
  37.5%     { transform: translate(-121.70%, 9.44%) scale(1.0186); --orbit-blur: 0.73; opacity: 0.978; z-index: 85; }
  41.6667%  { transform: translate(-145.52%, -7.61%) scale(0.9645); --orbit-blur: 1.25; opacity: 0.963; z-index: 75; }
  45.8333%  { transform: translate(-159.43%, -25.40%) scale(0.9016); --orbit-blur: 1.85; opacity: 0.944; z-index: 63; }
  50%       { transform: translate(-162.49%, -42.71%) scale(0.8340); --orbit-blur: 2.50; opacity: 0.925; z-index: 50; }
  54.1667%  { transform: translate(-154.49%, -58.37%) scale(0.7664); --orbit-blur: 3.15; opacity: 0.906; z-index: 37; }
  58.3333%  { transform: translate(-135.98%, -71.30%) scale(0.7035); --orbit-blur: 3.75; opacity: 0.887; z-index: 25; }
  62.5%     { transform: translate(-108.21%, -80.63%) scale(0.6494); --orbit-blur: 4.27; opacity: 0.872; z-index: 15; }
  66.6667%  { transform: translate(-73.08%, -85.71%) scale(0.6080); --orbit-blur: 4.67; opacity: 0.860; z-index: 7; }
  70.8333%  { transform: translate(-32.99%, -86.21%) scale(0.5819); --orbit-blur: 4.91; opacity: 0.853; z-index: 2; }
  75%       { transform: translate(9.34%, -82.09%) scale(0.5730); --orbit-blur: 5.00; opacity: 0.850; z-index: 0; }
  79.1667%  { transform: translate(51.02%, -73.63%) scale(0.5819); --orbit-blur: 4.91; opacity: 0.853; z-index: 2; }
  83.3333%  { transform: translate(89.21%, -61.40%) scale(0.6080); --orbit-blur: 4.67; opacity: 0.860; z-index: 7; }
  87.5%     { transform: translate(121.30%, -46.24%) scale(0.6494); --orbit-blur: 4.27; opacity: 0.872; z-index: 15; }
  91.6667%  { transform: translate(145.12%, -29.19%) scale(0.7035); --orbit-blur: 3.75; opacity: 0.887; z-index: 25; }
  95.8333%  { transform: translate(159.03%, -11.40%) scale(0.7664); --orbit-blur: 3.15; opacity: 0.906; z-index: 37; }
  100%      { transform: translate(162.09%, 5.91%) scale(0.8340); --orbit-blur: 2.50; opacity: 0.925; z-index: 50; }
}

/* Both washes centre on a point ~10% above the cluster's middle, as drawn. The
   SVGs carry their Gaussian blur's bleed as padding, which is why they're sized
   well past the graphic rather than to it — scaling them down to fit would
   shrink the gradient and wash it out. */

.closer-art .art-glow {
  position: absolute;
  top: 40%;
  left: 50%;
  height: auto;
  pointer-events: none;
}

.closer-art .art-glow-ellipse { width: 269.6%; transform: translate(-50%, -50%); }

/* Drawn pointing up in the file; the design rotates it. */

.closer-art .art-glow-wash    { width: 229.9%; transform: translate(-50%, -50%) rotate(180deg); }

.closer-ctas { display: flex; flex-wrap: wrap; justify-content: center; gap: 16px; }

/* ── RESPONSIVE ── (nav, marquee, and footer responsiveness live in nav.css / chrome.css) */

@media (max-width: 1200px) {
  .headline { font-size: 68px; line-height: 70px; }
}

@media (max-width: 1024px) {
  .hero-inner { padding: 64px 40px 96px; }
  /* tracks .hero-inner's margins */
  .band { padding: 72px 40px; }
  .headline { font-size: 60px; line-height: 62px; }
  .section-headline { font-size: 44px; line-height: 52px; }
  .closer .band-inner { gap: 64px; }
}

@media (max-width: 768px) {
  .hero-inner { padding: 48px 20px 80px; }
  .band { padding: 56px 20px; }
  .headline { font-size: 44px; line-height: 46px; }
  .section-headline { font-size: 36px; line-height: 42px; }
  .lede { font-size: 18px; line-height: 24px; }
  .lede p + p { margin-top: 24px; }
  .hero-head { gap: 24px; }
  .headline-script { width: 200px; }
  /* tracks .hero-inner's margins */
  /* Scale the strip down as a whole (width drives it — height follows) rather
     than squashing its aspect. At the desktop width a phone only sees the middle
     few hundred pixels, which is mostly playhead. */
  .closer .band-inner { gap: 48px; }
  .closer-copy { gap: 32px; }
  /* 92%, not 100%: the ring is a touch wider than its box (the tile at the
     far end of the major axis hangs past it), and at full width the band's
     overflow-x clip was shaving the leftmost tile. */
  .closer-art { width: 92%; }
  .orbit-slot { --orbit-blur-px: 0.55px; }
  /* Full-width CTAs so neither label truncates. */
  .closer-ctas { flex-direction: column; align-items: stretch; width: 100%; }
  .closer-ctas .cta { width: 100%; }
}

@media (max-height: 720px) {
  .hero-inner { padding-top: 48px; }
  .hero-head { gap: 24px; }
}

@media (max-width: 480px) {
  .headline { font-size: 38px; line-height: 40px; }
}

/* A row that flips on its own. use-case.css alternates with :nth-child(even),
   which needs a row above it to be even — and the listing pages dropped their
   first row, leaving the "Any video workflow" row alone and therefore odd. It
   would have rendered text-left, mirroring what the design draws. This is that
   sheet's own flip, addressable rather than positional.

   The mobile reset is not optional: below 991px use-case.css collapses
   .uc-split (0,1,0) to one column, which this selector (0,2,0) would outrank,
   and the row would stay two-up on a phone. */
.vs-splits .uc-split--flip {
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
}
.vs-splits .uc-split--flip .uc-split-text { order: 2; }
@media (max-width: 991px) {
  .vs-splits .uc-split--flip { grid-template-columns: minmax(0, 1fr); }
  .vs-splits .uc-split--flip .uc-split-text { order: 0; }
}

/* ── SPLIT-ROW HEADINGS ──
   The rows themselves are the shared .uc-split from use-case.css — same grid,
   same sticky copy, same alternating flip (and so the same fix for the column
   order that went in with #121). Only the type differs: these rows carry the
   page's own 56/64 heading rather than the h3 the use-case rows use, because
   here they're the section's main headings and not a sub-level. */
.vs-split-head {
  font-weight: 400;
  font-size: 56px;
  line-height: 64px;
  letter-spacing: -0.75px;
  color: #080808;
  text-wrap: balance;
}
.vs-split-copy {
  margin-top: 40px;
  font-size: 20px;
  line-height: 26px;
  color: #707070;
  mix-blend-mode: multiply;   /* sinks into the hero wash where it reaches */
  text-wrap: pretty;
}
.vs-split-copy p + p { margin-top: 26px; }

/* ── NUMBERED STEPS ──
   A rounded-square counter beside each step. The square is drawn rather than
   shipped as an asset — it's a 24px box with an 8px radius — and the number is
   Matter Mono, the same face the timeline strip's timecodes use. */
.vs-steps {
  margin-top: 40px;
  padding-left: 24px;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
/* A block with the square in its own left gutter — NOT display:flex. Flex
   would make every inline child of the <li> its own flex item, and the steps
   carry an inline .vs-cmd chip: the chip became a sibling item and squeezed the
   text into a narrow ragged column beside it. Wide desktop rows hid that; at
   375px it was unmissable. Absolute-positioning the counter keeps the text and
   the chip as ordinary inline content that wraps as one run. */
.vs-steps li {
  position: relative;
  padding-left: 36px;      /* the 24px square + the 12px gap beside it */
  font-size: 20px;
  line-height: 28px;
  color: #707070;
}
/* counter-reset/increment rather than <ol>'s own markers, so the number sits
   inside the drawn square and takes the mono face. */
.vs-steps { counter-reset: vs-step; }
.vs-steps li { counter-increment: vs-step; }
.vs-steps li::before {
  content: counter(vs-step);
  position: absolute;
  left: 0;
  top: 2px;                /* onto the text's first baseline, not the line box */
  width: 24px;
  height: 24px;
  border: 1px solid #707070;
  border-radius: 8px;
  font-family: var(--font-mono);
  font-size: 14px;
  line-height: 22px;
  text-align: center;
}
/* A link inside a step. global.css sets `a { color: inherit; text-decoration:
   none }`, so without this the MCP link in step two would be invisible — it
   would read as ordinary muted step text. This is the site's own inline body
   link, the one .body-col a in blog.css and .lg-doc a in legal.css wear: full
   ink against the step's muted grey, a 1.5px underline held 4px off the
   baseline, and the lime highlighter sweeping up from that baseline on hover. */
.vs-steps a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 4px;
  background-image: linear-gradient(var(--accent), var(--accent));
  background-repeat: no-repeat;
  background-size: 100% 0;
  background-position: 0 100%;
  transition: background-size 0.35s cubic-bezier(.2, .8, .2, 1),
              text-decoration-thickness 0.25s ease;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
.vs-steps a:hover,
.vs-steps a:focus-visible {
  background-size: 100% 100%;
  text-decoration-thickness: 2px;
}
@media (prefers-reduced-motion: reduce) {
  .vs-steps a { transition: text-decoration-thickness 0.25s ease; }
}

/* An inline command. The paragraph above the steps now types the skill name out
   as plain prose, so this treatment is only ever the command in step three:
   Capsule blue on a wash of itself. Inline-block so it can't be split across a
   line break. */
.vs-cmd {
  display: inline-block;
  padding: 0 4px;
  border-radius: 8px;
  background: rgba(45, 103, 248, 0.12);
  font-family: var(--font-mono);
  font-size: 16px;
  line-height: 24px;
  color: #2d67f8;
  white-space: nowrap;
}

/* ── TOOLS GRID ──
   Two columns of cards, each an icon beside a title and a line of copy. The
   card surface is the FAQ row's — same grey at 12%, one step up in radius. */
.vs-tools {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  width: 1098px;
  max-width: 100%;
}
.vs-tool {
  display: flex;
  gap: 24px;
  align-items: center;
  padding: 24px;
  border-radius: 32px;
  /* The same white card the FAQ rows and /use-case's cards are, via the token
     rather than a literal — one place decides what a card is. */
  background: var(--cu-card);
  color: inherit;
  text-decoration: none;
  transition: transform 0.2s ease;
}
/* Only the cards that are LINKS react. Most of these six have nowhere to point
   yet and ship as plain <div>s; giving those a hover would promise a click that
   isn't there. Each one starts responding the moment it gets an href.

   Just a size increase — no shadow. A transform, so it costs no layout and the
   cards around it don't move. 1.02 is set by the grid rather than picked: the
   cards are 532px in a 16px gutter, so 8px a side is all there is before two
   of them touch, and 532 x 0.02 / 2 is 5.3px. Anything past 1.03 collides. */
a.vs-tool:hover,
a.vs-tool:focus-visible {
  transform: scale(1.02);
}
@media (prefers-reduced-motion: reduce) {
  a.vs-tool:hover,
  a.vs-tool:focus-visible { transform: none; }
}
.vs-tool img {
  flex: 0 0 auto;
  width: 80px;
  height: 80px;
  border-radius: 24px;
  display: block;
}
.vs-tool h3 {
  font-weight: 400;
  font-size: 24px;
  line-height: 32px;
  color: #080808;
}
.vs-tool p {
  margin-top: 8px;
  font-size: 20px;
  line-height: 26px;
  color: #707070;
  text-wrap: pretty;
}

/* ── SPLIT / TOOLS RESPONSIVE ──
   use-case.css collapses .uc-split to one column at 991px, so the headings step
   down with it rather than at this file's own 768px breakpoint. */
@media (max-width: 991px) {
  .vs-split-head { font-size: 44px; line-height: 52px; }
  .vs-tools { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 768px) {
  .vs-split-head { font-size: 36px; line-height: 42px; }
  .vs-split-copy { margin-top: 24px; font-size: 18px; line-height: 24px; }
  .vs-steps { margin-top: 24px; padding-left: 0; }
  .vs-steps li { font-size: 18px; line-height: 26px; }
  .vs-tool { gap: 16px; padding: 16px; border-radius: 24px; }
  .vs-tool img { width: 64px; height: 64px; border-radius: 19px; }
  .vs-tool h3 { font-size: 20px; line-height: 28px; }
  .vs-tool p { font-size: 17px; line-height: 25px; }
}

/* ── MEDIA IN THE SPLIT ROWS ──
   .uc-media from use-case.css already gives the frame its near-white 60% lip —
   that border was aligned to these pages. Two things differ: the radius is 32px
   here rather than the 64px the customer wall uses, and the frame holds its own
   16:9-ish ratio from the design instead of taking the image's, so a taller
   still crops into it rather than making the row taller than the copy beside
   it. */
/* The rows are the shared .uc-split, so they should sit in the shared width
   envelope too: every other page puts them in .cu-section, which caps at
   --cu-max and insets by --cu-page-margin. This page's bands have no max-width
   of their own, so on a wide window the rows just kept growing. Expressed with
   the tokens rather than as 1472px so it tracks any change to them.

   The row gap is deliberately NOT set here. use-case.css already gives
   .uc-splits --cu-huge and steps it down to --cu-large under 991px; this sheet
   loads after it, so any gap here would win inside that media query too and
   the rows would keep their desktop spacing on a phone. */
.vs-splits {
  max-width: calc(var(--cu-max) - 2 * var(--cu-page-margin));
  margin: 0 auto;
}

.vs-splits .uc-media {
  border-radius: 32px;
  aspect-ratio: 652 / 367;
}
.vs-splits .uc-media > img {
  height: 100%;
  object-fit: cover;
}
@media (max-width: 768px) {
  .vs-splits .uc-media { border-radius: 24px; }
}

/* ================= THE PROMPT DOCK, SCRIM AND EMAIL GATE =================
   Shared by every /video-skills/* page that runs a live Skill in the hero —
   /cutdown and /clean-audio today. The markup and behaviour that go with
   these rules are in /blog/assets/video-skills-prompt.js; a page opts in by
   including that script plus the dock / scrim / gate / composer markup.

   Extracted verbatim from /video-skills/cutdown, which is why the notes below
   still speak in that page's terms. Nothing here is skill-specific: the box,
   the blur, the gate and the thread host behave the same wherever they run.
   ================================================================= */
/* ── PROMPT BOX ──
   The page's one interactive element, and it has to stay reachable: it's drawn
   in the hero, and once you start scrolling it settles 64px from the bottom of
   the viewport and stays there for the rest of the page.

   It can't be `position: sticky`. Sticky with a `bottom` offset holds an element
   up while its natural position is BELOW the offset line and releases it after —
   and the hero draws this box ABOVE that line, so sticky would do nothing at
   all. It also can't be a clamp on the scroll position, because the hero
   position is above the dock: scrolling only ever carries it further up, never
   down onto the line.

   So the box is ALWAYS fixed at the dock, and the script below <body> writes a
   transform that moves it off that line: translated up to where the hero draws
   it, and scaled up there too. Neither is flipped at a threshold — the box eases
   toward wherever the scroll position says it should be, frame by frame, which
   is what keeps the move from reading as a jump.

   .prompt-dock is an empty spacer holding the hero's layout open where the box
   appears to sit. Living at the end of <body> rather than inside .hero also
   keeps it clear of that section's `overflow: clip`.

   transform-origin pins the bottom edge, so the box grows upward out of the dock
   line and the spacer's own height is all that has to account for the growth.
   If the hero position ends up BELOW the dock line (a short window), the lift
   clamps to zero and the box is simply docked, at its docked size, from the
   start.

   At the end of the page the box rides up to stay 80px clear of the footer, and
   keeps going — off the top of the viewport, so it scrolls away with the page
   rather than hovering over the footer's links. */
/* The spacer doubles as the declaration of how big the box gets in the hero:
   815px is 652 × 1.25, and the script takes the ratio of this width to the box's
   own as the scale factor. Putting it here rather than as a number in the script
   means the growth is bounded by the room available at every width for free —
   both this and the box clamp to the same page margins, so as the window
   narrows the ratio falls to 1 on its own and the enlarged box can never
   overflow. On a phone there's no room for any of it and it stays at 1.

   The 46px above is the design's gap below the headline block, plus room for the
   box growing upward out of the dock line (see .prompt's transform-origin). */
.prompt-dock {
  width: min(815px, 100%);
  margin: 64px auto 0;
  /* 108 × 1.25 — the box's height at the design's sizes (20+24+20 of text row,
     then 32+12 of action row), grown. The script replaces this with the measured
     value; the literal is what holds the hero open before it runs (and if it
     never does). */
  height: 135px;
}
.prompt {
  /* Product UI, not site type: Inter in Figma. Rather than ship a font file for
     one element it falls back to the platform UI face, which reads the same at
     16px. (Same call as the composer mock on /lp/video-skills.) */
  --font-ui: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  position: fixed;
  bottom: 64px;
  left: 50%;
  z-index: 90;             /* over the page, under the sticky nav (100) */
  /* Matches .prompt-dock at every width — the dock is 652px inside .hero-inner's
     page margins, so the same margins are subtracted here. Keep the two in step:
     if the hero padding changes, this changes with it. */
  width: min(652px, calc(100vw - 120px));
  /* Bottom-centre: the scale then leaves the bottom edge on the dock line and
     the box grows upward, and the horizontal centre stays put — translateX(-50%)
     shifts by half the UNSCALED width, which only lands centred because the
     scale is about that same centre. */
  transform-origin: 50% 100%;
  /* The script writes the full transform; this is the no-JS resting state. */
  transform: translateX(-50%);
  /* Its own compositor layer, so the per-frame transform is applied by the
     compositor at subpixel precision instead of repainting the box — which is
     what would snap the type to whole pixels and step it as it moves. */
  will-change: transform;
  background: #fafafa;
  border-radius: 16px;
  /* The design's drop shadow, and only that. */
  box-shadow: 0 0 40px 40px rgba(45, 103, 248, 0.05);
  font-family: var(--font-ui);
  cursor: text;
}
/* Hold the resting composer size before the agent mounts (text 64 + actions 44).
   Avoids CLS when the empty host fills in. */
#cutdown-agent-composer {
  min-height: 108px;
}
.cutdown-composer-shell {
  display: flex;
  flex-direction: column;
  min-height: 108px;
}
.cutdown-composer-shell-field {
  margin: 0;
  padding: 20px 16px;
  font-size: 16px;
  font-weight: 400;
  line-height: 24px;
  color: #8f8f8f;
}
.cutdown-composer-shell-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: 0 12px 12px;
  margin-top: auto;
}
.cutdown-composer-shell-send {
  display: block;
  width: 32px;
  height: 32px;
  border-radius: 999px;
  background: var(--accent);
  opacity: 0.3;
}
/* There used to be a slow pulse here, on a pseudo-element carrying a second
   copy of the shadow. It's gone: it wasn't in the design, and it was animating
   opacity on a child of the one element on the page that has to glide, so every
   frame repainted a 48px blur along with the box's own move. The shadow above is
   the design's, and now the only one. */
/* Deliberately NO transition on the transform either. The script eases the
   hand-off itself, frame by frame, and a CSS transition on top would fight it —
   every frame would restart a half-second animation toward a target that has
   already moved, which is mush on a continuous scroll and lag on the footer. */
/* ── FOCUSED PROMPT ──
   Clicking into the field drops a scrim over the whole page and blurs
   everything behind it, so the prompt is the only thing in focus. The scrim goes
   ABOVE the sticky nav (which nav.css puts at z-index 100), because the design
   blurs the bar along with the rest of the page — so the prompt and the close
   button have to climb above the scrim in turn while it's open.

   backdrop-filter blurs whatever is painted beneath the element, so one fixed
   scrim does the whole page in a single pass — no filter on the content itself,
   which would have meant blurring a `position: fixed` box's own containing
   block and taking the prompt with it.

   visibility rides along with opacity so a closed layer can't eat clicks or be
   tabbed into. It is transitioned as `0s linear 0.32s` when hiding and `0s` when
   showing, rather than `0.32s`: given a duration, Chrome holds the discrete flip
   for the first couple of frames, which left the gate's email field genuinely
   unfocusable at the moment it appeared (measured — visibility stayed `hidden`
   for two frames, and focus() on a hidden element is a no-op). Zero duration
   plus a delay in the hiding direction only means it shows instantly and still
   sticks around for the length of the fade out. */
/* The page holds still while the prompt is open. scrollbar-gutter reserves the
   classic scrollbar's space at ALL times, which is what makes the lock free of a
   jump: without it, taking the scrollbar away widens the content by ~15px on
   Windows and everything shifts sideways as the scrim comes up. It's a no-op
   where scrollbars are overlays (macOS, iOS, Android).
   overscroll-behavior is scoped to the locked state rather than left on `html`
   for the life of the page: on the root it also turns off pull-to-refresh on
   Android, which has nothing to do with this. */
html { scrollbar-gutter: stable; }
html.prompt-locked {
  overflow: hidden;
  overscroll-behavior: none;
}
.prompt-scrim {
  position: fixed;
  inset: 0;
  z-index: 110;
  background: rgba(255, 255, 255, 0.3);
  backdrop-filter: blur(30px);
  -webkit-backdrop-filter: blur(30px);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.32s ease, visibility 0s linear 0.32s;
}
.prompt-close {
  position: fixed;
  top: 32px;
  right: 32px;
  z-index: 120;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  padding: 0;
  background: #f0f0f0;
  /* Per Figma — lets the chip sit into the blurred page rather than on top of
     it, so it reads as part of the same surface. */
  mix-blend-mode: multiply;
  border: 0;
  border-radius: 999px;
  color: #0f0f0f;
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.32s ease, visibility 0s linear 0.32s, background 0.18s ease;
}
.prompt-close:hover { background: #e6e6e6; }
.prompt-close svg { display: block; width: 16px; height: 16px; }
/* Open state. Set on <body> rather than on the prompt so the scrim and the close
   button — which are siblings of it, not children — can key off the same flag. */
body.prompt-open .prompt-scrim,
body.prompt-open .prompt-close { opacity: 1; visibility: visible; transition-delay: 0s; }
body.prompt-open .cutdown-agent-thread { opacity: 1; visibility: visible; }
/* Over the scrim while open; back under the nav when it closes. */
body.prompt-open .prompt { z-index: 120; }

/* ── EMAIL GATE ──
   Sits between opening the prompt and being able to use it: the scrim comes up,
   and this asks for an email and company website before the composer is
   live. Per the EMAIL frame in the wireframe.

   ⚠️ FRONT END + /api/capsule/brand-theme. Submitting maps email + company
   onto create-brand-theme { email, domain } for this guest session.

   A fixed flex box rather than the design's absolute centring, so it stays clear
   of the docked composer at any viewport height: the padding reserves the room
   the composer occupies at the bottom, and the card centres in what's left. On
   the design's 810px-tall frame that lands within a couple of pixels of where
   it's drawn. overflow-y is the escape hatch for a window too short to hold it —
   the page itself can't scroll while the prompt is open. */
.prompt-gate {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 96px 20px 224px;   /* bottom clears the composer + its 64px dock gap */
  overflow-y: auto;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.32s ease, visibility 0s linear 0.32s;
}
.prompt-gate-inner {
  width: 430px;
  max-width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 32px;
}
.prompt-gate-lede {
  font-size: 20px;
  line-height: 26px;
  color: #707070;
  text-align: center;
  text-wrap: pretty;
}
.prompt-gate-fields {
  display: flex;
  flex-direction: column;
  gap: 16px;
  width: 100%;
}
/* Fields are the same vocabulary as the HubSpot forms on /demo-request and
   /lp/video-skills — 16px label, 24px radius, 20px padding, and the stroke
   fading in blue on hover and deeper on focus. Written out here rather than
   shared because those pages style HubSpot's own markup through .form-panel and
   there's no stylesheet to import; the values are theirs, and this is the only
   non-HubSpot form on the site. */
.prompt-gate-field { display: flex; flex-direction: column; gap: 8px; }
.prompt-gate-field label {
  font-size: 16px;
  line-height: 24px;
  color: #707070;
}
.prompt-gate-field .req { color: #2d67f8; margin-left: 2px; }
.prompt-gate-field input {
  width: 100%;
  height: 68px;
  padding: 20px;
  font-family: var(--font-body);
  font-size: 20px;
  line-height: 28px;
  color: #0f0f0f;
  background: #fff;
  border: 1.5px solid transparent;   /* transparent so the focus stroke can fade in */
  border-radius: 24px;
  outline: none;
  -webkit-appearance: none;
  appearance: none;
  transition: border-color 0.15s ease;
}
.prompt-gate-field input::placeholder { color: #b0b0b0; }
.prompt-gate-field input:hover { border-color: rgba(45, 103, 248, 0.4); }
/* Focus last so it wins on a field that's also hovered. */
.prompt-gate-field input:focus { border-color: rgba(45, 103, 248, 0.8); }
/* :user-invalid, not :invalid — it only fires once someone has actually typed
   something or tried to submit, so an empty field isn't red on arrival.
   aria-invalid covers the custom website check (novalidate skips native bubbles). */
.prompt-gate-field input:user-invalid,
.prompt-gate-field input[aria-invalid="true"] { border-color: rgba(211, 71, 71, 0.6); }
/* Autofill paints fields light blue; the inset shadow is the only reliable
   override. Same trick as the other forms. */
.prompt-gate-field input:-webkit-autofill,
.prompt-gate-field input:-webkit-autofill:hover,
.prompt-gate-field input:-webkit-autofill:focus {
  -webkit-box-shadow: 0 0 0 1000px #fff inset;
  -webkit-text-fill-color: #0f0f0f;
  caret-color: #0f0f0f;
}
/* The shared .cta/.cta-lime from nav.css, full width. */
.prompt-gate .cta { width: 100%; }
.prompt-gate-submit-loading { display: none; }
.prompt-gate .cta[aria-busy="true"] {
  opacity: 1;
  cursor: wait;
}
.prompt-gate .cta[aria-busy="true"] .prompt-gate-submit-label { display: none; }
.prompt-gate .cta[aria-busy="true"] .prompt-gate-submit-loading {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
.prompt-gate-spinner {
  width: 14px;
  height: 14px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: prompt-gate-spin 700ms linear infinite;
}
@keyframes prompt-gate-spin {
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .prompt-gate-spinner { animation: none; }
}
/* Validation and, once it's wired, submission failures. Same red as the other
   forms' field errors. [hidden] needs the display override because the flex
   parent would otherwise lay it out anyway. */
.prompt-gate-error {
  font-size: 14px;
  line-height: 20px;
  color: #d34747;
  text-align: center;
}
.prompt-gate-error[hidden] { display: none; }

/* While the gate is up the composer is visible but out of reach — dimmed to the
   50% the design draws it at, and inert so it can't be typed into or tabbed
   into behind the gate. */
body.prompt-open.prompt-gated .prompt-gate { opacity: 1; visibility: visible; transition-delay: 0s; }
body.prompt-open.prompt-gated .prompt {
  opacity: 0.5;
  pointer-events: none;
}
/* The thread has nothing in it until the composer works, and it would sit under
   the gate anyway. */
body.prompt-open.prompt-gated .cutdown-agent-thread { opacity: 0; visibility: hidden; }

@media (prefers-reduced-motion: reduce) {
  .prompt-scrim, .prompt-close, .prompt-gate { transition: none; }
}
@media (max-width: 768px) {
  .prompt-close { top: 20px; right: 20px; width: 44px; height: 44px; }
  .prompt-gate { padding: 80px 20px 180px; }
  .prompt-gate-inner { gap: 24px; }
  .prompt-gate-lede { font-size: 18px; line-height: 24px; }
  .prompt-gate-field input { height: 60px; padding: 16px 20px; font-size: 18px; }
}

/* Thread host before embed.css loads — opacity only; blur stays on .prompt-scrim. */
.cutdown-agent-thread {
  position: fixed;
  inset: 0;
  z-index: 115;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.32s ease, visibility 0.32s;
}
@media (prefers-reduced-motion: reduce) {
  .cutdown-agent-thread { transition: none; }
}
