/* blinksnip.com. Built on meltkit.com's system, a sister site: the same dark theme (true-neutral greys, very round
   cards, one light pill button), with BlinkSnip's blues in the headline and the app itself in the pictures. */
@font-face {
  font-family: "Geist";
  src: url("/assets/geist.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
}
/* The handwriting next to the hero button (Gamja Flower, SIL Open Font License, Latin subset). */
@font-face {
  font-family: "Gamja Flower";
  src: url("/assets/gamja-flower.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}

:root {
  --background: #0b0b0b;
  --foreground: #efefef;
  --card: #1f1f1f;
  --muted-foreground: rgba(255, 255, 255, 0.6);
  --faint-foreground: rgba(255, 255, 255, 0.6);
  --border: rgba(255, 255, 255, 0.08);
  --border-strong: rgba(255, 255, 255, 0.14);
  --primary: #f4f4f4;
  --primary-foreground: #0b0b0b;
  /* Trying square corners: 0 here makes every card, tile and window pointy at once. */
  --radius: 0;
  --radius-sm: 0;
  --nav-h: 64px;
  color-scheme: dark;
}

* {
  box-sizing: border-box;
}

/* Components set their own display; hidden has to win over it. */
[hidden] {
  display: none !important;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--background);
  color: var(--foreground);
  font: 16px/1.55 "Geist", ui-sans-serif, system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  text-wrap: pretty;
  overflow-x: clip;
}

a {
  color: inherit;
}

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

h1,
h2,
h3 {
  margin: 0;
  font-weight: 500;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

.wrap {
  width: 100%;
  max-width: 1080px;
  margin: 0 auto;
  padding: 0 24px;
}

/* ---- Subpage header and the footer ---- */
.wrap.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: var(--nav-h);
}
.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 500;
  text-decoration: none;
  letter-spacing: -0.01em;
}
.brand img {
  width: 28px;
  height: 28px;
}
.nav-links {
  display: flex;
  align-items: center;
  gap: 22px;
  font-size: 14px;
  color: var(--muted-foreground);
}
.nav-links a {
  text-decoration: none;
  transition: color 0.15s;
}
.nav-links a:hover {
  color: var(--foreground);
}
/* The Buy pill keeps its dark text on hover; the link hover above must not wash it out. */
.nav-links .btn:hover {
  color: var(--primary-foreground);
}

.footer {
  padding: 32px 0 44px;
  color: var(--muted-foreground);
  font-size: 13px;
}
.footer .wrap {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 32px;
  justify-content: space-between;
  align-items: center;
}
.footer nav {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}
.footer a {
  text-decoration: none;
}
.footer a:hover {
  color: var(--foreground);
}
body:not(.home) .footer {
  margin-top: 96px;
}

/* ---- Buttons ---- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  height: 44px;
  padding: 0 20px;
  border-radius: 999px;
  border: 1px solid transparent;
  font: inherit;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.15s, transform 0.1s, border-color 0.15s;
  white-space: nowrap;
}
.btn:active {
  transform: translateY(1px);
}
.btn-light,
.btn-primary {
  background: var(--primary);
  color: var(--primary-foreground);
}
.btn-light:hover,
.btn-primary:hover {
  background: #dedede;
}
.btn-dark {
  background: #0b0b0b;
  color: #fff;
}
.btn-dark:hover {
  background: #262626;
}
.btn-outline {
  border-color: var(--border-strong);
  background: rgba(255, 255, 255, 0.04);
  color: var(--foreground);
}
.btn-outline:hover {
  background: rgba(255, 255, 255, 0.08);
}
.btn-sm {
  height: 34px;
  padding: 0 14px;
  font-size: 13px;
}
.btn-lg {
  height: 49.5px;
  padding: 0 15px;
  font-size: 17.25px;
  letter-spacing: -0.02em;
  border-radius: 17px;
}

/* ---- Hero: icon, gradient headline, one line, one button ---- */
/* Figma: icon at 80, headline at 210, line at 356, button at 429, band at 559. */
.hero {
  padding: 80px 0 81px;
}
.hero-inner {
  display: grid;
  justify-items: center;
  text-align: center;
}
.hero-mark {
  position: relative;
  width: 73.5px;
  height: 73.5px;
  border-radius: 19px;
}
.hero-mark img {
  width: 100%;
  height: 100%;
  border-radius: inherit;
}
.hero h1 {
  margin-top: 56.5px;
  font-size: clamp(40px, 5vw, 64px);
  line-height: 1.016;
  letter-spacing: -0.03em;
}
/* Each line carries its own run of colour, from the app's selection blue: ice to cornflower on the first, sky through
   periwinkle to lilac on the second. */
.grad {
  display: inline-block;
  /* room for the descenders inside the clipped box, without changing the line's height */
  padding-bottom: 0.08em;
  margin-bottom: -0.08em;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.grad-a {
  background-image: linear-gradient(90deg, #e3f1ff 0%, #c2dcff 30%, #8ab4ff 62%, #7d97ff 100%);
}
.grad-b {
  background-image: linear-gradient(90deg, #c9f0ff 0%, #b5d6ff 34%, #c3b6ff 66%, #e1b6f4 100%);
}
.hero .sub {
  margin-top: 16px;
  max-width: 480px; /* two lines, broken by hand in the markup */
  text-wrap: initial;
}
.hero-cta {
  position: relative;
  margin-top: 25px;
}
/* The aside sits off the button's bottom right corner; the offsets are the Figma frame's. On a narrow screen it would
   run off the right edge, so there the arrow and the label slide left together, the label keeping the page's 24px
   from the edge (the label ends 255px right of the button's left edge; the button is 168px wide and centred). */
.note {
  position: absolute;
  left: min(0px, 50vw - 195px);
  top: 0;
  pointer-events: none;
}
.note-arrow {
  position: absolute;
  left: 158px;
  top: 59px;
  width: 65px;
  max-width: none; /* the wrapper has no width of its own, so the global image cap would shrink it to nothing */
  height: 23px;
}
.note-text {
  position: absolute;
  left: 206px;
  top: 39px;
  font: 16px/1.5 "Gamja Flower", "Segoe Print", cursive;
  letter-spacing: -0.02em;
  color: rgba(255, 255, 255, 0.5);
  white-space: nowrap;
  transform: rotate(12deg);
  transform-origin: left center;
}

.sub {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 16px;
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.5;
  max-width: 360px;
  text-wrap: balance;
}

/* ---- Band: a blurred live look, full width, with the app window on it ---- */
/* 720px tall at the 1280px design width, and the same share of the width below it. */
/* The band is a card in the same column as the cards below (.wrap), not a full-bleed strip: the live look shows
   around the picture, inside the cards' corners. */
.band {
  position: relative;
  width: min(1032px, 100% - 48px);
  margin: 0 auto;
  padding: 37px; /* the same inset as the cards' text (.quote), so the picture sits on their grid */
  display: grid;
  place-items: center;
  overflow: hidden;
  isolation: isolate;
  border-radius: var(--radius);
  background: #b8dcfb;
}
.band-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
}
.band .window {
  margin: 0; /* a figure's own margins would make the band's padding uneven */
  width: 100%;
  background: #f4f4f4;
  box-shadow: none;
}
/* The product's screenshots keep their round corners whatever the cards do: a square window frame looks wrong. */
.window {
  border-radius: 19px;
  overflow: hidden;
  background: #171717;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08), 0 30px 80px -24px rgba(0, 0, 0, 0.45);
}
.window img {
  width: 100%;
}

/* ---- Sections ---- */
.section {
  padding: 80px 0 0;
}
.head {
  text-align: center;
  display: grid;
  justify-items: center;
  gap: 16px;
  margin-bottom: 49px;
}
.section h2 {
  font-size: clamp(34px, 3.75vw, 48px);
  line-height: 1;
  letter-spacing: -0.02em;
  color: #f4f4f4;
}

/* ---- Cards: 411px tall, 8px apart, the copy 293px down ---- */
.cards {
  display: grid;
  gap: 8px;
}
@media (min-width: 720px) {
  .cards {
    grid-template-columns: repeat(3, 1fr);
  }
}
/* --u is one design pixel: 1px while a card is at least as wide as in the Figma frame (263px inside the
   padding), a fraction of that on narrower cards, so the art and the vertical rhythm shrink with the card. The
   grid is the container; a card's inner width is the grid's width less the padding (stacked) or a third of it. */
.cards {
  container-type: inline-size;
}
.card {
  --u: min(1px, calc((100cqw - 72px) / 263));
  background: var(--card);
  border-radius: var(--radius);
  padding: calc(59 * var(--u)) 36px 28px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
}
@media (min-width: 720px) {
  .card {
    --u: min(1px, calc(((100cqw - 16px) / 3 - 72px) / 263));
  }
}
/* With the title and text boxes this adds up to the 411px card of the frame, without a fixed min-height. */
/* The title hangs under the art, not at the bottom, so all three line up when one text wraps a line more. */
.card h3 {
  font-size: 14px;
  letter-spacing: -0.02em;
  color: #eaeaea;
  padding-top: calc(37 * var(--u));
}
.card p {
  margin: 6px 0 0;
  color: var(--muted-foreground);
  font-size: 14px;
  letter-spacing: -0.02em;
  max-width: 221px;
}
.card-art {
  position: relative;
  width: 100%;
  height: 194px;
}
/* Card art, from the Figma frame (the art box starts 59px down, the title 293px down), in --u from .card.
   Everything is placed from the card's centre line so the three columns can share one grid. */
.card-art {
  height: calc(194 * var(--u));
}
.card-art img {
  position: absolute;
  object-fit: cover;
}
/* Four looks as circles, laid out like the points of a compass. */
.circles img {
  width: calc(62 * var(--u));
  height: calc(62 * var(--u));
  border-radius: 50%;
}
.circles img:nth-child(1) { left: calc(50% - 31 * var(--u)); top: calc(6 * var(--u)); }
.circles img:nth-child(2) { left: calc(50% - 92 * var(--u)); top: calc(62.5 * var(--u)); }
.circles img:nth-child(3) { left: calc(50% + 30 * var(--u)); top: calc(62.5 * var(--u)); }
.circles img:nth-child(4) { left: calc(50% - 31 * var(--u)); top: calc(121 * var(--u)); }
/* Three stills: a big one in the middle, two small ones tucked behind its top right and in front of its bottom left. */
.tile-heat { width: calc(157 * var(--u)); height: calc(157 * var(--u)); border-radius: calc(44 * var(--u)); left: calc(50% - 78.5 * var(--u)); top: calc(34.5 * var(--u)); }
.tile-thermal { width: calc(62 * var(--u)); height: calc(62 * var(--u)); border-radius: calc(17.5 * var(--u)); left: calc(50% + 35 * var(--u)); top: calc(6 * var(--u)); }
.tile-mosaic { width: calc(63 * var(--u)); height: calc(63 * var(--u)); border-radius: calc(17.5 * var(--u)); left: calc(50% - 125.5 * var(--u)); top: calc(108.5 * var(--u)); }
/* One picture, centred: the card art BlinkSnip uses (scripts in website/art/ draw them from the app). */
.single img { width: calc(194 * var(--u)); height: calc(194 * var(--u)); left: calc(50% - 97 * var(--u)); top: 0; }
/* One look cut into a ring. */
.ring img { width: calc(192 * var(--u)); height: calc(192 * var(--u)); left: calc(50% - 96 * var(--u)); top: calc(12 * var(--u)); }

/* The video is the whole card: its own dark margins around the app window are the padding. */
/* .card.card-wide so the phone-width .card padding below cannot put a frame around the video. It sits one grid
   gap (8px) below the other cards at every width; the Figma frame had 13.5px here, which read as a mistake. */
.card.card-wide {
  margin: 8px 0 0;
  min-height: 0;
  padding: 0;
  overflow: hidden;
}
.card-wide .shot {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius);
  background: #171717;
}

/* ---- Export tiles ---- */
.tiles {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 8px; /* the same gap as the cards above */
  grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 720px) {
  .tiles {
    grid-template-columns: repeat(3, 1fr);
  }
}
.tiles li {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background: var(--card);
  border-radius: var(--radius);
  padding: 34.5px 37px 37px;
  display: flex;
  flex-direction: column;
  min-height: 276.5px;
}
.tiles strong {
  font-size: 32px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.02em;
  color: #eaeaea;
}
.tiles span {
  margin-top: auto;
  font-size: 14px;
  letter-spacing: -0.02em;
  color: var(--faint-foreground);
}

/* ---- Pricing: white card on a live look, the app beside it ---- */
#pricing .head {
  margin-bottom: 60px;
}
.price-band {
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  isolation: isolate;
  background: #b9a9e6;
  padding: 29px 30px 31px;
  display: grid;
  gap: 30px; /* the same as the padding */
  align-items: start;
}
@media (min-width: 820px) {
  .price-band {
    grid-template-columns: 339px 1fr;
    min-height: 480px; /* a minimum, not a fixed height: the card must never be clipped when it grows */
  }
}
.tiers {
  display: grid;
}
.tier {
  border-radius: 22px; /* the same as the screenshot */
  background: #fff;
  color: #1f1f1f;
  padding: 34.5px 37px 37px; /* the same inner padding as the export tiles */
  display: flex;
  flex-direction: column;
  gap: 0;
}
/* Flex so the space in the markup does not count: at 80px that space alone is 20px wide. */
.tier .price {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 80px;
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1;
}
.tier .price small {
  font-size: 14px;
  font-weight: 400;
  letter-spacing: -0.02em;
  color: rgba(11, 11, 11, 0.5);
}
.tier .note {
  font-size: 13px;
  letter-spacing: -0.02em;
  color: #777;
}
/* Figma: the rule 16px under the price, the first check 20px under the rule, rows 48px apart. */
.includes {
  margin: 15.5px 0 0;
  padding: 19px 0 0;
  border-top: 1px solid rgba(11, 11, 11, 0.12);
  list-style: none;
  display: grid;
  gap: 24px;
  font-size: 16px;
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.5;
  color: rgba(31, 31, 31, 0.6);
}
.includes li {
  display: flex;
  align-items: center;
  gap: 14.5px;
}
/* The check from the design: a 1px circle and a 1px tick. */
.includes li::before {
  content: "";
  flex: none;
  width: 23px;
  height: 23px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22.8613 22.8613' fill='none'%3E%3Ccircle cx='11.4307' cy='11.4307' r='10.9307' stroke='%230B0B0B'/%3E%3Cpath d='M6.65039 10.9144L10.1816 14.4457L16.2113 8.41602' stroke='black'/%3E%3C/svg%3E") center / contain no-repeat;
}
.tier .btn {
  margin-top: 35px;
  width: 100%;
}
/* The window runs off the band's bottom and right edge, like a crop. */
.price-shot {
  margin: 0 -30px -31px 0;
  width: calc(100% + 30px);
  border-radius: 22px 0 0 0;
  overflow: hidden;
  background: #f4f4f4;
}
/* Beside the card it keeps the design's size and runs off the band's right and bottom edge. */
@media (min-width: 820px) {
  .price-shot {
    /* Out of the grid flow, so the band is as tall as the card and the window just runs off its edges. */
    position: absolute;
    top: 29px;
    left: 399px; /* the band's padding, the card column and the gap */
    margin: 0;
    width: 1032.5px;
    border-radius: 22px;
  }
}
.price-shot img {
  width: 100%;
}
/* Below the card it keeps the same half-scale as beside it, so the sidebar stays readable: the window is
   cropped by the figure instead of shrunk to the band. */
@media (max-width: 819.98px) {
  .price-shot {
    height: clamp(300px, 55vw, 450px);
  }
  .price-shot img {
    width: 1032.5px;
    max-width: none;
  }
}

/* ---- FAQ ---- */
/* One list the width of the column, under the centred heading: a bordered card of rows, a hairline between them. */
.faq {
  display: grid;
  border: 1px solid var(--border);
  background: var(--card);
}
.faq details {
  border-bottom: 1px solid var(--border);
}
.faq details:last-child {
  border-bottom: 0;
}
.faq summary {
  cursor: pointer;
  list-style: none;
  padding: 24px 72px 24px 36px;
  font-weight: 500;
  position: relative;
}
.faq summary::-webkit-details-marker {
  display: none;
}
.faq summary::after {
  content: "";
  position: absolute;
  right: 36px;
  top: 50%;
  width: 8px;
  height: 8px;
  border-right: 1.5px solid var(--muted-foreground);
  border-bottom: 1.5px solid var(--muted-foreground);
  transform: translateY(-70%) rotate(45deg);
  transition: transform 0.2s;
}
.faq details[open] summary::after {
  transform: translateY(-30%) rotate(225deg);
}
/* Links in running text (the answers here, and the support, privacy and thank-you pages): underlined in the text's
   own colour, and brighter under the pointer. */
.faq p a,
.page p a,
.page li a:not(.btn) {
  text-underline-offset: 3px;
  transition: color 0.15s;
}
.faq p a:hover,
.page p a:hover,
.page li a:not(.btn):hover {
  color: var(--foreground);
}
.faq details p {
  margin: 0;
  padding: 0 36px 24px;
  color: var(--muted-foreground);
  max-width: 44rem;
}

/* ---- Outro: a rounded dark panel on a live look, with the call to action, the footer and the name inside ---- */
.outro {
  position: relative;
  margin-top: 80px; /* the same gap as between the other sections */
  padding-bottom: 24px;
  overflow: hidden;
  isolation: isolate;
}
/* The look runs behind the lower part of the panel and below it, so it shows at the sides and the bottom. */
.outro .band-canvas {
  top: 40%;
  height: 60%;
}
.panel {
  /* The side and bottom padding have names: the wordmark's play button is placed by them. */
  --panel-x: clamp(24px, 5vw, 64px);
  --panel-b: clamp(28px, 4vw, 44px);
  position: relative;
  isolation: isolate;
  border-radius: var(--radius);
  padding: clamp(64px, 8vw, 110px) var(--panel-x) var(--panel-b);
  text-align: center;
}
.outro h2 {
  font-size: clamp(34px, 4.2vw, 46px);
  line-height: 1.05;
}
.cta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: center;
}
/* The dark fill is a layer under the content: an SVG rect masked so the name is cut out of it (the mask is in
   the page). Safari does not apply a url(#mask) to an HTML element, so the fill is SVG as well. */
