/* ==========================================================================
   Dynamic Mockups — homepage
   --------------------------------------------------------------------------
   Ported from the design source of truth (landing/index.html in the redesign
   handoff). Every rule is `dm-` prefixed and page-agnostic — a section can be
   dropped on any template. Values read from
   the tokens in dm/tokens.css.

   Design language: white/paper ground, hairlines used sparingly (shade steps
   and spacing do most of the separation), modest display type, mono only where
   it is literally code, no full-bleed colour fields — the loudest brand moment
   is the contained CTA gradient panel, with the integration tiles and the AI
   editor card carrying quieter gradient doses.

   Motion is quiet and gated behind html.dm-motion: reveals, counts, terminal
   and composer typing, gridfill, FAQ ease, the two-path pin.
   ========================================================================== */

/* Any page built from these sections reserves the fixed header's height. Use
   `dm-page` on the wrapper inside `.dm`; it is not homepage-specific. */
.dm-page {
  padding-top: var(--dm-header-h, 72px);
}

/* ==========================================================================
   Hero
   ========================================================================== */
.dm-hero {
  position: relative;
  overflow: hidden;
}

.dm-hero .dm-container {
  padding-block: 80px 88px;
  /* the copy rides above the tile collage */
  position: relative;
  z-index: 1;
}

/* ---------- the hero orbit ----------
   A single canvas laid over the hero, painted by js/dm/hero.js: the renders
   ride one slow circle whose radius is larger than the hero is tall, so only
   the band that crosses the copy is ever visible. Sizing and device-pixel
   scaling are set from script — the element carries no intrinsic size, so it
   must be given one here or it falls back to canvas's 300x150 default. */
.dm-hero-orbit {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
}

.dm-hero-grid {
  display: grid;
  grid-template-columns: 1fr;
  text-align: center;
}

/* the collage needs height to compose against, and the room either side of the
   centre column only exists on a wide viewport — below that it is hidden */
/* Size the hero against the viewport so a slice of the product stage always
   shows above the fold — the page has to look scrollable on a laptop, not just
   on a tall monitor. 104px is where the hero starts (80) plus the 24px of the
   next section we want left showing.

   The ceiling is 58vw rather than a px value because it is really the orbit's
   constraint in disguise: tiles below the centre are upside down (that is what
   facing inward means down there), and the innermost ring is the one that can
   bring them inside the hero. Radii are a fraction of WIDTH, so the height that
   keeps them out scales with width too.

   With the current three-ring set that ring no longer clears the hero on tall
   viewports — at 1920x1080 its lowest tiles reach 46px in, at 2560x1440 66px.
   They land inside the bottom fade and peak around 21% opacity, so they read as
   part of the dissolve rather than as clipped tiles, which is why the cap stays
   where it is. Raise it and they climb out of the fade and start to read as
   upside down. Check hero.js DEFAULTS before touching this. */
@media (min-width: 1101px) {
  .dm-hero {
    display: flex;
    align-items: center;
    min-height: 690px;                                   /* no-clamp fallback */
    min-height: clamp(540px, calc(100svh - 104px), 58vw);
  }

  .dm-hero .dm-container {
    width: 100%;
    padding-block: 48px;
  }
}

/* no room beside the centre column below this, and hero.js paints one static
   frame rather than looping — hiding it keeps that frame off the page too */
@media (max-width: 1100px) {
  .dm-hero-orbit { display: none; }
}

.dm-hero-badges {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 24px;
}

.dm-hero-badges img {
  height: 36px;
  width: auto;
  display: block;
}

.dm-hero h1 {
  font-family: var(--dm-font-display);
  font-weight: 400;
  font-size: clamp(42px, 4vw, 56px);
  line-height: 1.1;
  letter-spacing: var(--dm-tracking-display);
  color: var(--dm-ink);
  margin: 0 auto 24px;
  max-width: 20ch;
}

.dm-hero-lede {
  font-size: 18px;
  line-height: 1.55;
  color: var(--dm-text-secondary);
  margin: 0 auto 32px;
  max-width: 50ch;
}

/* the MockAnything composer */
.dm-composer {
  background: var(--dm-surface-raised);
  border-radius: var(--dm-radius-card-inner);
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.10);
  padding: 20px 20px 16px;
  /* the hero centres, but a text field the visitor types into does not */
  max-width: 640px;
  margin-inline: auto;
  text-align: left;
}