.panel-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  border-radius: inherit;
  overflow: hidden;
  pointer-events: none;
}
#panel-bg-rect {
  fill: var(--card);
}
/* Headline, one line, one button: the same rhythm as the hero. */
.panel .sub {
  margin: 16px auto 0;
}
.outro .cta {
  margin-top: 25px;
}
/* The footer inside the panel: the brand and a line about it, then two short columns of links. */
.panel-footer {
  margin-top: clamp(64px, 8vw, 100px);
  padding-top: 40px;
  border-top: 1px solid var(--border);
  display: grid;
  gap: 32px;
  text-align: left;
  font-size: 14px;
  letter-spacing: -0.02em;
}
@media (min-width: 720px) {
  .panel-footer {
    grid-template-columns: 1.6fr 1fr 1fr;
    gap: 40px;
  }
}
.panel-brand p {
  margin: 16px 0 0;
  max-width: 300px;
  color: var(--muted-foreground);
}
.panel-footer nav {
  display: grid;
  gap: 12px;
  align-content: start;
  justify-items: start;
}
.panel-footer h4 {
  margin: 0 0 4px;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--muted-foreground);
}
.panel-footer a,
.panel-legal a {
  text-decoration: none;
  color: var(--foreground);
  transition: color 0.15s;
}
.panel-footer a:hover,
.panel-legal a:hover {
  color: var(--muted-foreground);
}
.panel-legal {
  margin-top: 40px;
  padding-top: 24px;
  border-top: 1px solid var(--border);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px 24px;
  font-size: 13px;
  color: var(--muted-foreground);
  text-align: left;
}
/* As wide as the content column (.wrap, like the cards above): site.js measures the ink and sets the font size and the left shift to match. */
.wordmark {
  margin-top: clamp(32px, 5vw, 56px);
  font-size: clamp(88px, 18.5vw, 280px);
  font-weight: 500;
  letter-spacing: -0.06em;
  line-height: 0.8;
  user-select: none;
  white-space: nowrap;
  text-align: left;
  /* This div only holds the space and is measured by site.js; the letters themselves are cut out of the panel.
     Its line is shorter than its type, so the letters' box reaches up over the row above: it must not take the
     pointer there (it kept the credit's link from being hovered or clicked). */
  pointer-events: none;
  color: transparent;
  margin-right: -0.15em;
}

/* ---- 404: the hero's shape, centred in whatever is left of the viewport ---- */
body.lost {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
.lost-hero {
  flex: 1;
  display: grid;
  place-items: center;
}
.lost-hero h1 {
  margin-top: 0; /* the hero rule spaces its headline from the app icon; there is no icon here */
  font-size: clamp(40px, 5vw, 64px);
  line-height: 1.016;
  letter-spacing: -0.03em;
}
.lost-code {
  margin: 0 0 20px;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--muted-foreground);
}
.lost-hero .sub {
  margin-top: 16px;
  max-width: 326px;
}
.lost-hero .btn {
  margin-top: 25px;
}
/* The footer-only panel (404): no call to action above the links, so no rule and less room at the top. */
.outro-footer .panel {
  padding-top: clamp(28px, 4vw, 44px);
}
.outro-footer .panel-footer {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}
.outro-footer .band-canvas {
  top: 25%;
  height: 75%;
}

/* ---- Text pages: privacy, support, thank you ---- */
.page {
  max-width: 720px;
  margin: 48px auto 0;
}
.page h1 {
  font-size: clamp(32px, 5vw, 48px);
  line-height: 1.1;
}
.page .meta {
  margin-top: 8px;
  color: var(--muted-foreground);
  font-size: 14px;
}
.page h2 {
  margin: 40px 0 0;
  font-size: 20px;
}
.page p,
.page li {
  color: #c9c9c9;
}
.page ul,
.page ol {
  padding-left: 22px;
}
.page .steps {
  margin-top: 32px;
  display: grid;
  gap: 12px;
  padding: 0;
  list-style: none;
  counter-reset: step;
}
.steps li {
  counter-increment: step;
  border-radius: 18px;
  background: var(--card);
  padding: 22px 22px 22px 64px;
  position: relative;
  color: var(--foreground);
}
.steps li::before {
  content: counter(step);
  position: absolute;
  left: 22px;
  top: 21px;
  width: 26px;
  height: 26px;
  border-radius: 999px;
  display: grid;
  place-items: center;
  background: var(--primary);
  color: var(--primary-foreground);
  font-size: 14px;
  font-weight: 600;
}
.steps p {
  margin: 4px 0 0;
  color: var(--muted-foreground);
}
.steps .btn {
  margin-top: 14px;
  margin-right: 8px;
}

@media (max-width: 560px) {
  .wrap {
    padding: 0 16px;
  }
  :root {
    --radius: 28px;
  }
  .card {
    min-height: 0;
    padding: 36px 24px 32px;
  }
  .card h3 {
    padding-top: 28px;
  }
  .band {
    width: calc(100% - 32px);
    padding: 16px;
    border-radius: var(--radius-sm);
  }
  .band .window {
    border-radius: 12px;
  }
  .tiles li {
    min-height: 170px;
    padding: 24px;
  }
  .tiles strong {
    font-size: 24px;
  }
  .price-band {
    padding: 14px;
    gap: 14px; /* the same as the padding at this width */
  }
  /* The same corners as the screenshot; the same inner padding as the tiles at this width. */
  .tier {
    border-radius: 22px; /* the same as the screenshot */
    padding: 24px;
  }
  .price-shot {
    width: calc(100% + 14px);
    margin-bottom: -14px;
    border-radius: 22px 0 0 0;
  }
  .hero {
    padding: 56px 0 56px;
  }
  .card {
    padding-top: 40px;
  }
  .tier .price {
    font-size: 56px;
  }
}

@media (prefers-reduced-motion: reduce) {
  * {
    transition: none !important;
    animation: none !important;
  }
  html {
    scroll-behavior: auto;
  }
}

/* ---- BlinkSnip: a buy button with no checkout behind it yet (site.js) ---- */
.btn.is-soon {
  opacity: 0.55;
  cursor: default;
  pointer-events: none;
}

/* ---- BlinkSnip: the pains, in the user's own words, as three quote cards (the cards' size and corners) ---- */
.quotes {
  display: grid;
  gap: 8px;
}
@media (min-width: 720px) {
  .quotes {
    grid-template-columns: repeat(3, 1fr);
  }
}
.quote {
  margin: 0;
  background: var(--card);
  border-radius: var(--radius);
  padding: 34.5px 37px 37px;
  display: flex;
  flex-direction: column;
  min-height: 260px;
}
.quote blockquote {
  margin: 0;
  font-size: 22px;
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: -0.02em;
  color: #eaeaea;
  text-wrap: balance;
}
/* An open quote mark above the words, faint, as on a pull quote. */
.quote blockquote::before {
  content: "\201C";
  display: block;
  height: 30px;
  font-size: 56px;
  line-height: 1;
  color: rgba(255, 255, 255, 0.2);
}
.quote figcaption {
  margin-top: auto;
  padding-top: 28px;
  font-size: 14px;
  letter-spacing: -0.02em;
  color: var(--faint-foreground);
}

/* ---- BlinkSnip: the old way beside BlinkSnip. The old way is a dark card; BlinkSnip is white, like the price card ---- */
.compare {
  display: grid;
  gap: 8px;
}
@media (min-width: 720px) {
  .compare {
    grid-template-columns: 1fr 1fr;
  }
}
.side {
  background: var(--card);
  border-radius: var(--radius);
  padding: 34.5px 37px 37px;
}
.side h3 {
  font-size: 22px;
  letter-spacing: -0.02em;
  color: #eaeaea;
}
.side .count {
  margin: 4px 0 0;
  font-size: 14px;
  letter-spacing: -0.02em;
  color: var(--faint-foreground);
}
.side ol {
  margin: 28px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 14px;
  counter-reset: step;
}
.side li {
  counter-increment: step;
  display: flex;
  align-items: center;
  gap: 14px;
  font-size: 16px;
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.4;
  color: var(--muted-foreground);
}
/* Numbered like the thank-you page's steps: an outline here, filled on BlinkSnip's side. */
.side li::before {
  content: counter(step);
  flex: none;
  width: 26px;
  height: 26px;
  border-radius: 999px;
  display: grid;
  place-items: center;
  border: 1px solid var(--border-strong);
  font-size: 13px;
  font-weight: 600;
}
.side.new {
  background: #fff;
}
.side.new h3,
.side.new li {
  color: #1f1f1f;
}
.side.new .count {
  color: rgba(11, 11, 11, 0.5);
}
.side.new li::before {
  border-color: transparent;
  background: #0b0b0b;
  color: #fff;
}
.side .after {
  margin: 28px 0 0;
  padding-top: 19px;
  border-top: 1px solid rgba(11, 11, 11, 0.12);
  font-size: 14px;
  letter-spacing: -0.02em;
  color: rgba(11, 11, 11, 0.5);
}

@media (max-width: 560px) {
  .quote,
  .side {
    padding: 24px;
  }
  .quote {
    min-height: 0;
  }
  .quote blockquote {
    font-size: 20px;
  }
}

/* The two sides stand as tall as each other; BlinkSnip's closing line sits at the foot of its side. */
.side {
  display: flex;
  flex-direction: column;
}
.side .after {
  margin-top: auto;
}
/* Room above the line even when the list fills the side. */
.side.new ol {
  margin-bottom: 28px;
}

/* ---- BlinkSnip: where it works, as a row of pills rather than tiles: names need no room of their own ---- */
.apps {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
}
.apps li {
  padding: 16px 26px;
  border-radius: 999px;
  background: var(--card);
  font-size: 20px;
  font-weight: 500;
  letter-spacing: -0.02em;
  color: #eaeaea;
}
/* The last one is everything else: an outline, quieter than the names. */
.apps li.any {
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--border-strong);
  color: var(--muted-foreground);
}
@media (max-width: 560px) {
  .apps li {
    padding: 12px 20px;
    font-size: 17px;
  }
}

/* ---- Light theme: the same tokens as the app's light mode (white, true-neutral greys), on <html class="light">. ----
   The cards and headings above use fixed dark-theme colours, so each gets its light counterpart here. */