.dm-composer textarea {
  width: 100%;
  /* The theme's style.min.css pads and borders every bare textarea
     (.5rem 1rem, 1px solid #666); the design's reset zeroes it. */
  padding: 0;
  border: 0;
  outline: 0;
  resize: none;
  background: transparent;
  font: 15px/1.5 var(--dm-font-body);
  min-height: 56px;
  color: var(--dm-ink);
}

/* No ring on the field. A text input matches :focus-visible on a plain mouse
   click too, so the base ring drew a black box inside the card on every click —
   and the design has no outline here at all. The caret marks focus; the card
   answers with a slightly deeper lift, which stays inside the quiet language. */
.dm-composer textarea:focus,
.dm-composer textarea:focus-visible {
  outline: none;
}

.dm-composer:focus-within {
  box-shadow: 0 6px 28px rgba(0, 0, 0, 0.14);
}

.dm-composer textarea::placeholder { color: var(--dm-text-tertiary); }

.dm-composer-row {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 12px;
  padding-top: 8px;
  flex-wrap: wrap;
}

/* the attach control sits at the row's left, the submit stays hard right */
.dm-composer-attach { margin-right: auto; }

.dm-composer-attach-btn,
.dm-composer-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font: 14px/1 var(--dm-font-body);
  color: var(--dm-text-secondary);
  cursor: pointer;
}

.dm-composer-attach-btn:hover { color: var(--dm-ink); }

/* `display` beats the hidden attribute, so both states have to say so
   explicitly — otherwise the chip and the button render side by side. */
.dm-composer-attach-btn[hidden],
.dm-composer-chip[hidden],
.dm-composer-attach[hidden],
.dm-composer-error[hidden] { display: none; }

/* the real input stays in the a11y tree — visually-hidden, not display:none,
   so it keeps keyboard focus and the label still opens the picker */
.dm-composer-attach-btn input[type="file"] {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.dm-composer-attach-btn:focus-within {
  color: var(--dm-ink);
  outline: 2px solid var(--dm-ink);
  outline-offset: 4px;
  border-radius: var(--dm-radius-button);
}

/* the chip takes the button's slot once a file is picked, so the row's other
   controls never shift */
.dm-composer-chip {
  padding: 5px 6px 5px 5px;
  border: 1px solid var(--dm-hairline);
  border-radius: 999px;
  background: var(--dm-surface-white);
  color: var(--dm-ink);
  max-width: 240px;
}

.dm-composer-thumb {
  width: 24px;
  height: 24px;
  border-radius: 999px;
  object-fit: cover;
  flex: none;
  background: var(--dm-surface-card);
}

.dm-composer-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.dm-composer-clear {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 20px;
  height: 20px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--dm-text-secondary);
  cursor: pointer;
}

.dm-composer-clear:hover { background: var(--dm-surface-card); color: var(--dm-ink); }

.dm-composer-error {
  flex-basis: 100%;
  order: 99;
  margin: 4px 0 0;
  font-size: 13px;
  line-height: 1.4;
  color: var(--dm-red-600, #b42318);
}

/* ==========================================================================
   Trust — the claim and the numbers beside the customer tiles
   ========================================================================== */
/* more air than the standard 96px: this section is mostly whitespace and a
   logo grid, so it reads cramped at the shared rhythm */
.dm-trust .dm-container { padding-block: 112px; }

/* minmax(0,1fr) here and on the tiles: a nested 1fr floors at min-content, and
   the nowrap-ish names would jam the track open into page overflow. */
.dm-trust-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 64px;
  align-items: stretch;
}

.dm-trust-copy {
  display: flex;
  flex-direction: column;
}

/* The tile grid is the taller of the two columns, so the copy was top-packed
   against it and left ~110px of dead space underneath. Pushing the stats down
   makes both columns start AND finish together: the claim lines up with the
   top tile row, the numbers with the bottom one, and the air lands in the
   middle where it reads as intent rather than as a short column. */
.dm-trust-copy .dm-trust-stats { margin-top: auto; }

.dm-trust-copy .dm-h2 {
  max-width: 19ch;
  margin-bottom: 24px;
}

/* rating row — the human signal under the claim; the avatars reuse the
   reviewers' own monograms from the carousel below, never invented people */
.dm-rating {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 40px;
}

.dm-rating-faces { display: flex; }

.dm-avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-family: var(--dm-font-mono);
  font-size: 10px;
  border: 2px solid var(--dm-surface-page);
}

.dm-avatar + .dm-avatar { margin-left: -9px; }

.dm-avatar--1 { background: var(--dm-pink-50);    color: var(--dm-pink-800); }
.dm-avatar--2 { background: var(--dm-cyan-50);    color: var(--dm-cyan-800); }
.dm-avatar--3 { background: var(--dm-lime-100);   color: var(--dm-lime-900); }
.dm-avatar--4 { background: var(--dm-orange-100); color: var(--dm-orange-900); }
.dm-avatar--5 { background: var(--dm-purple-100); color: var(--dm-purple-700); }
.dm-avatar--6 { background: var(--dm-blue-50);    color: var(--dm-blue-900); }

.dm-stars {
  display: flex;
  gap: 1px;
  color: var(--dm-orange-600);
}

.dm-stars svg { width: 15px; height: 15px; display: block; }

.dm-rating-note {
  font-size: 14px;
  color: var(--dm-text-secondary);
  white-space: nowrap;
}

.dm-rating-note strong { color: var(--dm-ink); font-weight: 600; }

/* hairlines separate the stats */
.dm-trust-stats {
  display: flex;
  flex-wrap: wrap;
  row-gap: 24px;
  margin: 0;
}

.dm-trust-stats > div {
  padding-inline: 44px;
  border-left: 1px solid var(--dm-border-hairline);
}

.dm-trust-stats > div:first-child { padding-left: 0; border-left: 0; }
.dm-trust-stats > div:last-child { padding-right: 0; }

.dm-trust-stats dt {
  font-family: var(--dm-font-body);
  font-weight: 500;
  font-size: 36px;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--dm-ink);
}

.dm-trust-stats dd {
  font-size: 13px;
  line-height: 1.4;
  color: var(--dm-text-secondary);
  margin: 6px 0 0;
  max-width: 16ch;
}

.dm-logo-tiles {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}

.dm-logo-tiles li {
  background: var(--dm-surface-card);
  border-radius: var(--dm-radius-card);
  aspect-ratio: 1.05;
  display: grid;
  place-items: center;
  padding: 16px;
}

/* real customer marks, hit into total gray; brand exports can swap in later */
.dm-logo-tiles img {
  max-width: min(120px, 80%);
  height: auto;
  filter: grayscale(1);
  opacity: .62;
}

/* ==========================================================================
   Two ways to build — segmented control over a scroll-pinned card deck
   ========================================================================== */
.dm-path-switch {
  display: inline-flex;
  gap: 4px;
  padding: 4px;
  background: var(--dm-surface-card);
  border-radius: 999px;
}

.dm-path-switch button {
  border: 0;
  cursor: pointer;
  background: transparent;
  font-family: inherit;
  border-radius: 999px;
  padding: 10px 22px;
  font-size: 14px;
  font-weight: 400;
  color: var(--dm-text-secondary);
  transition: background .25s var(--dm-ease-press), color .25s var(--dm-ease-press);
}

.dm-path-switch button[aria-selected="true"] {
  background: var(--dm-surface-dark);
  color: var(--dm-surface-page);
}

.dm-paths-grid { display: block; }

.dm-path-card {
  padding: 48px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 48px;
  align-items: center;
}

.dm-path-card[hidden] { display: none; }
.dm-path-card + .dm-path-card { margin-top: 24px; }

/* the deck: one card behind the other with its edge showing, echoing the hero
   photos; scrolling through the pinned section drives the flip. Desktop and
   motion only — smaller screens and reduced motion keep the plain switch, and
   with no JS both cards simply stack (is-deck is JS-applied). */
.dm-paths-grid.is-deck { display: grid; }
.is-deck .dm-path-card { grid-area: 1/1; }
.is-deck .dm-path-card + .dm-path-card { margin-top: 0; }

@media (min-width: 1101px) {
  .dm-motion .dm-paths-track { height: 200vh; }

  .dm-motion .dm-paths-sticky {
    position: sticky;
    top: 0;
    min-height: 100vh;
    display: flex;
    align-items: center;
  }

  .dm-motion .dm-paths-sticky .dm-container {
    padding-block: 48px;
    width: 100%;
  }

  .dm-motion .is-deck .dm-path-card {
    transition: transform .55s var(--dm-ease-press), box-shadow .55s var(--dm-ease-press);
  }

  .dm-motion .is-deck .dm-path-card.is-front {
    position: relative;
    z-index: 2;
    box-shadow: 0 24px 48px rgba(0, 0, 0, 0.12);
  }

  .dm-motion .is-deck .dm-path-card.is-back {
    z-index: 1;
    transform: translateY(-22px) scale(0.965) rotate(0.7deg);
  }
}

.dm-path-card .dm-render {
  margin-bottom: 0;
  align-self: stretch;
  min-height: 340px;
}

.dm-path-body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