html.light {
  --background: #f4f4f4; /* the page and the cards swapped: grey page, white cards */
  --foreground: #1c1c1c;
  --card: #ffffff;
  --muted-foreground: rgba(0, 0, 0, 0.6);
  --faint-foreground: rgba(0, 0, 0, 0.55);
  --border: rgba(0, 0, 0, 0.09);
  --border-strong: rgba(0, 0, 0, 0.16);
  --primary: #1c1c1c;
  --primary-foreground: #fafafa;
  color-scheme: light;
}
html.light .btn-primary:hover { background: #333; }
html.light .btn-outline { background: rgba(0, 0, 0, 0.04); }
html.light .btn-outline:hover { background: rgba(0, 0, 0, 0.08); }
html.light .section h2, html.light .card h3, html.light .tiles strong, html.light .quote blockquote, html.light .side h3, html.light .apps li { color: var(--foreground); }
html.light .page li { color: #444; }
html.light .window, html.light .card-wide .shot { background: #e9e9e9; }
html.light .side.new { background: #1c1c1c; }
html.light .side.new li { color: #efefef; }
html.light .side.new li::before { background: #fafafa; color: #1c1c1c; }
/* On white the headline's gradient is grey: dark at the start of the first line, lighter by the end of the second. */
html.light .grad-a { background-image: linear-gradient(90deg, #161616 0%, #2a2a2a 45%, #4a4a4a 100%); }
html.light .grad-b { background-image: linear-gradient(90deg, #3a3a3a 0%, #5c5c5c 50%, #7a7a7a 100%); }
/* The handwritten "One time" and its arrow are white at half strength for the dark page; on white they go dark. */
html.light .note-text { color: rgba(0, 0, 0, 0.55); }
html.light .note-arrow { filter: invert(1); }

/* ---- Guides: the content column's two edges drawn as dashed lines down the whole page, behind everything, and a
   small square wherever the band's corners sit on them, as on a blueprint. ---- */
body { position: relative; }
.guides {
  position: absolute;
  z-index: -1;
  top: 0;
  bottom: 0;
  left: 50%;
  width: min(1032px, 100% - 48px);
  transform: translateX(-50%);
  border-left: 1px dashed var(--border-strong);
  border-right: 1px dashed var(--border-strong);
  pointer-events: none;
}
.band { overflow: visible; } /* the markers straddle its edges; the canvas fills its box exactly, so nothing else spills */
.corner {
  position: absolute;
  z-index: 2;
  width: 7px;
  height: 7px;
  background: #3b82f6;
}
.corner.tl { left: -4px; top: -4px; }
.corner.tr { right: -4px; top: -4px; }
.corner.bl { left: -4px; bottom: -4px; }
.corner.br { right: -4px; bottom: -4px; }
/* The corners are the highlighter's own handles (desktop/overlay.css .corner): a 10px white dot with its hairline and
   shadow, centred on the corner. The guides' dashes are drawn, not bordered: 10 on, 8 off, which a dashed border
   cannot be told to do. */
.corner { width: 10px; height: 10px; border-radius: 50%; background: #fff; box-shadow: 0 0 0 .5px rgba(0, 0, 0, .3), 0 1px 3px rgba(0, 0, 0, .35); }
.corner.tl { left: -5px; top: -5px; }
.corner.tr { right: -5px; top: -5px; }
.corner.bl { left: -5px; bottom: -5px; }
.corner.br { right: -5px; bottom: -5px; }
.guides {
  border: 0;
  background:
    repeating-linear-gradient(to bottom, var(--border-strong) 0 10px, transparent 10px 18px) left top / 1px 100% no-repeat,
    repeating-linear-gradient(to bottom, var(--border-strong) 0 10px, transparent 10px 18px) right top / 1px 100% no-repeat;
}
/* The pricing band and the footer carry the handles too; their canvases fill their boxes exactly, so overflow may show. */
.price-band { overflow: visible; }
/* A frame for handles around a band that must clip its own overflow: the frame is the band's box, the handles its corners. */
.framed { position: relative; }
.price-band { overflow: hidden; }
/* The outro clips its overflow and its panel starts at its top: 6px of room above the panel keeps the top handles whole. */
.outro { margin-top: 74px; padding-top: 6px; }
/* On a phone the column's gutter is 16px (.wrap, .band): the guides follow it. */
@media (max-width: 560px) {
  .guides { width: calc(100% - 32px); }
}
/* The phone breakpoint above rounds the cards again (28px): square there too, as on the desktop. */
@media (max-width: 560px) {
  :root { --radius: 0; }
}

/* The quote cards, taller, with a live MeltKit look (Prism Halo, Poured Glass, Pool) as a strip under the words:
   the canvas is the last block of the card, bleeding to its edges. */
.quote { overflow: hidden; min-height: 460px; }
.quote .band-canvas { position: relative; inset: auto; order: 3; width: calc(100% + 74px); height: 200px; margin: 28px -37px -37px; z-index: 0; }
/* The guides run over the cards, not behind them; the handles (z 2) stay on top, and clicks pass through. */
.guides { z-index: 1; }
/* The bands that carry handles sit above the guides, so a handle covers the line where they meet. */
.band, .framed, .panel { z-index: 2; }
/* The footer panel's side padding is the bands' 37px, not its own clamp: the same grid as every other card. */
.panel { --panel-x: 37px; }

/* ---- The quote cards' illustrations: small pieces of UI over the look strip, animated in a slow loop. They use the
   app's own vocabulary (white panels, 10px controls, Lucide icons) and read as a still when motion is reduced. ---- */
.quote .art { position: absolute; left: 0; right: 0; bottom: 0; height: 200px; z-index: 1; display: grid; place-items: center; pointer-events: none; color: #1c1c1c; }
.quote .art svg { width: 14px; height: 14px; }
.mini, .steps-strip { display: flex; align-items: center; gap: 8px; padding: 8px; background: #fff; border: 1px solid rgba(0, 0, 0, 0.08); border-radius: 14px; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06), 0 16px 40px -16px rgba(0, 0, 0, 0.35); }
/* 1. The hunt: a cursor tries each button, resting on it a moment, and starts over. */
.art-hunt { position: relative; }
.mini-field { display: flex; align-items: center; gap: 6px; height: 28px; min-width: 92px; padding: 0 10px; border-radius: 10px; background: rgba(0, 0, 0, 0.05); font-size: 12px; color: rgba(0, 0, 0, 0.55); }
.mini-btn { display: grid; place-items: center; width: 28px; height: 28px; border-radius: 10px; color: rgba(0, 0, 0, 0.6); animation: 6s infinite; }
.b1 { animation-name: hover-1; } .b2 { animation-name: hover-2; } .b3 { animation-name: hover-3; }
@keyframes hover-1 { 0%, 20% { background: transparent; } 24%, 36% { background: rgba(0, 0, 0, 0.07); color: #1c1c1c; } 40%, 100% { background: transparent; } }
@keyframes hover-2 { 0%, 48% { background: transparent; } 52%, 64% { background: rgba(0, 0, 0, 0.07); color: #1c1c1c; } 68%, 100% { background: transparent; } }
@keyframes hover-3 { 0%, 76% { background: transparent; } 80%, 92% { background: rgba(0, 0, 0, 0.07); color: #1c1c1c; } 96%, 100% { background: transparent; } }
.art-hunt .cursor { position: absolute; left: 50%; top: 50%; width: 18px; height: 18px; fill: #fff; stroke: #1c1c1c; stroke-width: 1.5; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.35)); animation: hunt 6s cubic-bezier(0.4, 0, 0.2, 1) infinite; }
@keyframes hunt { 0%, 8% { transform: translate(-40px, 44px); } 22%, 36% { transform: translate(12px, 2px); } 50%, 64% { transform: translate(48px, 2px); } 78%, 92% { transform: translate(84px, 2px); } 100% { transform: translate(-40px, 44px); } }
/* 2. The steps: each lights up in turn, the line between filling ahead of the next. */
.steps-strip { gap: 0; padding: 10px 12px; }
.step { display: grid; place-items: center; width: 34px; height: 34px; border-radius: 10px; background: rgba(0, 0, 0, 0.05); color: rgba(0, 0, 0, 0.55); animation: step-on 6s infinite; }
.step svg { width: 16px; height: 16px; }
.s2 { animation-delay: 1.3s; } .s3 { animation-delay: 2.6s; } .s4 { animation-delay: 3.9s; }
@keyframes step-on { 0% { background: rgba(0, 0, 0, 0.05); color: rgba(0, 0, 0, 0.55); transform: none; } 5% { background: #1c1c1c; color: #fff; transform: scale(1.08); } 20% { background: #1c1c1c; color: #fff; transform: none; } 26%, 100% { background: rgba(0, 0, 0, 0.05); color: rgba(0, 0, 0, 0.55); transform: none; } }
.step-line { position: relative; width: 22px; height: 2px; overflow: hidden; background: rgba(0, 0, 0, 0.1); }
.step-line::after { content: ""; position: absolute; inset: 0; background: #1c1c1c; transform: scaleX(0); transform-origin: left; animation: line-fill 6s infinite; }
.l1::after { animation-delay: 0.8s; } .l2::after { animation-delay: 2.1s; } .l3::after { animation-delay: 3.4s; }
@keyframes line-fill { 0% { transform: scaleX(0); } 8% { transform: scaleX(1); } 58% { transform: scaleX(1); } 64%, 100% { transform: scaleX(0); } }
/* 3. The pile: three messages arrive one after another, then the thread clears. */
.art-stack { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 8px; padding-left: 37px; }
.bubble { max-width: 210px; padding: 8px 12px; border-radius: 14px; background: #1c1c1c; color: #fff; font-size: 12px; line-height: 1.4; opacity: 0; transform: translateY(8px) scale(0.96); animation: 7s cubic-bezier(0.2, 0, 0, 1) infinite; box-shadow: 0 10px 30px -14px rgba(0, 0, 0, 0.45); }
.m1 { animation-name: pop-1; } .m2 { animation-name: pop-2; } .m3 { animation-name: pop-3; }
@keyframes pop-1 { 0%, 4% { opacity: 0; transform: translateY(8px) scale(0.96); } 10%, 84% { opacity: 1; transform: none; } 92%, 100% { opacity: 0; transform: translateY(-4px); } }
@keyframes pop-2 { 0%, 26% { opacity: 0; transform: translateY(8px) scale(0.96); } 32%, 84% { opacity: 1; transform: none; } 92%, 100% { opacity: 0; transform: translateY(-4px); } }
@keyframes pop-3 { 0%, 48% { opacity: 0; transform: translateY(8px) scale(0.96); } 54%, 84% { opacity: 1; transform: none; } 92%, 100% { opacity: 0; transform: translateY(-4px); } }
/* Without motion each reads as a finished still: the cursor on a button, the last step lit, all three messages in. */
@media (prefers-reduced-motion: reduce) {
  .art-hunt .cursor { transform: translate(48px, 2px); }
  .b2 { background: rgba(0, 0, 0, 0.07); color: #1c1c1c; }
  .s4 { background: #1c1c1c; color: #fff; }
  .step-line::after { transform: none; }
  .bubble { opacity: 1; transform: none; }
}
.quote { position: relative; } /* the illustrations anchor to the card */
/* The steps' "on" state: a deeper grey tile with a dark icon, no scaling (a scaled 34px box lands between pixels and
   shimmers), and no dark fill to tween through. */
.step { animation-name: step-on-grey; }
@keyframes step-on-grey { 0%, 2% { background: rgba(0, 0, 0, 0.05); color: rgba(0, 0, 0, 0.55); } 6%, 20% { background: rgba(0, 0, 0, 0.14); color: #1c1c1c; } 25%, 100% { background: rgba(0, 0, 0, 0.05); color: rgba(0, 0, 0, 0.55); } }
.step-line::after { background: rgba(0, 0, 0, 0.4); }
@media (prefers-reduced-motion: reduce) {
  .s4 { background: rgba(0, 0, 0, 0.14); color: #1c1c1c; }
}
/* One 6s timeline for the whole strip: a step lights for about 1.3s, the line before it fills just ahead of it, and
   at the end the lines empty together before the first step lights again. */
.step, .step-line::after { animation-delay: 0s; }
.s1 { animation-name: step-1; } .s2 { animation-name: step-2; } .s3 { animation-name: step-3; } .s4 { animation-name: step-4; }
@keyframes step-1 { 0%, 1% { background: rgba(0, 0, 0, 0.05); color: rgba(0, 0, 0, 0.55); } 3%, 20% { background: rgba(0, 0, 0, 0.14); color: #1c1c1c; } 23%, 100% { background: rgba(0, 0, 0, 0.05); color: rgba(0, 0, 0, 0.55); } }
@keyframes step-2 { 0%, 21.5% { background: rgba(0, 0, 0, 0.05); color: rgba(0, 0, 0, 0.55); } 23.5%, 42% { background: rgba(0, 0, 0, 0.14); color: #1c1c1c; } 45%, 100% { background: rgba(0, 0, 0, 0.05); color: rgba(0, 0, 0, 0.55); } }
@keyframes step-3 { 0%, 43.5% { background: rgba(0, 0, 0, 0.05); color: rgba(0, 0, 0, 0.55); } 45.5%, 63% { background: rgba(0, 0, 0, 0.14); color: #1c1c1c; } 66%, 100% { background: rgba(0, 0, 0, 0.05); color: rgba(0, 0, 0, 0.55); } }
@keyframes step-4 { 0%, 65% { background: rgba(0, 0, 0, 0.05); color: rgba(0, 0, 0, 0.55); } 67%, 86% { background: rgba(0, 0, 0, 0.14); color: #1c1c1c; } 89%, 100% { background: rgba(0, 0, 0, 0.05); color: rgba(0, 0, 0, 0.55); } }
.l1::after { animation-name: line-1; } .l2::after { animation-name: line-2; } .l3::after { animation-name: line-3; }
@keyframes line-1 { 0%, 17% { transform: scaleX(0); } 21.5%, 88% { transform: scaleX(1); } 92%, 100% { transform: scaleX(0); } }
@keyframes line-2 { 0%, 39% { transform: scaleX(0); } 43.5%, 88% { transform: scaleX(1); } 92%, 100% { transform: scaleX(0); } }
@keyframes line-3 { 0%, 61% { transform: scaleX(0); } 65.5%, 88% { transform: scaleX(1); } 92%, 100% { transform: scaleX(0); } }
/* The steps stand on the look by themselves: no panel, each tile white with its own hairline and shadow. */
.steps-strip { padding: 0; background: none; border: 0; box-shadow: none; }
.step { background: #fff; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08), 0 8px 24px -12px rgba(0, 0, 0, 0.35); }
.step-line { background: rgba(255, 255, 255, 0.7); }
@keyframes step-1 { 0%, 1% { background: #fff; color: rgba(0, 0, 0, 0.55); } 3%, 20% { background: #e2e2e2; color: #1c1c1c; } 23%, 100% { background: #fff; color: rgba(0, 0, 0, 0.55); } }
@keyframes step-2 { 0%, 21.5% { background: #fff; color: rgba(0, 0, 0, 0.55); } 23.5%, 42% { background: #e2e2e2; color: #1c1c1c; } 45%, 100% { background: #fff; color: rgba(0, 0, 0, 0.55); } }
@keyframes step-3 { 0%, 43.5% { background: #fff; color: rgba(0, 0, 0, 0.55); } 45.5%, 63% { background: #e2e2e2; color: #1c1c1c; } 66%, 100% { background: #fff; color: rgba(0, 0, 0, 0.55); } }
@keyframes step-4 { 0%, 65% { background: #fff; color: rgba(0, 0, 0, 0.55); } 67%, 86% { background: #e2e2e2; color: #1c1c1c; } 89%, 100% { background: #fff; color: rgba(0, 0, 0, 0.55); } }
@media (prefers-reduced-motion: reduce) {
  .s4 { background: #e2e2e2; color: #1c1c1c; }
}
/* A lit step is the hover grey of the first card's buttons (7% black on white), nothing deeper. */
@keyframes step-1 { 0%, 1% { background: #fff; color: rgba(0, 0, 0, 0.55); } 3%, 20% { background: #ededed; color: #1c1c1c; } 23%, 100% { background: #fff; color: rgba(0, 0, 0, 0.55); } }
@keyframes step-2 { 0%, 21.5% { background: #fff; color: rgba(0, 0, 0, 0.55); } 23.5%, 42% { background: #ededed; color: #1c1c1c; } 45%, 100% { background: #fff; color: rgba(0, 0, 0, 0.55); } }
@keyframes step-3 { 0%, 43.5% { background: #fff; color: rgba(0, 0, 0, 0.55); } 45.5%, 63% { background: #ededed; color: #1c1c1c; } 66%, 100% { background: #fff; color: rgba(0, 0, 0, 0.55); } }
@keyframes step-4 { 0%, 65% { background: #fff; color: rgba(0, 0, 0, 0.55); } 67%, 86% { background: #ededed; color: #1c1c1c; } 89%, 100% { background: #fff; color: rgba(0, 0, 0, 0.55); } }
@media (prefers-reduced-motion: reduce) {
  .s4 { background: #ededed; color: #1c1c1c; }
}
/* The toolbar sits flat on the look: a hairline, no drop shadow. */
.mini { box-shadow: none; }
/* Concentric corners, as the app's strips: 10px controls 4px inside a 14px bar. The cursor's stops follow. */
.mini { padding: 4px; gap: 4px; border-radius: 14px; }
@keyframes hunt { 0%, 8% { transform: translate(-40px, 44px); } 22%, 36% { transform: translate(10px, 2px); } 50%, 64% { transform: translate(42px, 2px); } 78%, 92% { transform: translate(74px, 2px); } 100% { transform: translate(-40px, 44px); } }
@media (prefers-reduced-motion: reduce) {
  .art-hunt .cursor { transform: translate(42px, 2px); }
}
/* 3, again: a pile. Light bubbles like the rest, each dropping onto the last with a small offset and tilt. */
.art-stack { display: grid; place-items: center; padding: 0; }
.bubble { grid-area: 1 / 1; background: #fff; color: #1c1c1c; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08); white-space: nowrap; }
@keyframes pop-1 { 0%, 4% { opacity: 0; transform: translate(-14px, -10px) rotate(-4deg); } 10%, 84% { opacity: 1; transform: translate(-14px, 16px) rotate(-4deg); } 92%, 100% { opacity: 0; transform: translate(-14px, 16px) rotate(-4deg); } }
@keyframes pop-2 { 0%, 26% { opacity: 0; transform: translate(10px, -24px) rotate(3deg); } 32%, 84% { opacity: 1; transform: translate(10px, 2px) rotate(3deg); } 92%, 100% { opacity: 0; transform: translate(10px, 2px) rotate(3deg); } }
@keyframes pop-3 { 0%, 48% { opacity: 0; transform: translate(-4px, -38px) rotate(-1.5deg); } 54%, 84% { opacity: 1; transform: translate(-4px, -12px) rotate(-1.5deg); } 92%, 100% { opacity: 0; transform: translate(-4px, -12px) rotate(-1.5deg); } }
@media (prefers-reduced-motion: reduce) {
  .m1 { opacity: 1; transform: translate(-14px, 16px) rotate(-4deg); }
  .m2 { opacity: 1; transform: translate(10px, 2px) rotate(3deg); }
  .m3 { opacity: 1; transform: translate(-4px, -12px) rotate(-1.5deg); }
}
/* A touch more spread, so each earlier message still peeks out from under the pile. */
@keyframes pop-1 { 0%, 4% { opacity: 0; transform: translate(-16px, -4px) rotate(-3deg); } 10%, 84% { opacity: 1; transform: translate(-16px, 26px) rotate(-3deg); } 92%, 100% { opacity: 0; transform: translate(-16px, 26px) rotate(-3deg); } }
@keyframes pop-2 { 0%, 26% { opacity: 0; transform: translate(12px, -26px) rotate(2.5deg); } 32%, 84% { opacity: 1; transform: translate(12px, 2px) rotate(2.5deg); } 92%, 100% { opacity: 0; transform: translate(12px, 2px) rotate(2.5deg); } }
@keyframes pop-3 { 0%, 48% { opacity: 0; transform: translate(-6px, -48px) rotate(-1deg); } 54%, 84% { opacity: 1; transform: translate(-6px, -22px) rotate(-1deg); } 92%, 100% { opacity: 0; transform: translate(-6px, -22px) rotate(-1deg); } }
@media (prefers-reduced-motion: reduce) {
  .m1 { transform: translate(-16px, 26px) rotate(-3deg); }
  .m2 { transform: translate(12px, 2px) rotate(2.5deg); }
  .m3 { transform: translate(-6px, -22px) rotate(-1deg); }
}
/* 3, as notifications: a new message slides in from above to the front; the ones before step back, smaller and
   fainter, like a settled stack. */
.bubble { transform-origin: 50% 0; }
@keyframes pop-1 { 0%, 2% { opacity: 0; transform: translateY(-28px); } 8%, 28% { opacity: 1; transform: translateY(0) scale(1); } 34%, 53% { opacity: 0.8; transform: translateY(11px) scale(0.94); } 59%, 84% { opacity: 0.55; transform: translateY(22px) scale(0.88); } 92%, 100% { opacity: 0; transform: translateY(22px) scale(0.88); } }
@keyframes pop-2 { 0%, 27% { opacity: 0; transform: translateY(-28px); } 33%, 53% { opacity: 1; transform: translateY(0) scale(1); } 59%, 84% { opacity: 0.8; transform: translateY(11px) scale(0.94); } 92%, 100% { opacity: 0; transform: translateY(11px) scale(0.94); } }
@keyframes pop-3 { 0%, 52% { opacity: 0; transform: translateY(-28px); } 58%, 84% { opacity: 1; transform: translateY(0) scale(1); } 92%, 100% { opacity: 0; transform: translateY(0) scale(1); } }
@media (prefers-reduced-motion: reduce) {
  .m1 { opacity: 0.55; transform: translateY(22px) scale(0.88); }
  .m2 { opacity: 0.8; transform: translateY(11px) scale(0.94); }
  .m3 { opacity: 1; transform: none; }
}
/* 3, in turns: the messages share one spot. Each fades in a little small, holds, then grows a touch as it fades out,
   the next one arriving as it goes. */
.bubble { transform-origin: 50% 50%; }
@keyframes pop-1 { 0% { opacity: 0; transform: scale(0.9); } 6%, 26% { opacity: 1; transform: scale(1); } 33%, 100% { opacity: 0; transform: scale(1.1); } }
@keyframes pop-2 { 0%, 31% { opacity: 0; transform: scale(0.9); } 37%, 58% { opacity: 1; transform: scale(1); } 65%, 100% { opacity: 0; transform: scale(1.1); } }
@keyframes pop-3 { 0%, 63% { opacity: 0; transform: scale(0.9); } 69%, 91% { opacity: 1; transform: scale(1); } 98%, 100% { opacity: 0; transform: scale(1.1); } }
@media (prefers-reduced-motion: reduce) {
  .m1, .m2 { opacity: 0; }
  .m3 { opacity: 1; transform: none; }
}
/* 3, as an iOS notification stack: three frosted cards of one width behind each other, the ones behind peeking above
   the front one, smaller and fainter. The front card lifts away, the next steps forward, and the departed one
   returns at the back. Each card cycles through the three places in turn. */
.art-stack { padding-top: 24px; }
.bubble { width: 220px; white-space: normal; text-align: left; padding: 10px 12px; border-radius: 14px; background: rgba(255, 255, 255, 0.62); -webkit-backdrop-filter: blur(16px) saturate(1.2); backdrop-filter: blur(16px) saturate(1.2); box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.55); transform-origin: 50% 0; animation-duration: 6s; }
@keyframes pop-1 { 0%, 28% { opacity: 1; transform: translateY(0) scale(1); z-index: 3; } 33% { opacity: 0; transform: translateY(14px) scale(1.04); z-index: 3; } 33.5% { opacity: 0; transform: translateY(-34px) scale(0.84); z-index: 0; } 39%, 61% { opacity: 0.6; transform: translateY(-24px) scale(0.88); z-index: 1; } 67%, 94% { opacity: 0.85; transform: translateY(-12px) scale(0.94); z-index: 2; } 100% { opacity: 1; transform: translateY(0) scale(1); z-index: 3; } }
@keyframes pop-2 { 0%, 28% { opacity: 0.85; transform: translateY(-12px) scale(0.94); z-index: 2; } 33%, 61% { opacity: 1; transform: translateY(0) scale(1); z-index: 3; } 67% { opacity: 0; transform: translateY(14px) scale(1.04); z-index: 3; } 67.5% { opacity: 0; transform: translateY(-34px) scale(0.84); z-index: 0; } 73%, 94% { opacity: 0.6; transform: translateY(-24px) scale(0.88); z-index: 1; } 100% { opacity: 0.85; transform: translateY(-12px) scale(0.94); z-index: 2; } }
@keyframes pop-3 { 0%, 28% { opacity: 0.6; transform: translateY(-24px) scale(0.88); z-index: 1; } 33%, 61% { opacity: 0.85; transform: translateY(-12px) scale(0.94); z-index: 2; } 67%, 94% { opacity: 1; transform: translateY(0) scale(1); z-index: 3; } 97% { opacity: 0; transform: translateY(14px) scale(1.04); z-index: 3; } 97.5% { opacity: 0; transform: translateY(-34px) scale(0.84); z-index: 0; } 100% { opacity: 0.6; transform: translateY(-24px) scale(0.88); z-index: 1; } }
@media (prefers-reduced-motion: reduce) {
  .m1 { opacity: 1; transform: none; z-index: 3; }
  .m2 { opacity: 0.85; transform: translateY(-12px) scale(0.94); z-index: 2; }
  .m3 { opacity: 0.6; transform: translateY(-24px) scale(0.88); z-index: 1; }
}
/* Only the front card shows its words; the ones behind are plain frosted strips, as on iOS. */
@keyframes pop-1 { 0%, 28% { opacity: 1; transform: translateY(0) scale(1); z-index: 3; color: #1c1c1c; } 33% { opacity: 0; transform: translateY(14px) scale(1.04); z-index: 3; color: #1c1c1c; } 33.5% { opacity: 0; transform: translateY(-34px) scale(0.84); z-index: 0; color: transparent; } 39%, 61% { opacity: 0.6; transform: translateY(-24px) scale(0.88); z-index: 1; color: transparent; } 67%, 94% { opacity: 0.85; transform: translateY(-12px) scale(0.94); z-index: 2; color: transparent; } 100% { opacity: 1; transform: translateY(0) scale(1); z-index: 3; color: #1c1c1c; } }
@keyframes pop-2 { 0%, 28% { opacity: 0.85; transform: translateY(-12px) scale(0.94); z-index: 2; color: transparent; } 33%, 61% { opacity: 1; transform: translateY(0) scale(1); z-index: 3; color: #1c1c1c; } 67% { opacity: 0; transform: translateY(14px) scale(1.04); z-index: 3; color: #1c1c1c; } 67.5% { opacity: 0; transform: translateY(-34px) scale(0.84); z-index: 0; color: transparent; } 73%, 94% { opacity: 0.6; transform: translateY(-24px) scale(0.88); z-index: 1; color: transparent; } 100% { opacity: 0.85; transform: translateY(-12px) scale(0.94); z-index: 2; color: transparent; } }
@keyframes pop-3 { 0%, 28% { opacity: 0.6; transform: translateY(-24px) scale(0.88); z-index: 1; color: transparent; } 33%, 61% { opacity: 0.85; transform: translateY(-12px) scale(0.94); z-index: 2; color: transparent; } 67%, 94% { opacity: 1; transform: translateY(0) scale(1); z-index: 3; color: #1c1c1c; } 97% { opacity: 0; transform: translateY(14px) scale(1.04); z-index: 3; color: #1c1c1c; } 97.5% { opacity: 0; transform: translateY(-34px) scale(0.84); z-index: 0; color: transparent; } 100% { opacity: 0.6; transform: translateY(-24px) scale(0.88); z-index: 1; color: transparent; } }
@media (prefers-reduced-motion: reduce) {
  .m2, .m3 { color: transparent; }
}
/* Closer steps between the cards and a slower, softer cycle: 8s, with longer eased moves. */
.bubble { animation-duration: 8s; animation-timing-function: cubic-bezier(0.3, 0, 0, 1); }
@keyframes pop-1 { 0%, 25% { opacity: 1; transform: translateY(0) scale(1); z-index: 3; color: #1c1c1c; } 31% { opacity: 0; transform: translateY(10px) scale(1.03); z-index: 3; color: #1c1c1c; } 31.5% { opacity: 0; transform: translateY(-24px) scale(0.9); z-index: 0; color: transparent; } 39%, 58% { opacity: 0.6; transform: translateY(-16px) scale(0.92); z-index: 1; color: transparent; } 66%, 91% { opacity: 0.85; transform: translateY(-8px) scale(0.96); z-index: 2; color: transparent; } 100% { opacity: 1; transform: translateY(0) scale(1); z-index: 3; color: #1c1c1c; } }
@keyframes pop-2 { 0%, 25% { opacity: 0.85; transform: translateY(-8px) scale(0.96); z-index: 2; color: transparent; } 33%, 58% { opacity: 1; transform: translateY(0) scale(1); z-index: 3; color: #1c1c1c; } 64% { opacity: 0; transform: translateY(10px) scale(1.03); z-index: 3; color: #1c1c1c; } 64.5% { opacity: 0; transform: translateY(-24px) scale(0.9); z-index: 0; color: transparent; } 72%, 91% { opacity: 0.6; transform: translateY(-16px) scale(0.92); z-index: 1; color: transparent; } 100% { opacity: 0.85; transform: translateY(-8px) scale(0.96); z-index: 2; color: transparent; } }
@keyframes pop-3 { 0%, 25% { opacity: 0.6; transform: translateY(-16px) scale(0.92); z-index: 1; color: transparent; } 33%, 58% { opacity: 0.85; transform: translateY(-8px) scale(0.96); z-index: 2; color: transparent; } 66%, 91% { opacity: 1; transform: translateY(0) scale(1); z-index: 3; color: #1c1c1c; } 95% { opacity: 0; transform: translateY(10px) scale(1.03); z-index: 3; color: #1c1c1c; } 95.5% { opacity: 0; transform: translateY(-24px) scale(0.9); z-index: 0; color: transparent; } 100% { opacity: 0.6; transform: translateY(-16px) scale(0.92); z-index: 1; color: transparent; } }
@media (prefers-reduced-motion: reduce) {
  .m2 { transform: translateY(-8px) scale(0.96); }
  .m3 { transform: translateY(-16px) scale(0.92); }
}
/* The front card is solid white; only the cards behind are frosted. */
@keyframes pop-1 { 0%, 25% { opacity: 1; transform: translateY(0) scale(1); z-index: 3; color: #1c1c1c; background: #fff; } 31% { opacity: 0; transform: translateY(10px) scale(1.03); z-index: 3; color: #1c1c1c; background: #fff; } 31.5% { opacity: 0; transform: translateY(-24px) scale(0.9); z-index: 0; color: transparent; background: rgba(255, 255, 255, 0.62); } 39%, 58% { opacity: 0.6; transform: translateY(-16px) scale(0.92); z-index: 1; color: transparent; background: rgba(255, 255, 255, 0.62); } 66%, 91% { opacity: 0.85; transform: translateY(-8px) scale(0.96); z-index: 2; color: transparent; background: rgba(255, 255, 255, 0.62); } 100% { opacity: 1; transform: translateY(0) scale(1); z-index: 3; color: #1c1c1c; background: #fff; } }
@keyframes pop-2 { 0%, 25% { opacity: 0.85; transform: translateY(-8px) scale(0.96); z-index: 2; color: transparent; background: rgba(255, 255, 255, 0.62); } 33%, 58% { opacity: 1; transform: translateY(0) scale(1); z-index: 3; color: #1c1c1c; background: #fff; } 64% { opacity: 0; transform: translateY(10px) scale(1.03); z-index: 3; color: #1c1c1c; background: #fff; } 64.5% { opacity: 0; transform: translateY(-24px) scale(0.9); z-index: 0; color: transparent; background: rgba(255, 255, 255, 0.62); } 72%, 91% { opacity: 0.6; transform: translateY(-16px) scale(0.92); z-index: 1; color: transparent; background: rgba(255, 255, 255, 0.62); } 100% { opacity: 0.85; transform: translateY(-8px) scale(0.96); z-index: 2; color: transparent; background: rgba(255, 255, 255, 0.62); } }
@keyframes pop-3 { 0%, 25% { opacity: 0.6; transform: translateY(-16px) scale(0.92); z-index: 1; color: transparent; background: rgba(255, 255, 255, 0.62); } 33%, 58% { opacity: 0.85; transform: translateY(-8px) scale(0.96); z-index: 2; color: transparent; background: rgba(255, 255, 255, 0.62); } 66%, 91% { opacity: 1; transform: translateY(0) scale(1); z-index: 3; color: #1c1c1c; background: #fff; } 95% { opacity: 0; transform: translateY(10px) scale(1.03); z-index: 3; color: #1c1c1c; background: #fff; } 95.5% { opacity: 0; transform: translateY(-24px) scale(0.9); z-index: 0; color: transparent; background: rgba(255, 255, 255, 0.62); } 100% { opacity: 0.6; transform: translateY(-16px) scale(0.92); z-index: 1; color: transparent; background: rgba(255, 255, 255, 0.62); } }
@media (prefers-reduced-motion: reduce) {
  .m1 { background: #fff; }
}
/* 3, as a slideshow: one message at a time in the centre, the next sliding in from the right as the current one
   leaves to the left. Solid white cards, no stack. */
.art-stack { padding-top: 0; }
.bubble { background: #fff; color: #1c1c1c; -webkit-backdrop-filter: none; backdrop-filter: none; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08); transform-origin: 50% 50%; }
@keyframes pop-1 { 0%, 25% { opacity: 1; transform: translateX(0); } 32%, 90% { opacity: 0; transform: translateX(-64px); } 90.5% { opacity: 0; transform: translateX(64px); } 100% { opacity: 1; transform: translateX(0); } }
@keyframes pop-2 { 0%, 24% { opacity: 0; transform: translateX(64px); } 33%, 58% { opacity: 1; transform: translateX(0); } 65%, 100% { opacity: 0; transform: translateX(-64px); } }
@keyframes pop-3 { 0%, 57% { opacity: 0; transform: translateX(64px); } 66%, 91% { opacity: 1; transform: translateX(0); } 98%, 100% { opacity: 0; transform: translateX(-64px); } }
@media (prefers-reduced-motion: reduce) {
  .m1 { opacity: 1; transform: none; background: #fff; color: #1c1c1c; }
  .m2, .m3 { opacity: 0; }
}
/* The step cards: a live Aura strip across the top (the art box and the padding above it), the art over it. */
.card { position: relative; overflow: hidden; }
.card > .band-canvas { top: 0; left: 0; right: 0; bottom: auto; width: 100%; height: calc(253 * var(--u)); z-index: 0; }
.card-art { z-index: 1; }
/* The step cards stand as tall as the quote cards above. */
.card { min-height: 460px; }
/* Under the strip the title and text sit in the middle of the white: equal room above and below. */
.card { padding-bottom: 0; }
.card h3 { margin-top: auto; padding-top: 0; }
.card p { margin-bottom: auto; }

/* ---- The step cards' illustrations, over their strips, in the quote cards' manner. ---- */
.card .art { position: absolute; top: 0; left: 0; right: 0; height: calc(253 * var(--u)); z-index: 1; display: grid; place-items: center; pointer-events: none; color: #1c1c1c; }
.card .art svg { width: 14px; height: 14px; }
/* 1. The highlight: drawn from the top-left corner, held, then gone and drawn again. */
.snip-frame { width: 132px; height: 92px; }
.snip-box { position: relative; width: 28px; height: 20px; background: rgba(255, 255, 255, 0.14); box-shadow: 0 0 0 1px #fff, 0 0 0 2px rgba(0, 0, 0, 0.1); animation: snip 6s cubic-bezier(0.3, 0, 0, 1) infinite; }
.hd { position: absolute; width: 10px; height: 10px; border-radius: 50%; background: #fff; box-shadow: 0 0 0 .5px rgba(0, 0, 0, .3), 0 1px 3px rgba(0, 0, 0, .35); }
.hd.nw { left: -5px; top: -5px; } .hd.ne { right: -5px; top: -5px; } .hd.sw { left: -5px; bottom: -5px; } .hd.se { right: -5px; bottom: -5px; }
@keyframes snip { 0%, 6% { width: 28px; height: 20px; opacity: 1; } 40%, 86% { width: 132px; height: 92px; opacity: 1; } 92% { width: 132px; height: 92px; opacity: 0; } 92.5%, 100% { width: 28px; height: 20px; opacity: 0; } }
/* 2. The note: the pill with its two 28px controls; the words type in, pause, and clear. */
.composer-pill { display: flex; align-items: center; gap: 4px; height: 36px; padding: 4px 4px 4px 12px; background: #fff; border-radius: 14px; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08); }
.typed { width: 0; overflow: hidden; white-space: nowrap; font-size: 12px; line-height: 20px; border-right: 1.5px solid #1c1c1c; animation: typing 6s steps(20, end) infinite, caret 1s steps(1) infinite; }
@keyframes typing { 0%, 8% { width: 0; } 50%, 88% { width: 118px; } 94%, 100% { width: 0; } }
@keyframes caret { 0%, 50% { border-color: #1c1c1c; } 50.01%, 100% { border-color: transparent; } }
.pill-mic, .pill-send, .chat-go { display: grid; place-items: center; width: 28px; height: 28px; border-radius: 10px; color: rgba(0, 0, 0, 0.6); }
.pill-send, .chat-go { background: #1c1c1c; color: #fff; }
/* 3. Send: the cursor comes to the field and clicks; the field lights and the Inserted badge pops up. */
.art-send { position: relative; }
.chat-field { display: flex; align-items: center; gap: 8px; height: 36px; padding: 4px 4px 4px 12px; background: #fff; border-radius: 14px; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08); font-size: 12px; color: rgba(0, 0, 0, 0.45); animation: field-lit 6s infinite; }
.chat-placeholder { min-width: 110px; }
@keyframes field-lit { 0%, 32% { box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08); } 36%, 60% { box-shadow: 0 0 0 1.5px #3b82f6; } 66%, 100% { box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08); } }
.art-send .cursor { position: absolute; left: 50%; top: 50%; width: 18px; height: 18px; fill: #fff; stroke: #1c1c1c; stroke-width: 1.5; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.35)); animation: come-click 6s cubic-bezier(0.3, 0, 0, 1) infinite; }
@keyframes come-click { 0%, 6% { transform: translate(70px, 60px); } 30%, 34% { transform: translate(-30px, -4px); } 36% { transform: translate(-30px, -4px) scale(0.9); } 38%, 100% { transform: translate(-30px, -4px); } }
.inserted { position: absolute; left: 50%; top: 50%; display: flex; align-items: center; gap: 8px; height: 32px; padding: 0 12px 0 6px; border-radius: 12px; background: #fff; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08); font-size: 12px; font-weight: 500; transform: translate(-50%, 24px); opacity: 0; animation: inserted 6s cubic-bezier(0.2, 0, 0, 1) infinite; }
.inserted-mark { display: grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; background: #3b82f6; color: #fff; }
.inserted-mark svg { width: 12px; height: 12px; }
@keyframes inserted { 0%, 40% { opacity: 0; transform: translate(-50%, 30px); } 46%, 88% { opacity: 1; transform: translate(-50%, 24px); } 94%, 100% { opacity: 0; transform: translate(-50%, 24px); } }
@media (prefers-reduced-motion: reduce) {
  .snip-box { width: 132px; height: 92px; }
  .typed { width: 118px; border-color: transparent; }
  .art-send .cursor { transform: translate(-30px, -4px); }
  .chat-field { box-shadow: 0 0 0 1.5px #3b82f6; }
  .inserted { opacity: 1; transform: translate(-50%, 24px); }
}
/* The strip's height is the card's top padding, so the text keeps to the white below it. */
.card { padding-top: calc(253 * var(--u)); }
/* At the end the fill drains as one bar, from the right end back to the start, before the first step lights again. */
@keyframes line-1 { 0%, 17% { transform: scaleX(0); } 21.5%, 93% { transform: scaleX(1); } 95.5%, 100% { transform: scaleX(0); } }
@keyframes line-2 { 0%, 39% { transform: scaleX(0); } 43.5%, 90.5% { transform: scaleX(1); } 93%, 100% { transform: scaleX(0); } }
@keyframes line-3 { 0%, 61% { transform: scaleX(0); } 65.5%, 88% { transform: scaleX(1); } 90.5%, 100% { transform: scaleX(0); } }
.step-line::after { animation-timing-function: linear; }
/* Once the box is drawn, an arrow is drawn inside it, in the app's mark red, and clears with the box. */
.snip-mark { position: absolute; left: 0; top: 0; width: 132px; height: 92px; overflow: visible; }
.snip-mark path { fill: none; stroke: #ff3b30; stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 100; stroke-dashoffset: 100; animation: draw-mark 6s cubic-bezier(0.3, 0, 0.2, 1) infinite; }
@keyframes draw-mark { 0%, 46% { stroke-dashoffset: 100; opacity: 1; } 64%, 86% { stroke-dashoffset: 0; opacity: 1; } 92%, 100% { stroke-dashoffset: 0; opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .snip-mark path { stroke-dashoffset: 0; }
}
.card .art svg.snip-mark { width: 132px; height: 92px; } /* not an icon: the mark spans the box */
/* The step cards' strip is the quote cards' 200px, not the old art box. */
.card { padding-top: 200px; }
.card > .band-canvas, .card .art { height: 200px; }
/* The mark is a measurement: the span with a tick at each end draws first, then its red pill pops in on the line. */
.measure-label rect { fill: #ff3b30; }
.measure-label text { fill: #fff; font-size: 9.5px; font-weight: 600; letter-spacing: -0.01em; }
.measure-label { transform-box: fill-box; transform-origin: center; opacity: 0; animation: label-pop 6s cubic-bezier(0.2, 0, 0, 1) infinite; }
@keyframes label-pop { 0%, 60% { opacity: 0; transform: scale(0.8); } 66%, 86% { opacity: 1; transform: scale(1); } 92%, 100% { opacity: 0; transform: scale(1); } }
@media (prefers-reduced-motion: reduce) {
  .measure-label { opacity: 1; transform: none; }
}
/* The mark is a circle: drawn around something inside the highlight, from the top, clockwise. */
.snip-mark ellipse { fill: none; stroke: #ff3b30; stroke-width: 2.5; stroke-linecap: round; stroke-dasharray: 100; stroke-dashoffset: 100; animation: draw-mark 6s cubic-bezier(0.3, 0, 0.2, 1) infinite; }
@media (prefers-reduced-motion: reduce) {
  .snip-mark ellipse { stroke-dashoffset: 0; }
}
/* Hidden outright until it starts drawing: a fully offset dash still shows its round cap as a dot. */
@keyframes draw-mark { 0%, 45.9% { stroke-dashoffset: 100; opacity: 0; } 46% { stroke-dashoffset: 100; opacity: 1; } 64%, 86% { stroke-dashoffset: 0; opacity: 1; } 92%, 100% { stroke-dashoffset: 0; opacity: 0; } }
/* "Made for the fiddly parts": the heading stays put on the left while the six tiles scroll by on the right. */
@media (min-width: 820px) {
  #details .wrap { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 48px; align-items: start; }
  #details .head { position: sticky; top: 48px; text-align: left; justify-items: start; margin-bottom: 0; }
  #details .head .sub { text-wrap: initial; }
  #details .tiles { grid-template-columns: repeat(2, 1fr); }
}

/* ---- The feature tiles: one per row, the words on the left and a look panel with a still illustration on the right. ---- */
@media (min-width: 820px) {
  #details .tiles { grid-template-columns: 1fr; }
}
.tiles li { padding: 0; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); min-height: 240px; }
.tile-text { padding: 34.5px 37px 37px; display: flex; flex-direction: column; justify-content: space-between; gap: 24px; }
.tile-look { position: relative; overflow: hidden; display: grid; place-items: center; }
.tile-look .band-canvas { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; }
.tile-art { position: relative; z-index: 1; display: grid; place-items: center; color: #1c1c1c; }
.tile-art svg { width: 14px; height: 14px; }
@media (max-width: 819.98px) {
  .tiles li { grid-template-columns: 1fr; }
  .tile-look { min-height: 180px; }
}
/* A highlight box with the handles; inside it an arrow, or a reference thumbnail in the corner. */
.tart-box { position: relative; width: 112px; height: 72px; background: rgba(255, 255, 255, 0.14); box-shadow: 0 0 0 1px #fff, 0 0 0 2px rgba(0, 0, 0, 0.1); }
.tile-art svg.tart-mark { position: absolute; left: 0; top: 0; width: 112px; height: 72px; overflow: visible; }
.tart-mark path { fill: none; stroke: #ff3b30; stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }
.tart-ref { position: absolute; left: 6px; bottom: 6px; width: 28px; height: 28px; border-radius: 8px; background: linear-gradient(135deg, #ffd1b8, #d99cff); box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.8); }
.tart-ref b, .tart-shot b { position: absolute; left: 3px; bottom: 3px; min-width: 12px; height: 12px; padding: 0 3px; border-radius: 6px; background: rgba(24, 24, 24, 0.72); color: #fff; font-size: 8px; font-weight: 600; line-height: 12px; text-align: center; }
/* The measurement: the span, its ticks and the red pill. */
.tile-art svg.tart-measure { width: 132px; height: 40px; overflow: visible; }
.tart-measure path { fill: none; stroke: #ff3b30; stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }
.tart-measure rect { fill: #ff3b30; }
.tart-measure text { fill: #fff; font-size: 9.5px; font-weight: 600; letter-spacing: -0.01em; }
/* A paused player: a white frame, the pause mark in the middle, a bar frozen part way. */
.tart-player { position: relative; width: 128px; height: 80px; border-radius: 10px; background: #fff; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08); display: grid; place-items: center; }
.tart-pause { display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; background: #1c1c1c; color: #fff; }
.tart-pause svg { width: 12px; height: 12px; }
.tart-bar { position: absolute; left: 12px; right: 12px; bottom: 10px; height: 3px; border-radius: 2px; background: rgba(0, 0, 0, 0.1); }
.tart-bar b { position: absolute; left: 0; top: 0; bottom: 0; width: 42%; border-radius: 2px; background: #1c1c1c; }
/* Three shots fanned, numbered as in the app, and the send button after them. */
.tart-shots { display: flex; align-items: center; }
.tart-shot { position: relative; width: 44px; height: 44px; margin-right: -12px; border-radius: 8px; background: #fff; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1); }
.tart-shot.s1 { background: linear-gradient(135deg, #cfcbff, #aeb8ff); } .tart-shot.s2 { background: linear-gradient(135deg, #ffd4ba, #f6abc6); } .tart-shot.s3 { background: linear-gradient(135deg, #c3ebdf, #b6d0ff); }
.tart-shot.s2 { transform: translateY(-6px); } .tart-shot.s3 { transform: translateY(-12px); }
.tart-go { display: grid; place-items: center; width: 28px; height: 28px; margin-left: 24px; border-radius: 50%; background: #1c1c1c; color: #fff; }
/* The note pill, at rest. */
.composer-pill.still { height: 36px; }
.typed-still { font-size: 12px; line-height: 20px; white-space: nowrap; }
/* Spans inside an illustration are not the tile's description: no auto margin, no muted colour. */
.tile-art span, .tile-art b, .tile-art i { margin: 0; max-width: none; font-size: inherit; line-height: inherit; color: inherit; }
.tart-pause svg { fill: #fff; stroke: #fff; }
.typed-still { color: #1c1c1c; }
.tile-art .pill-send, .tile-art .tart-go, .tile-art .tart-pause { color: #fff; } /* white glyphs on the dark buttons, above the reset */
.tile-art .tart-ref b, .tile-art .tart-shot b { font-size: 8px; line-height: 12px; color: #fff; } /* the number badges keep their own size */
/* On a phone the tile's inset is the words', so the look panel still runs to the tile's edges. */
@media (max-width: 560px) {
  .tiles li { padding: 0; }
  .tile-text { padding: 24px; }
}

/* ---- The feature tiles' pictures: crops of MeltKit (art/tiles.cjs) in a small white window, with BlinkSnip's marks
   placed over them in the crop's own pixels. ---- */
.mk { position: relative; width: min(240px, 80%); border-radius: 12px; overflow: visible; background: #fff; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08); }
.mk > img { display: block; width: 100%; height: 100%; border-radius: 12px; }
.mk-box { position: absolute; background: rgba(59, 130, 246, 0.06); box-shadow: 0 0 0 1.5px #fff, 0 0 0 2.5px rgba(0, 0, 0, 0.12); }
.tile-art svg.mk-ink { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.mk-ink path { fill: none; stroke: #ff3b30; stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }
.tile-art .mk-pill { position: absolute; transform: translate(-50%, -50%); height: 16px; padding: 0 6px; border-radius: 8px; background: #ff3b30; color: #fff; font-size: 9.5px; font-weight: 600; line-height: 16px; white-space: nowrap; }
.tile-art .mk-box .tart-ref { left: -10px; bottom: -10px; width: 34px; height: 34px; background: linear-gradient(135deg, #ffd1b8, #d99cff); box-shadow: 0 0 0 1.5px #fff, 0 4px 12px -4px rgba(0, 0, 0, 0.35); }
/* Many shots: three crops as kept-shot tiles, numbered, then send. */
.mk-shots { display: flex; align-items: center; }
.tile-art .mk-shot { position: relative; width: 64px; height: 64px; margin-right: -14px; border-radius: 10px; overflow: hidden; background: #fff; box-shadow: 0 0 0 1.5px #fff, 0 6px 16px -6px rgba(0, 0, 0, 0.35); }
.mk-shot:nth-child(2) { transform: translateY(-8px); } .mk-shot:nth-child(3) { transform: translateY(-16px); }
.mk-shot img { width: 100%; height: 100%; object-fit: cover; }
.tile-art .mk-shot b { position: absolute; left: 4px; bottom: 4px; min-width: 14px; height: 14px; padding: 0 3px; border-radius: 7px; background: rgba(24, 24, 24, 0.72); color: #fff; font-size: 9px; font-weight: 600; line-height: 14px; text-align: center; }
.mk-shots .tart-go { margin-left: 28px; }
/* Type or talk: MeltKit's card with the note pill under it. */
.mk-stack { display: grid; justify-items: center; gap: 10px; width: 100%; }
.mk-note { margin-top: -18px; position: relative; z-index: 2; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08), 0 8px 24px -10px rgba(0, 0, 0, 0.3); }
/* As in the app, an inspiration image pins just under the box's bottom-left corner, not over the box. */
.tile-art .mk-box .tart-ref { left: 0; bottom: auto; top: calc(100% + 8px); width: 30px; height: 30px; }
/* The note is as wide as MeltKit's card above it. */
.mk-note { width: min(240px, 80%); }
.mk-note .typed-still { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.tile-art .typed-still { font-size: 12px; line-height: 20px; } /* above the panels' span reset */

/* ---- A screen under the highlighter (desktop/overlay.css #highlight): the crop set 40px in, running off the panel;
   outside the box it is dimmed 28% black, inside clear; a 1px outline at 45% white and the 10px handles. ---- */
.tile-art:has(> .ss) { position: absolute; inset: 0; display: block; }
.ss { position: absolute; inset: 0; }
.ss-screen, .ss-layer { position: absolute; left: 40px; top: 44px; width: 300px; height: 240px; }
.ss-screen { overflow: hidden; border-radius: 14px 0 0 0; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.06); }
.ss-screen img { display: block; width: 300px; height: 240px; }
.ss-dim { position: absolute; box-shadow: 0 0 0 100vmax rgba(0, 0, 0, 0.28); }
.ss-box { position: absolute; outline: 1px solid rgba(255, 255, 255, 0.45); }
.tile-art svg.ss-ink { position: absolute; left: 0; top: 0; width: 300px; height: 240px; overflow: visible; }
.ss-ink path { fill: none; stroke: #ff3b30; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.tile-art .ss-pill { position: absolute; transform: translate(-50%, -50%); height: 16px; padding: 0 6px; border-radius: 8px; background: #ff3b30; color: #fff; font-size: 9.5px; font-weight: 600; line-height: 16px; white-space: nowrap; }
.tile-art .ss-note { position: absolute; width: 190px; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08), 0 8px 24px -10px rgba(0, 0, 0, 0.3); }
.ss-note .typed-still { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.ss-box .tart-ref { position: absolute; left: 0; top: calc(100% + 8px); width: 30px; height: 30px; border-radius: 8px; background: linear-gradient(135deg, #ffd1b8, #d99cff); box-shadow: 0 0 0 1.5px #fff, 0 4px 12px -4px rgba(0, 0, 0, 0.35); }

/* Kept shots in the screen's bottom-left corner, as the highlighter's strip (desktop/overlay.css .shots), at about
   six tenths of its size: 56px tiles with 10px corners and the number badge, then New shot and Send in a white bar. */
.ss-shots { position: absolute; left: 50px; bottom: 12px; z-index: 2; display: flex; align-items: flex-end; gap: 6px; }
.tile-art .ss-shot { position: relative; display: block; width: 56px; height: 56px; border-radius: 10px; overflow: hidden; background: #fff; box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.6), 0 8px 20px -8px rgba(0, 0, 0, 0.45); }
.ss-shot img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: 0 0; }
.tile-art .ss-shot b { position: absolute; left: 4px; bottom: 4px; min-width: 13px; height: 13px; padding: 0 3px; border-radius: 7px; background: rgba(24, 24, 24, 0.72); color: #fff; font-size: 8.5px; font-weight: 600; line-height: 13px; text-align: center; }
.tile-art .ss-actions { display: flex; flex-direction: column; gap: 2px; padding: 3px; border-radius: 10px; background: #fff; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08), 0 8px 20px -8px rgba(0, 0, 0, 0.35); }
.ss-actions i { display: grid; place-items: center; width: 22px; height: 22px; border-radius: 7px; color: rgba(0, 0, 0, 0.6); }
.tile-art .ss-actions svg { width: 12px; height: 12px; }
@media (max-width: 819.98px) {
  .tile-look { min-height: 240px; } /* the screens and the kept-shot corner need the panel's full height */
}
/* The footer's look lives inside the panel, under its dark fill: it shows through the cut-out letters, nowhere else. */
.panel > .panel-look { top: 0; height: 100%; z-index: -2; border-radius: inherit; }

/* ---- The hero demo: a 14s loop on a 1280×800 stage (the size the product shots are drawn at), scaled to the window
   by site.js. Alt+S over MeltKit, a box dragged around the effects list, a note typed, Send; then VS Code, the
   picker, a click in Claude Code's prompt, and the shot and note pasted there. Every part runs on the same 14s, so
   they keep step in every loop; the typed characters differ only by a delay. ---- */
.demo { position: relative; width: 100%; aspect-ratio: 16 / 10; overflow: hidden; background: #f4f4f4; }
.d-stage { position: absolute; left: 0; top: 0; width: 1280px; height: 800px; transform: scale(var(--s, 1)); transform-origin: 0 0; font-family: Geist, ui-sans-serif, system-ui, sans-serif; }
.d-stage *, .d-stage *::before { animation-duration: 14s; animation-iteration-count: infinite; animation-fill-mode: both; }
.d-app, .d-code { position: absolute; inset: 0; }
.d-app > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; max-width: none; }
.d-app { animation-name: d-app; }
.d-code { animation-name: d-code; background: #1f1f1f; color: #cccccc; font-size: 13px; }
@keyframes d-app { 0%, 49% { opacity: 1; } 52%, 93% { opacity: 0; } 97%, 100% { opacity: 1; } }
@keyframes d-code { 0%, 49% { opacity: 0; } 52%, 93% { opacity: 1; } 97%, 100% { opacity: 0; } }

/* Alt + S, as keycaps, before the screen dims. */
.d-keys { position: absolute; left: 50%; bottom: 72px; display: flex; gap: 8px; transform: translateX(-50%); animation-name: d-keys; }
.d-keys kbd { min-width: 54px; height: 54px; padding: 0 14px; display: grid; place-items: center; border-radius: 14px; background: #1c1c1c; color: #fff; font: 600 20px/1 Geist, system-ui, sans-serif; box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.1), 0 16px 40px -12px rgba(0, 0, 0, 0.5); }
@keyframes d-keys { 0%, 2% { opacity: 0; transform: translate(-50%, 12px) scale(0.96); } 4%, 8% { opacity: 1; transform: translate(-50%, 0) scale(1); } 5% { transform: translate(-50%, 0) scale(0.97); } 10%, 100% { opacity: 0; transform: translate(-50%, 0) scale(1); } }

/* The highlight: it dims the screen around itself (desktop/overlay.css #highlight) and grows with the drag. */
.d-box { position: absolute; left: 12px; top: 158px; width: 0; height: 0; outline: 1px solid rgba(255, 255, 255, 0.45); box-shadow: 0 0 0 2000px rgba(0, 0, 0, 0.28); animation-name: d-box; animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); }
@keyframes d-box { 0%, 8.5% { opacity: 0; width: 0; height: 0; } 9.5%, 10% { opacity: 1; width: 0; height: 0; } 20%, 47% { opacity: 1; width: 278px; height: 346px; } 49%, 100% { opacity: 0; width: 278px; height: 346px; } }
.d-box .hd { animation-name: d-shown; }
.d-strip, .d-note { animation-name: d-shown; }
@keyframes d-shown { 0%, 20% { opacity: 0; transform: translateY(4px); } 22%, 46.5% { opacity: 1; transform: none; } 48.5%, 100% { opacity: 0; transform: none; } }
/* The tool strip beside it, as in the highlighter, in the app's dark theme. */
.d-strip { position: absolute; left: 300px; top: 156px; display: flex; flex-direction: column; gap: 2px; padding: 4px; border-radius: 14px; background: #1c1c1c; box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 10px 15px -3px rgba(0, 0, 0, 0.3); }
.d-strip i { display: grid; place-items: center; width: 28px; height: 28px; color: #939393; }
.d-strip b { display: block; height: 1px; margin: 3px 2px; background: rgba(239, 239, 239, 0.07); }
/* The note under the box, typed in a moment, then Send. */
.d-note { position: absolute; left: 12px; top: 514px; width: 278px; min-height: 84px; padding: 10px 12px 40px; border-radius: 14px; background: #1c1c1c; color: #efefef; box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 10px 15px -3px rgba(0, 0, 0, 0.3); }
.d-typed { margin: 0; font-size: 13.5px; line-height: 20px; }
.d-typed span { animation-name: d-char; animation-delay: calc(var(--i) * 0.04s); }
@keyframes d-char { 0%, 23% { opacity: 0; } 23.01%, 47% { opacity: 1; } 47.5%, 100% { opacity: 0; } }
.d-mic, .d-send { position: absolute; bottom: 6px; display: grid; place-items: center; width: 28px; height: 28px; border-radius: 10px; }
.d-mic { right: 40px; color: #939393; }
.d-send { right: 6px; border-radius: 50%; background: #fafafa; color: #131313; animation-name: d-press; }
@keyframes d-press { 0%, 44.5% { transform: none; } 45.2% { transform: scale(0.86); background: #d4d4d4; } 46.5%, 100% { transform: none; } }

/* VS Code with the Claude Code panel. */
.v-title { position: absolute; left: 0; right: 0; top: 0; height: 32px; display: grid; place-items: center; background: #181818; border-bottom: 1px solid #2b2b2b; color: #9d9d9d; font-size: 12px; }
.v-activity { position: absolute; left: 0; top: 32px; bottom: 0; width: 48px; display: flex; flex-direction: column; align-items: center; gap: 22px; padding-top: 14px; background: #181818; border-right: 1px solid #2b2b2b; color: #868686; }
.v-activity i.on { color: #e7e7e7; }
.v-side { position: absolute; left: 48px; top: 32px; bottom: 0; width: 220px; padding: 10px 0; background: #181818; border-right: 1px solid #2b2b2b; font-size: 13px; }
.v-side h6, .v-claude h6 { margin: 0 0 8px; padding: 0 16px; font-size: 11px; font-weight: 500; letter-spacing: 0.04em; color: #9d9d9d; }
.v-side p { margin: 0; padding: 3px 16px; white-space: pre; color: #cccccc; }
.v-side p.sel { background: #37373d; color: #fff; }
.v-editor { position: absolute; left: 268px; top: 32px; bottom: 0; width: 592px; }
.v-tabs { display: flex; height: 35px; background: #181818; border-bottom: 1px solid #2b2b2b; }
.v-tabs span { padding: 0 16px; display: grid; place-items: center; border-right: 1px solid #2b2b2b; color: #9d9d9d; font-size: 13px; }
.v-tabs span.on { background: #1f1f1f; color: #fff; box-shadow: inset 0 1px 0 #0078d4; }
.v-lines { padding: 10px 0; font: 13px/20px "Cascadia Code", Consolas, "SF Mono", Menlo, monospace; }
.v-lines p { margin: 0; white-space: pre; color: #d4d4d4; }
.v-lines u { display: inline-block; width: 44px; padding-right: 18px; text-align: right; text-decoration: none; color: #6e7681; }
.v-lines k { color: #c586c0; } .v-lines v, .v-lines a { color: #9cdcfe; } .v-lines s { color: #ce9178; text-decoration: none; }
.v-lines c { color: #6a9955; } .v-lines f { color: #dcdcaa; } .v-lines t { color: #4ec9b0; }
.v-claude { position: absolute; left: 860px; right: 0; top: 32px; bottom: 0; padding: 14px 16px; background: #181818; border-left: 1px solid #2b2b2b; }
.v-claude h6 { display: flex; align-items: center; gap: 6px; padding: 0; margin-bottom: 18px; color: #d97757; }
.v-msg { margin-bottom: 14px; color: #cccccc; font-size: 13px; line-height: 1.5; }
.v-msg.me { padding: 8px 12px; border-radius: 8px; background: #2a2a2a; color: #e7e7e7; }
.v-prompt { position: absolute; left: 16px; right: 16px; bottom: 16px; min-height: 120px; padding: 12px; border: 1px solid #3c3c3c; border-radius: 10px; background: #1f1f1f; animation-name: d-focus; }
@keyframes d-focus { 0%, 62% { border-color: #3c3c3c; } 62.5%, 92% { border-color: #d97757; } 95%, 100% { border-color: #3c3c3c; } }
.v-placeholder { color: #6e6e6e; font-size: 13px; animation-name: d-placeholder; }
@keyframes d-placeholder { 0%, 63% { opacity: 1; } 63.2%, 93% { opacity: 0; } 95%, 100% { opacity: 1; } }
.v-pasted { position: absolute; left: 12px; right: 12px; top: 12px; display: flex; gap: 10px; animation-name: d-pasted; }
@keyframes d-pasted { 0%, 63% { opacity: 0; transform: translateY(4px); } 64%, 93% { opacity: 1; transform: none; } 95%, 100% { opacity: 0; transform: none; } }
/* The snipped area itself: the screen picture, cropped to the box the same way it is drawn on the stage. */
.v-thumb { flex-shrink: 0; width: 56px; height: 70px; border-radius: 6px; background: url(/assets/shots/meltkit.webp) -2.96px -31.8px / 258.8px 161.1px no-repeat; box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.12); }
.v-pasted p { margin: 0; color: #e7e7e7; font-size: 13px; line-height: 1.5; }

/* The field picker card, then the Inserted badge, as the app shows them. */
.d-picker { position: absolute; left: 50%; top: 52px; width: 440px; display: flex; gap: 12px; padding: 16px 20px; border-radius: 14px; background: #1c1c1c; color: #efefef; box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 20px 40px -12px rgba(0, 0, 0, 0.5); transform: translateX(-50%); animation-name: d-picker; }
.d-picker > span { padding-top: 1px; color: #939393; opacity: 0.6; }
.d-picker b { display: block; font-size: 13px; font-weight: 500; }
.d-picker em { display: block; margin-top: 2px; font-style: normal; font-size: 12px; color: #939393; }
@keyframes d-picker { 0%, 52.5% { opacity: 0; transform: translate(-50%, -8px); } 54%, 61.5% { opacity: 1; transform: translate(-50%, 0); } 63%, 100% { opacity: 0; transform: translate(-50%, 0); } }
.d-inserted { position: absolute; right: 16px; bottom: 16px; display: flex; align-items: center; gap: 8px; height: 40px; padding: 0 14px 0 10px; border-radius: 14px; background: #1c1c1c; color: #efefef; font-size: 13px; font-weight: 500; box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.1), 0 16px 32px -12px rgba(0, 0, 0, 0.6); animation-name: d-inserted; }
.d-inserted span { display: grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; background: #3b82f6; color: #fff; }
@keyframes d-inserted { 0%, 64.5% { opacity: 0; transform: translateY(8px); } 66%, 80% { opacity: 1; transform: none; } 83%, 100% { opacity: 0; transform: none; } }

/* The pointer: one path through the whole loop, pressing where it clicks. */
.d-cursor { position: absolute; left: -4px; top: -4px; width: 24px; height: 24px; fill: #fff; stroke: #1c1c1c; stroke-width: 1.5; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.35)); animation-name: d-cursor; animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); }
@keyframes d-cursor {
  0%, 4% { transform: translate(720px, 620px); }
  9%, 10% { transform: translate(12px, 158px); }
  20%, 22% { transform: translate(290px, 504px); }
  24%, 41% { transform: translate(380px, 540px); }
  44.5% { transform: translate(266px, 572px); }
  45.2% { transform: translate(266px, 572px) scale(0.85); }
  46%, 55% { transform: translate(266px, 572px); }
  61.5% { transform: translate(1010px, 712px); }
  62.2% { transform: translate(1010px, 712px) scale(0.85); }
  63%, 66% { transform: translate(1010px, 712px); }
  72%, 92% { transform: translate(700px, 470px); }
  100% { transform: translate(720px, 620px); }
}

/* Without motion: the moment after the drag, the note written, nothing moving. */
@media (prefers-reduced-motion: reduce) {
  .d-stage *, .d-stage *::before { animation: none !important; }
  .d-box { width: 278px; height: 346px; }
  .d-code, .d-keys, .d-cursor { display: none; }
}
.d-inserted { bottom: 160px; right: 32px; } /* above Claude Code's prompt box, not over it */
/* On the dark page the headline's gradient is grey too: near white at "Stop", a mid grey by the end of "screen." */
.grad-a { background-image: linear-gradient(90deg, #f4f4f4 0%, #dcdcdc 45%, #b4b4b4 100%); }
.grad-b { background-image: linear-gradient(90deg, #c8c8c8 0%, #a4a4a4 50%, #858585 100%); }
/* The demo's Alt key carries the Mac's ⌥ in its corner, as an Option key does. */
.d-keys kbd.k-alt { position: relative; min-width: 78px; }
.d-keys kbd.k-alt i { position: absolute; top: 7px; right: 10px; font-style: normal; font-size: 14px; font-weight: 500; opacity: 0.6; }
/* Both shortcuts, side by side and named: Alt+S on Windows, ⌥S on a Mac. */
.d-keys { gap: 28px; align-items: flex-start; }
.d-combo { display: grid; justify-items: center; gap: 10px; }
.d-combo > span { display: flex; gap: 8px; }
.d-combo em { padding: 3px 10px; border-radius: 999px; background: rgba(28, 28, 28, 0.78); color: #efefef; font: 500 14px/1.3 Geist, system-ui, sans-serif; font-style: normal; }
.d-keys kbd { font-size: 22px; }
.d-keys { bottom: 100px; } /* clear of MeltKit's toolbar below */
.d-keys { bottom: 72px; } /* without labels the keys sit where they first did */
/* Alt / ⌥ + S: the two modifier keys side by side, then the letter. */
.d-keys { gap: 10px; align-items: center; }
.d-keys > i { font: 600 26px/1 Geist, system-ui, sans-serif; font-style: normal; color: #1c1c1c; }

/* ---- The FAQ as it first was: the heading on the left, the questions on the right as plain rows, a hairline under
   each, no card. ---- */
.faq-grid { display: grid; gap: 24px 64px; align-items: start; }
@media (min-width: 820px) {
  .faq-grid { grid-template-columns: 5fr 7fr; }
}
.faq { border: 0; background: none; }
.faq details, .faq details:last-child { border-bottom: 1px solid var(--border); }
.faq summary { padding: 18px 32px 18px 0; }
.faq summary::after { right: 4px; }
.faq details p { margin: 0 0 18px; padding: 0; max-width: 40rem; }
/* A curved arrow over the seam between the two ways, from the old list into BlinkSnip's. */
.compare { position: relative; }
.compare-arrow { position: absolute; z-index: 2; left: calc(50% - 110px); top: 52%; width: 220px; height: 120px; overflow: visible; pointer-events: none; }
.compare-arrow path { fill: none; stroke: #ff3b30; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
@media (max-width: 719.98px) {
  .compare-arrow { display: none; } /* stacked, the two panels have no seam to cross */
}
/* The arrow takes the old way's text grey, not the mark red. On the white panel that 60% white would vanish, so the
   colour is the same grey made solid: #9d9d9d over the dark card, which also reads on white. */
.compare-arrow path { stroke: #9d9d9d; }

/* ---- Works with your AI chat: the tools on a ring around "Anything you can paste into". The ring turns once a
   minute; each tile turns back as much, so its logo and name stay upright. ---- */
.orbit { position: relative; width: 440px; height: 440px; margin: 8px auto 0; }
.orbit-ring { position: absolute; border-radius: 50%; border: 1px dashed var(--border-strong); }
.orbit-ring.r1 { inset: 52px; }
.orbit-ring.r2 { inset: 132px; border-style: solid; border-color: var(--border); }
.orbit-spin { position: absolute; inset: 0; margin: 0; padding: 0; list-style: none; animation: orbit-spin 60s linear infinite; }
.orb { position: absolute; width: 0; height: 0; }
.orb-tile, .orb-name { position: absolute; left: 0; top: 0; animation: orbit-spin 60s linear infinite reverse; }
.orb-tile { width: 56px; height: 56px; margin: -28px 0 0 -28px; display: grid; place-items: center; border-radius: 50%; background: #fff; box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.12), 0 12px 30px -12px rgba(0, 0, 0, 0.6); }
.orb-tile svg { width: 26px; height: 26px; }
/* The name sits under its tile; turned with it about the tile's own centre. */
.orb-name { width: 120px; margin-left: -60px; text-align: center; transform-origin: 60px -38px; top: 38px; font-size: 13px; font-weight: 500; color: var(--muted-foreground); white-space: nowrap; }
.orb-claude svg { fill: #d97757; }
.orb-openai svg, .orb-cursor svg { fill: #0b0b0b; }
.orb-gemini svg { fill: #8e75b2; }
.orb-claude-code svg { fill: #d97757; }
.orbit-center { position: absolute; left: 50%; top: 50%; margin: 0; padding: 12px 18px; transform: translate(-50%, -50%); border-radius: 999px; background: var(--card); color: var(--foreground); font-size: 15px; font-weight: 500; white-space: nowrap; box-shadow: 0 0 0 1px var(--border-strong); }
@keyframes orbit-spin { to { transform: rotate(360deg); } }
@media (max-width: 560px) {
  .orbit { transform: scale(0.78); margin: -40px auto -48px; }
}
@media (prefers-reduced-motion: reduce) {
  .orbit-spin, .orb-tile, .orb-name { animation: none; }
}
/* Stretched: the ring is an ellipse as wide as the column, reaching the guides at both sides. The tiles travel along it
   by script (site.js), not by rotating the list, so they and their names stay level without counter-turning. */
.orbit { width: 100%; height: 440px; transform: none; margin: 8px 0 0; }
.orbit-ring.r1 { inset: 28px 0; }
.orbit-ring.r2 { inset: 120px 30%; }
.orbit-spin, .orb-tile, .orb-name { animation: none; }
.orb-name { transform: none; }
@media (max-width: 560px) {
  .orbit { height: 380px; margin: 0; transform: none; }
  .orbit-center { font-size: 13px; padding: 10px 14px; }
}
/* Bigger pieces for the wider ring. */
.orb-tile { width: 64px; height: 64px; margin: -32px 0 0 -32px; }
.orb-tile svg { width: 30px; height: 30px; }
.orb-name { top: 42px; font-size: 14px; }
.orbit-center { font-size: 17px; padding: 14px 22px; }
@media (max-width: 560px) {
  .orb-tile { width: 52px; height: 52px; margin: -26px 0 0 -26px; }
  .orb-tile svg { width: 24px; height: 24px; }
  .orb-name { top: 34px; font-size: 12px; }
  .orbit-center { font-size: 13px; padding: 10px 14px; }
}
/* The inner oval is the outer one at 45%, both ways, so the two share one shape. (The outer is the box less 28px top
   and bottom.) */
.orbit-ring.r2 { inset: auto; left: 50%; top: 50%; width: 45%; height: calc((100% - 56px) * 0.45); transform: translate(-50%, -50%); }
/* The tiles move by transform (site.js), not by left and top, so they glide on sub-pixels instead of snapping. */
.orbit .orb { left: 0; top: 0; will-change: transform; }
.orb-vscode svg { fill: #007acc; }
/* The centre is the words alone: no pill. */
.orbit-center { padding: 0; background: none; box-shadow: none; border-radius: 0; }
/* The inner oval reaches further toward the outer one: 62% of it, still the same shape. */
.orbit-ring.r2 { width: 62%; height: calc((100% - 56px) * 0.62); }
/* The inner oval keeps an even gap to the outer one all the way round: 105px at the top, bottom and both sides, so its
   ends reach out as far as the outer oval's do. */
.orbit-ring.r2 { left: 105px; right: 105px; top: 133px; bottom: 133px; width: auto; height: auto; transform: none; }
@media (max-width: 560px) {
  .orbit-ring.r2 { left: 60px; right: 60px; top: 88px; bottom: 88px; }
}
/* Less stretched: the sides sit 190px in from the outer oval, between the scaled copy (284) and the even gap (105). */
.orbit-ring.r2 { left: 190px; right: 190px; }
@media (max-width: 560px) {
  .orbit-ring.r2 { left: 84px; right: 84px; }
}
/* The look sits 1px inside the panel on every side: the dark fill is sized in whole pixels and the panel ends on a
   fraction of one, which let a sliver of the look show along the edge. The letters, well inside, still show it. */
.panel > .panel-look { top: 1px; left: 1px; width: calc(100% - 2px); height: calc(100% - 2px); }
/* One feature per row at every width, phones and tablets too. */
#details .tiles { grid-template-columns: 1fr; }
/* Inside a tile, words and picture stay side by side down to 560px; only a phone stacks them. Stacked, the panel is
   as wide as the phone, so its screen is drawn a fifth larger to still run off the edge. */
@media (max-width: 819.98px) {
  .tiles li { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}
@media (max-width: 560px) {
  .tiles li { grid-template-columns: 1fr; }
  .ss-screen, .ss-layer { transform: scale(1.2); transform-origin: 0 0; }
}
/* On a phone the picture panel keeps the desktop's shape (287×240), and its screen starts where the words do (24px in)
   and runs off the right edge, scaled to the phone by site.js (--ss, and --ss-top for the same top margin as desktop). */
@media (max-width: 560px) {
  .tile-look { min-height: 0; aspect-ratio: 287 / 240; }
  .ss-screen, .ss-layer { left: 24px; top: var(--ss-top, 44px); transform: scale(var(--ss, 1)); transform-origin: 0 0; }
  .ss-shots { left: 34px; }
}
/* On a phone the feature tiles touch, one running into the next, and each title sits right above its line. */
@media (max-width: 560px) {
  #details .tiles { gap: 0; }
  .tile-text { justify-content: flex-start; gap: 8px; }
}
/* On a phone the quote and step cards keep the desktop shape (339×460, the strip 200 of it, which is 59% of the
   width), and stack touching. The card is the phone's width less the 16px gutters. */
@media (max-width: 560px) {
  .quotes, .cards { gap: 0; }
  .quote, #how .card { min-height: 0; aspect-ratio: 339 / 460; }
  #how .card { padding-top: 59%; }
  #how .card > .band-canvas, #how .card .art { height: 43.48%; }
  .quote .band-canvas { height: calc((100vw - 32px) * 0.59); }
  .quote .art { height: calc((100vw - 32px) * 0.59); }
}