/* The reader's own voice — "I sell products online" is the visitor identifying
   themselves, not the product describing itself, so it keeps the serif while
   everything below it in the card (tagline, feature list) stays Geist. */
.dm-path-card h3 {
  font-family: var(--dm-font-display);
  font-weight: 400;
  font-size: 30px;
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--dm-ink);
  margin-bottom: 4px;
}

.dm-path-tagline {
  font-style: italic;
  font-size: 15px;
  color: var(--dm-text-secondary);
  margin-bottom: 16px;
}

.dm-path-body p.dm-path-text {
  font-size: 15px;
  line-height: 1.55;
  color: var(--dm-text-secondary);
  margin-bottom: 20px;
}

.dm-path-card .dm-checks { margin-bottom: 28px; }

.dm-path-card .dm-btn {
  align-self: flex-start;
  margin-top: auto;
}

.dm-path-card--dark { background: var(--dm-surface-dark); box-shadow: none; }
.dm-path-card--dark h3 { color: var(--dm-surface-page); }
.dm-path-card--dark .dm-path-tagline { color: var(--dm-text-tertiary); }
.dm-path-card--dark .dm-path-body p.dm-path-text { color: var(--dm-text-inverse-secondary); }
.dm-path-card--dark .dm-checks { margin-bottom: 24px; }
.dm-path-card--dark .dm-checks li { color: var(--dm-text-inverse-secondary); }
.dm-path-card--dark .dm-checks li::before { color: var(--dm-lime); }

/* the builder card's API demo: a live terminal that types the real render
   call, cycles the SDKs the bullets promise, and loops. DOM animation — the
   code IS the demo, so there is no video and no screenshot. */
.dm-terminal {
  background: #191A15;
  overflow: hidden;
}

.dm-term-body {
  position: absolute;
  inset: 0;
  padding: 18px 20px;
  overflow: hidden;
  font-family: var(--dm-font-mono);
  color: var(--dm-neutral-400);
  white-space: pre-wrap;
  transition: opacity 220ms linear;
}

.dm-terminal.is-wiping .dm-term-body { opacity: 0; }
.dm-motion .dm-terminal .dm-term-body::after { content: "▍"; animation: dm-caret 1.1s steps(2) infinite; }

@keyframes dm-caret { 50% { opacity: 0; } }

/* ==========================================================================
   Features — frameless cards
   ========================================================================== */
.dm-features .dm-h2 { max-width: 18ch; }

/* 12 columns so the bottom row fits four: three feature tiles + the dark CTA */
.dm-features-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 48px 24px;
}

/* every card links out; the arrow chip answers on hover */
.dm-feat {
  display: flex;
  flex-direction: column;
  position: relative;
  grid-column: span 4;
  color: inherit;
  text-decoration: none;
}

.dm-feat > .dm-tile-arrow { top: 0; right: 0; }
.dm-feat-card > .dm-tile-arrow { top: 22px; right: 22px; }

.dm-feat--wide { grid-column: span 8; }

.dm-feat h3 {
  font-size: 17px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--dm-ink);
}

.dm-feat p {
  font-size: 15px;
  line-height: 1.55;
  color: var(--dm-text-secondary);
  margin-top: 10px;
}

.dm-feat--wide p { max-width: 72ch; }

.dm-feat .dm-render {
  margin-top: 24px;
  flex: 1;
  min-height: 260px;
}

.dm-feat--wide .dm-render { min-height: 300px; }

/* the AI editor card is two layers: the ground is CSS — gradient stops sampled
   from the design composite, plus the shared grain — and the editor window
   rides on top as its own element, so responsive scales the window instead of
   cropping a baked image. */
.dm-editor-shot {
  position: relative;
  overflow: hidden;
  background: linear-gradient(112deg, #4b9e8c, #64a97e 30%, #8dbb64 58%, #a4c455);
  display: grid;
  place-items: center;
  padding: clamp(20px, 5%, 52px);
}

.dm-editor-shot > img {
  position: relative;
  inset: auto;
  width: min(100%, 1000px);
  height: auto;
  object-fit: contain;
  border-radius: 10px;
  box-shadow: 0 22px 54px rgba(0, 0, 0, 0.22);
}

/* bulk, shown not told: a masonry of render thumbs that stagger-fills. Explicit
   heights per thumb and multicol balancing, so there is no forced-height /
   aspect interplay to jam a track open. */
/* Was multicol with a fixed pixel height per thumb. Those balanced to exactly
   526px a column against a box the grid stretches to 575 — a 49px dead strip
   along the bottom that read as the tile being shorter than the editor card
   beside it. Fixed content cannot fill a stretched box at every width, so the
   proportions moved into the grid: twenty fractional rows, each thumb spanning
   a share of them. The column totals stay equal, the varied thumb sizes
   survive, and it fills exactly whatever height the row is given. */
.dm-gridfill {
  display: grid;
  grid-auto-flow: column;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(20, 1fr);
  gap: 8px;
  height: 100%;
}

.dm-gridfill span {
  display: block;
  width: auto;
  height: auto;
  border-radius: 8px;
  background-size: cover;
  background-position: center;
}

/* spans per thumb — each column adds to 20 */
.dm-gridfill span:nth-child(1) { grid-row: span 8; }
.dm-gridfill span:nth-child(2) { grid-row: span 5; }
.dm-gridfill span:nth-child(3) { grid-row: span 7; }
.dm-gridfill span:nth-child(4) { grid-row: span 6; }
.dm-gridfill span:nth-child(5) { grid-row: span 8; }
.dm-gridfill span:nth-child(6) { grid-row: span 6; }
.dm-gridfill span:nth-child(7) { grid-row: span 7; }
.dm-gridfill span:nth-child(8) { grid-row: span 5; }
.dm-gridfill span:nth-child(9) { grid-row: span 8; }

.dm-motion .dm-gridfill[data-dm-reveal-group] > * { transform: translateY(10px) scale(0.85); }

.dm-motion .dm-gridfill[data-dm-reveal-group].is-in > * {
  transform: translateY(0) scale(1);
  transition-duration: 480ms;
}

/* the three icon cards: a paper card opens with a bare thin-line mark (no
   chip), the text right below it in the section's own type */
.dm-feat-card {
  background: var(--dm-surface-card);
  border-radius: var(--dm-radius-card);
  padding: 28px;
  display: flex;
  flex-direction: column;
  gap: 20px;
  grid-column: span 3;
}

.dm-chip-icon { color: var(--dm-ink); flex: none; }
.dm-chip-icon svg { display: block; width: 32px; height: 32px; }

/* the section's own conversion answer — the contrast-dark card, fourth in the
   bottom row */
.dm-feat-cta {
  grid-column: span 3;
  background: var(--dm-surface-dark);
  border-radius: var(--dm-radius-card);
  padding: 28px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
}

.dm-feat-cta p {
  font-size: 17px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--dm-surface-page);
  margin: 0;
}

/* ==========================================================================
   Templates — the category slider
   ========================================================================== */
.dm-templates .dm-sec-head { align-items: center; margin-bottom: 36px; }
.dm-templates .dm-h2 { max-width: 20ch; margin-bottom: 0; }

.dm-cat-card {
  position: relative;
  flex: 0 0 min(300px, 74vw);
  height: 380px;
  border-radius: var(--dm-radius-card);
  overflow: hidden;
  background-size: cover;
  background-position: center;
  background-color: var(--dm-surface-card);
  scroll-snap-align: start;
}

.dm-motion .dm-cat-card { transition: transform .35s var(--dm-ease-press); }
.dm-motion .dm-cat-card:hover { transform: translateY(-4px); }

.dm-cat-card .dm-pill { top: auto; bottom: 14px; }

.dm-cat-card--discover {
  background: var(--dm-surface-dark);
  display: grid;
  place-items: center;
  text-align: center;
  text-decoration: none;
}

.dm-cat-card--discover span {
  font-family: var(--dm-font-body);
  font-weight: 500;
  font-size: 22px;
  line-height: 1.35;
  letter-spacing: -0.01em;
  color: var(--dm-surface-page);
  padding: 0 24px;
}

/* ==========================================================================
   Integrations — per-brand gradient + grain tiles
   --------------------------------------------------------------------------
   Colours picked from each brand's icon and mapped to the nearest DM ramp,
   with the CTA's gradient logic: a neighbouring hue opens the top-left corner,
   then the brand's 50 → 200. Each tile gets its own angle or shape so the grid
   doesn't read as one repeated swatch. Ink titles; body text takes the ramp's
   900 step so it holds ≥4.5:1 on the deepest stop.
   ========================================================================== */
.dm-integrations .dm-h2 { max-width: 18ch; }

.dm-int-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 24px;
}

.dm-int-tile {
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  position: relative;
  overflow: hidden;
  border-radius: var(--dm-radius-card);
  text-decoration: none;
  color: inherit;
}

/* Lift the tile's content above the grain layer — but not the arrow chip, which
   is absolutely positioned by base.css. In the design both rules live in one
   stylesheet with the arrow declared last, so it won; here base.css loads first,
   so an unqualified `> *` would silently drop the arrow back into flow and add
   ~45px to the top of every tile. */
.dm-int-tile > *:not(.dm-tile-arrow) { position: relative; }

.dm-int-tile h3 {
  font-size: 16px;
  font-weight: 600;
  color: var(--dm-ink);
}

.dm-int-tile p {
  font-size: 14px;
  line-height: 1.5;
  color: var(--dm-text-secondary);
  margin: 0;
}

/* slightly desaturated: openers mix 15% white, deep stops 20% — a nudge, not
   a ramp step */
.dm-int-tile--ps { background: linear-gradient(135deg, color-mix(in oklab, var(--dm-purple-100) 85%, white), var(--dm-blue-50) 45%, color-mix(in oklab, var(--dm-blue-200) 80%, white)); }
.dm-int-tile--ps p { color: var(--dm-blue-900); }

.dm-int-tile--etsy { background: linear-gradient(215deg, color-mix(in oklab, var(--dm-pink-100) 85%, white), var(--dm-orange-50) 45%, color-mix(in oklab, var(--dm-orange-200) 80%, white)); }
.dm-int-tile--etsy p { color: var(--dm-orange-900); }

.dm-int-tile--shopify { background: radial-gradient(140% 140% at 12% 8%, color-mix(in oklab, var(--dm-lime-100) 85%, white), var(--dm-green-50) 45%, color-mix(in oklab, var(--dm-green-200) 80%, white)); }
.dm-int-tile--shopify p { color: var(--dm-green-900); }

.dm-int-tile--wp { background: linear-gradient(25deg, color-mix(in oklab, var(--dm-cyan-100) 85%, white), var(--dm-mint-50) 45%, color-mix(in oklab, var(--dm-mint-200) 80%, white)); }
.dm-int-tile--wp p { color: var(--dm-mint-900); }

.dm-int-tile--zapier { background: linear-gradient(350deg, color-mix(in oklab, var(--dm-orange-100) 85%, white), var(--dm-red-50) 45%, color-mix(in oklab, var(--dm-red-200) 80%, white)); }
.dm-int-tile--zapier p { color: var(--dm-red-900); }

.dm-int-tile--make { background: radial-gradient(150% 150% at 88% 12%, color-mix(in oklab, var(--dm-pink-100) 85%, white), var(--dm-purple-50) 45%, color-mix(in oklab, var(--dm-purple-200) 80%, white)); }
.dm-int-tile--make p { color: var(--dm-purple-900); }

/* the AI tile goes neutral gray — the assistants aren't one brand */
.dm-int-tile--ai {
  grid-column: span 2;
  background: linear-gradient(105deg, color-mix(in oklab, var(--dm-neutral-100) 85%, white), var(--dm-neutral-50) 40%, color-mix(in oklab, var(--dm-neutral-200) 80%, white));
}

.dm-int-tile--ai p { color: var(--dm-neutral-900); }

.dm-assistants {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 2px;
}

.dm-assistants span {
  display: inline-flex;
  background: var(--dm-surface-white);
  border-radius: 999px;
  padding: 5px 12px;
  font-size: 12px;
  color: var(--dm-ink);
}

/* marks keep their own baked backgrounds; only Shopify gets a white one — its
   original box was a gray-green that clashed with the tile gradient */
.dm-int-mark {
  width: 40px;
  height: 40px;
  border-radius: 14px;
  display: block;
  flex: none;
}

.dm-int-tile--shopify .dm-int-mark {
  background: var(--dm-surface-white);
  box-shadow: inset 0 0 0 1px rgba(33, 34, 29, 0.06);
}

/* the see-all sits in the section head now, opposite the title */
.dm-integrations .dm-sec-head { align-items: center; }
.dm-integrations .dm-h2 { margin-bottom: 0; }

/* The tile still lifts on hover; the mark itself no longer stamps. The
   dm-stamp keyframes went with it — that rule was its only user. */
.dm-motion .dm-int-tile { transition: transform .35s var(--dm-ease-press); }
.dm-motion .dm-int-tile:hover { transform: translateY(-2px); }

/* ==========================================================================
   Reviews
   ========================================================================== */
.dm-reviews .dm-sec-head { align-items: center; margin-bottom: 44px; }
.dm-reviews .dm-h2 { margin-bottom: 0; }

/* One review lifted out of the carousel and set as a pull-quote. This is where
   the section earns its serif: a person is speaking, and at 32px Fraunces is an
   editorial moment rather than the legibility downgrade it would be at the
   15px of a card. The section head above it stays Geist — it is a label, not a
   voice — so the serif marks the human, not the furniture. Quote is verbatim;
   the card it replaced was removed from the track rather than duplicated. */
.dm-review-pull {
  margin: 0 0 44px;
}

/* measure lives on the blockquote, not the figure — `ch` has to resolve against
   the display size to mean anything (32ch of 16px Geist is half the line the
   quote wants) */
.dm-review-pull blockquote {
  max-width: 32ch;
  font-family: var(--dm-font-display);
  font-weight: 300;
  font-size: clamp(24px, 2.6vw, 32px);
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--dm-ink);
  margin: 0;
}

/* two globals reach in here and have to be answered explicitly: the parent
   theme italicises every figcaption, and the blog stylesheet (loaded
   site-wide) centres them. The attribution reads as a byline under the quote,
   so it stays plain and flush left. */
.dm-review-pull figcaption {
  margin-top: 16px;
  font-size: 13px;
  line-height: 1.4;
  color: var(--dm-text-secondary);
  text-align: left;
  font-style: normal;
}

.dm-review { padding: 28px; }

.dm-review .dm-review-stars {
  letter-spacing: 3px;
  font-size: 13px;
  margin-bottom: 12px;
  color: var(--dm-orange-500);
}

.dm-review-quote {
  font-size: 15px;
  line-height: 1.55;
  color: var(--dm-neutral-900);
}

.dm-review-by {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 18px;
  font-size: 13px;
  color: var(--dm-text-secondary);
}

.dm-review-by .dm-avatar {
  width: 32px;
  height: 32px;
  font-size: 11px;
  border: 0;
}

.dm-review-by strong { color: var(--dm-ink); }

.dm-car-track .dm-review {
  flex: 0 0 min(380px, 82vw);
  scroll-snap-align: start;
  margin-bottom: 0;
}

/* ==========================================================================
   Final CTA — the page's one gradient moment, contained in a rounded panel.
   The light gradient forces ink text (5.5:1 at its worst point).
   ========================================================================== */
/* A PAPER island — the mirror of the ink islands in dm/pricing.css. This
   panel's ground is the light brand gradient whatever page it lands on, so it
   pins the ink tokens dark: on a `dm-dark` page `--dm-ink` is light, and the
   headline would wash out over the pink. Any section whose ground never
   darkens has to do this. */
.dm-cta-panel {
  --dm-ink: #21221D;
  --dm-text-body: #21221D;
  --dm-text-secondary: #4F5049;
  --dm-text-tertiary: #6F7168;
  --dm-on-ink: #FFFFFF;
  --dm-surface-page: #F4F5F1;
  --dm-surface-white: #FFFFFF;
  --dm-surface-card: #ECEDE5;
  --dm-border-card: #E5E5DF;

  position: relative;
  overflow: hidden;
  border-radius: var(--dm-radius-card);
  background-color: var(--dm-pink-0);
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
  padding: 96px 48px;
  text-align: center;
}

.dm-cta-pattern {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
}

.dm-cta-inner { position: relative; }

.dm-cta-panel h2 {
  font-family: var(--dm-font-display);
  font-weight: 400;
  font-size: clamp(40px, 4.5vw, 56px);
  line-height: 1.04;
  letter-spacing: var(--dm-tracking-display);
  color: var(--dm-ink);
  margin: 0 auto 20px;
  max-width: 20ch;
}

.dm-cta-sub {
  font-size: 16px;
  line-height: 1.5;
  color: var(--dm-ink);
  margin: 0 auto 32px;
  max-width: 52ch;
}

.dm-cta-actions {
  display: flex;
  gap: 12px;
  justify-content: center;
  flex-wrap: wrap;
}

/* ==========================================================================
   FAQ
   ========================================================================== */
.dm-faq-grid {
  display: grid;
  grid-template-columns: 1fr 1.7fr;
  gap: 64px;
  align-items: start;
}

.dm-faq-rail { position: sticky; top: 104px; }

.dm-faq-rail p {
  font-size: 15px;
  line-height: 1.55;
  color: var(--dm-text-secondary);
  margin-top: 16px;
}

.dm-faq-rail a {
  display: inline-block;
  margin-top: 18px;
  font-size: 15px;
  font-weight: 700;
}

.dm-faq-list details { padding: 22px 0; }

.dm-faq-list summary {
  font-weight: 600;
  font-size: 17px;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  gap: 16px;
  color: var(--dm-ink);
}

.dm-faq-toggle {
  color: var(--dm-text-tertiary);
  font-weight: 400;
}

.dm-faq-toggle::after {
  content: "+";
  display: inline-block;
  transition: transform .3s var(--dm-ease-press);
}

.dm-faq-list details[open] .dm-faq-toggle::after { transform: rotate(45deg); }

.dm-faq-body {
  overflow: hidden;
}

.dm-faq-list details p {
  margin-top: 12px;
  color: var(--dm-text-secondary);
  line-height: 1.55;
  font-size: 15px;
}

.dm-faq-list code {
  font-family: var(--dm-font-mono);
  font-size: 13px;
  background: var(--dm-surface-card);
  border-radius: var(--dm-radius-badge);
  padding: 2px 6px;
}

/* Open/close is animated by sections.js (see the FAQ block there): it measures the
   answer and eases its height, which works in every browser — the CSS-only
   ::details-content transition this replaced is Chromium-only. */

/* ==========================================================================
   Responsive — per the handoff's recommendations
   ========================================================================== */
@media (max-width: 1100px) {
  .dm-trust-grid { grid-template-columns: 1fr; gap: 48px; }
  .dm-trust-copy .dm-h2 { margin-bottom: 20px; }

  .dm-path-card { grid-template-columns: 1fr; gap: 28px; padding: 32px; }
  .dm-path-card .dm-render { min-height: 240px; }

  /* Not .dm-paths-grid: sections.js makes it a grid (is-deck) at every width
     and pins both cards to column 1, so two columns here halved the visible
     card on phones and tablets. It stays a single implicit column. */
  .dm-features-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .dm-feat,
  .dm-feat--wide,
  .dm-feat-card,
  .dm-feat-cta { grid-column: auto; }

  .dm-int-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .dm-faq-grid { grid-template-columns: 1fr; gap: 40px; }
  .dm-faq-rail { position: static; }
}

@media (max-width: 720px) {
  .dm-hero h1 { font-size: clamp(34px, 9vw, 44px); }

  .dm-trust .dm-container { padding-block: 72px; }
  .dm-trust-stats > div { padding-inline: 16px; }
  .dm-trust-stats dt { font-size: 30px; }
  .dm-rating { flex-wrap: wrap; row-gap: 10px; }
  .dm-logo-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .dm-path-card { padding: 28px 24px; }

  .dm-features-grid,
  .dm-int-grid { grid-template-columns: 1fr; }

  .dm-int-tile--ai { grid-column: auto; }

  .dm-cat-card { height: 320px; }

  .dm-cta-panel h2 { font-size: clamp(30px, 8.5vw, 40px); }
  .dm-cta-panel { padding: 64px 24px; }
}

@media (max-width: 480px) {
  /* stats wrap here — a wrapped item's left border reads as a stray line */
  .dm-trust-stats { gap: 20px 32px; }
  .dm-trust-stats > div { border-left: 0; padding-inline: 0; }
}

/* A how-it-works reads better ending on the action than trailing off after the
   last step. Opt-in: pass cta_label. */
.dm-steps-cta {
  margin-top: 40px;
  text-align: center;
}

/* ---- prompt-chips: example prompts that fill the composer (dm/prompt-chips.js) ----
   Sits tight under the hero: no top padding of its own. Buttons reset every
   box property the theme's global style.min.css leaks onto bare <button>. */
.dm-pchips { padding-top: 0; padding-bottom: 56px; }
.dm-pchips .dm-container { padding-top: 0; }

.dm-pchips-head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  margin-bottom: 18px;
  text-align: center;
}

.dm-pchips-row {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
}

.dm-pchip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  padding: 10px 16px;
  border: 1px solid var(--dm-border-card);
  border-radius: 999px;
  background: var(--dm-surface-white);
  box-shadow: none;
  appearance: none;
  font-family: var(--dm-font-body);
  font-size: 14px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--dm-ink);
  text-align: left;
  white-space: normal;
  max-width: 100%;
  cursor: pointer;
  transition: border-color .15s ease, background .15s ease, transform .15s ease;
}

.dm-pchip:hover { border-color: var(--dm-ink); }
.dm-pchip:active { transform: translateY(1px); }
.dm-pchip:focus-visible { outline: 2px solid var(--dm-accent-primary); outline-offset: 2px; }
.dm-pchip svg { color: var(--dm-text-tertiary); flex: none; }
.dm-pchip.is-used { background: var(--dm-surface-page); border-color: var(--dm-ink); }

@media (max-width: 640px) {
  .dm-pchips { padding-bottom: 40px; }
  .dm-pchips-row { justify-content: flex-start; }
  .dm-pchip { font-size: 13px; padding: 9px 14px; }
}
