/* Caret — landing comparison, Fable programmatic product-demo revision.
   Warm Ink & Caret system; preserved hero/privacy band, sticky header,
   three Download Caret CTAs, and symmetric feature rows. Every product
   figure is now a live, looping programmatic demo: a coded iPhone-style
   app surface over a coded recreation of the Caret keyboard (.ckb).
   No screenshots, video, external fonts, or dependencies. demos.js runs
   the per-demo state machines; without it (or with reduced motion) each
   demo renders its complete final state. */

:root {
  color-scheme: light;
  --paper: #f7f5f0;
  --ink: #14161a;
  --signal: #e2571a;
  --muted: #6e7480;
  --line: #e3dfd6;
  --signal-soft: #f8e9df;
  --card: #fdfcfa;
  --keyboard-tan: #f7f5f0;
  --mono: Menlo, Monaco, "Courier New", monospace;
  --ios: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, Arial, sans-serif;
  --blue: #007aff;
  --max: 1120px;
  --gutter: clamp(20px, 5vw, 56px);
  --band: clamp(52px, 6.5vw, 88px);
  --header-h: 84px;
}

* {
  box-sizing: border-box;
}

html {
  /* keep in-page anchor targets clear of the sticky header */
  scroll-padding-top: calc(var(--header-h) + 12px);
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 16px;
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;
}

img,
svg {
  display: block;
  max-width: 100%;
}

a {
  color: inherit;
  text-decoration: none;
}

h1,
h2,
h3,
p,
dl,
dd,
figure {
  margin: 0;
}

.skip-link {
  position: fixed;
  z-index: 10;
  top: 14px;
  left: 14px;
  padding: 10px 14px;
  background: var(--ink);
  color: var(--paper);
  font-size: 14px;
  transform: translateY(-220%);
}

.skip-link:focus {
  transform: translateY(0);
}

:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 4px;
}

.site-header-inner,
.hero,
.pair,
.closing,
.site-footer {
  width: min(100%, var(--max));
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* ---------- header ---------- */

.site-header {
  position: sticky;
  z-index: 5;
  top: 0;
  border-bottom: 1px solid var(--line);
  background: var(--paper);
  background: rgba(247, 245, 240, 0.94);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}

.site-header-inner {
  display: flex;
  min-height: var(--header-h);
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-size: 20px;
  font-weight: 500;
  letter-spacing: -0.01em;
}

.brand-mark {
  width: 34px;
  height: 34px;
  fill: var(--ink);
}

.brand-mark .brand-stem {
  fill: var(--signal);
}

.button {
  display: inline-flex;
  min-height: 44px;
  padding: 0 22px;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: var(--signal);
  color: var(--ink);
  font-size: 15px;
  font-weight: 500;
  line-height: 1;
  transition: background-color 140ms ease, color 140ms ease;
}

.button:hover {
  background: var(--ink);
  color: var(--paper);
}

/* the Download Caret CTAs are real <button>s (they open the coming-soon
   dialog rather than navigate); strip UA chrome so they render exactly
   like the anchor CTAs */
button.button {
  margin: 0;
  border: 0;
  font-family: inherit;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
}

/* ---------- editorial bits ---------- */

.kicker {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.kicker-no {
  padding: 3px 9px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--ink);
  letter-spacing: 0.08em;
}

.kicker + h2 {
  margin-top: 18px;
  font-size: clamp(26px, 2.6vw, 36px);
  font-weight: 600;
  letter-spacing: -0.024em;
  line-height: 1.12;
  text-wrap: balance;
}

.copy {
  max-width: 26em;
  margin-top: 14px;
  color: var(--muted);
  font-size: clamp(16px, 1.25vw, 17.5px);
  line-height: 1.6;
}

/* ---------- iPhone chrome ---------- */

.phone {
  position: relative;
  container-type: inline-size;
  padding: 10px;
  border-radius: 15% / 6.9%;
  background: var(--ink);
  box-shadow:
    inset 0 0 0 1px rgba(247, 245, 240, 0.07),
    0 1px 2px rgba(20, 22, 26, 0.08),
    0 22px 44px -20px rgba(20, 22, 26, 0.32);
}

/* Dynamic Island */
.phone::before {
  content: "";
  position: absolute;
  z-index: 4;
  top: calc(10px + 1.5%);
  left: 50%;
  width: 27%;
  height: 2.9%;
  transform: translateX(-50%);
  border-radius: 999px;
  background: #0a0b0d;
}

/* volume keys, left edge */
.phone::after {
  content: "";
  position: absolute;
  top: 21%;
  left: -2px;
  width: 2.5px;
  height: 5%;
  border-radius: 2px 0 0 2px;
  background: #24272d;
  box-shadow: 0 0 0 0 #24272d, 0 52px 0 0 #24272d;
}

/* power key, right edge */
.phone-key {
  position: absolute;
  top: 24.5%;
  right: -2px;
  width: 2.5px;
  height: 7.5%;
  border-radius: 0 2px 2px 0;
  background: #24272d;
}

/* ---------- programmatic screen ---------- */

.screen {
  position: relative;
  display: flex;
  flex-direction: column;
  aspect-ratio: 853 / 1844;
  overflow: hidden;
  border-radius: 12.2% / 5.6%;
  background: #fff;
  font-family: var(--ios);
  /* Top-chrome contract, shared by every programmatic app surface:
       0 → ~9.3cqw   status bar + Dynamic Island overlay zone (z 3–4;
                     the island bottom lands at ~9.3cqw from screen top)
       --chrome-top  each app header owns this safe-area inset as
                     padding-top, so its background material extends
                     behind the status bar exactly like iOS nav bars
       header row    the app's own nav content (back / title / tools),
                     closed by its border or bottom padding
       content       first scroll row starts in flow below the header;
                     nothing may render above or beneath the header.
     12cqw clears the island bottom with ~2.7cqw of breathing room at
     every phone size (island geometry scales with phone width). */
  --chrome-top: 12cqw;
}

.statusbar {
  position: absolute;
  z-index: 3;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 2.6cqw 7.5cqw 0 9cqw;
  color: #0b0c0e;
}

.sb-time {
  font-size: 3.7cqw;
  font-weight: 600;
  letter-spacing: 0.01em;
}

.sb-svg {
  width: 16.5cqw;
  height: auto;
}

.app {
  position: relative;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: opacity 0.3s ease;
}

/* Every app header owns the safe area (see .screen contract above). */
.msg-head,
.notes-head,
.mail-nav,
.team-head {
  padding-top: var(--chrome-top);
}

/* =============================================================
   .ckb — programmatic recreation of the Caret keyboard.
   Geometry and colors are transcribed from qa/keyboard-reference.png
   (1206x858); every offset below is a percentage of that box, so the
   component scales losslessly. qa/keyboard_similarity.py renders this
   component at native size and scores it against the reference.
   ============================================================= */

.ckb {
  position: relative;
  container-type: inline-size;
  width: 100%;
  margin-top: auto;
  aspect-ratio: 1206 / 858;
  flex: none;
  background: var(--keyboard-tan);
  border-radius: 4cqw 4cqw 0 0;
  overflow: hidden;
  font-family: var(--ios);
  user-select: none;
}

.ckb > span {
  position: absolute;
}

/* top drawer lip. The standalone QA target keeps the screenshot-derived
   divider; inside a phone, the stage continues in the keyboard tan. */
.ckb-lip {
  top: 0;
  left: 0;
  right: 0;
  height: 5.6%;
  background: #e2e3e7;
}

.screen .ckb-lip {
  background: var(--keyboard-tan);
  border-top: 1px solid #e2ded5;
}

/* Dictate / Ask / Imagine segmented control */
.ckb-track {
  left: 3.48%;
  top: 7.69%;
  width: 93.03%;
  height: 10.14%;
  background: #e7e5e2;
  border-radius: 999px;
}

.ckb-pill {
  left: 3.98%;
  top: 8.39%;
  width: 29.85%;
  height: 8.74%;
  background: #d2602f;
  border-radius: 999px;
  transition: left 0.38s cubic-bezier(0.3, 0.7, 0.3, 1);
}

.ckb--ask .ckb-pill {
  left: 34.83%;
}

.ckb--imagine .ckb-pill {
  left: 66%;
}

.ckb-tabs {
  left: 3.31%;
  top: 7.69%;
  width: 93.03%;
  height: 10.14%;
  display: flex;
}

.ckb-tab {
  flex: 1;
  display: grid;
  place-items: center;
  font-size: 3.02cqw;
  font-weight: 500;
  color: #6f7480;
  transition: color 0.25s ease, font-weight 0.25s ease;
}

.ckb-tab--dictate,
.ckb--ask .ckb-tab--ask,
.ckb--imagine .ckb-tab--imagine {
  color: #141519;
  font-weight: 700;
}

.ckb--ask .ckb-tab--dictate,
.ckb--imagine .ckb-tab--dictate {
  color: #6f7480;
  font-weight: 500;
}

/* hint line — variants toggled per demo state */
.ckb-hint {
  left: -0.41%;
  right: 0.41%;
  top: 23.51%;
  text-align: center;
  font-size: 3.63cqw;
  font-weight: 500;
  letter-spacing: 0.012em;
  color: #6f7480;
  line-height: 1.15;
}

.ckb-hint span {
  display: none;
}

.ckb-hint .h-base {
  display: block;
}

.ckb--ask .ckb-hint .h-base,
.ckb--imagine .ckb-hint .h-base {
  display: none;
}

.ckb--ask .ckb-hint .h-ask,
.ckb--imagine .ckb-hint .h-imagine {
  display: block;
}

/* secondary controls */
.ckb-radio {
  left: 2.49%;
  top: 30.89%;
  width: 6.88%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: #d2602f;
  color: #141519;
  display: grid;
  place-items: center;
}

.ckb-radio svg {
  width: 57%;
}

.ckb-history {
  left: 3.49%;
  top: 45.11%;
  width: 5.31%;
  color: #6f7480;
}

.ckb-kbdic {
  left: 91.17%;
  top: 32.82%;
  width: 5.95%;
  color: #6f7480;
}

.ckb-share {
  left: 91.43%;
  top: 45.43%;
  width: 4.45%;
  color: #6f7480;
}

/* waveform rails become organic bars while the microphone is active */
.ckb-dots {
  top: 37.8%;
  width: 29.76%;
  height: 8.6%;
  display: flex;
  align-items: center;
  justify-content: space-around;
}

.ckb-dots--l {
  left: 10.89%;
}

.ckb-dots--r {
  left: 59.42%;
}

.ckb-dots i {
  display: block;
  width: 0.82cqw;
  height: 0.82cqw;
  border-radius: 999px;
  background: #c0bfbc;
  transform-origin: center;
}

/* central microphone control */
.ckb-record {
  left: 42.54%;
  top: 31.7%;
  width: 14.84%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(120% 120% at 38% 30%, #c95f31 0%, #c0582b 55%, #b95229 100%);
  box-shadow: 0 0.3cqw 2.8cqw rgba(80, 62, 50, 0.5);
  transition: transform 180ms ease, box-shadow 240ms ease, background 240ms ease;
}

.ckb-record::after {
  content: "";
  position: absolute;
  inset: 31%;
  border-radius: 50%;
  background: #f8f2eb;
  box-shadow: inset 0 0 0 0.4cqw rgba(93, 42, 23, 0.18);
  opacity: 0;
  transform: scale(0.4);
  transition: opacity 180ms ease, transform 220ms ease;
}

/* backspace / space / return row */
.ckb-keys {
  position: absolute;
  left: 3.48%;
  right: 3.57%;
  top: 56.5%;
  height: 14.8%;
  display: flex;
  justify-content: space-between;
}

.ckb-key {
  background: #fdfcfa;
  border-radius: 1.95cqw;
  box-shadow: 0 0.14cqw 0.3cqw rgba(20, 21, 25, 0.09),
    0 0.5cqw 0.9cqw rgba(20, 21, 25, 0.1);
  color: #141519;
  display: grid;
  place-items: center;
}

.ckb-key--bs,
.ckb-key--ret {
  width: 24.55%;
}

.ckb-key--space {
  width: 46.5%;
}

.ckb-key--bs svg {
  width: 25.1%;
  transform: translate(-1.4%, 1.7%);
}

.ckb-key--ret svg {
  width: 24.4%;
  transform: translate(-12%, 7%);
}

/* bottom globe / mic bar */
.ckb-barbg {
  left: 0;
  right: 0;
  bottom: 0;
  height: 20%;
  background: #fff;
}

.ckb-bar {
  left: 0.17%;
  right: 0.25%;
  bottom: 0.12%;
  height: 26.1%;
  background: #e3e4e7;
  border-radius: 2cqw;
  color: #141519;
}

.ckb-globe {
  position: absolute;
  left: 7.16%;
  top: 29%;
  width: 6.63cqw;
}

.ckb-mic {
  position: absolute;
  left: 87.34%;
  top: 28.14%;
  width: 4.56cqw;
}

/* ---------- shared app-surface bits ---------- */

.typed {
  white-space: pre-wrap;
}

.tcaret {
  display: none;
  flex: none;
  width: 0.45cqw;
  min-width: 1.5px;
  height: 4.8cqw;
  margin-left: 0.3cqw;
  border-radius: 1px;
  background: var(--blue);
  vertical-align: text-bottom;
  animation: tcaret-blink 1.05s steps(1) infinite;
}

@keyframes tcaret-blink {
  50% {
    opacity: 0;
  }
}

.composer {
  display: flex;
  align-items: center;
  gap: 2.6cqw;
  padding: 1.8cqw 3.4cqw 2.8cqw;
}

.plus {
  flex: none;
  width: 8.6cqw;
  height: 8.6cqw;
  border-radius: 50%;
  background: #e9e9eb;
  color: #5f6368;
  display: grid;
  place-items: center;
  font-size: 5.6cqw;
  font-weight: 400;
  line-height: 1;
}

.field {
  position: relative;
  flex: 1;
  display: flex;
  align-items: center;
  min-height: 9.4cqw;
  padding: 1.5cqw 9.4cqw 1.5cqw 3.8cqw;
  border: 1px solid #d8d8dc;
  border-radius: 999px;
  font-size: 4.1cqw;
  line-height: 1.3;
  color: #0b0c0e;
}

.ph {
  position: absolute;
  left: 3.8cqw;
  color: #8e8e93;
}

.send {
  position: absolute;
  right: 0.9cqw;
  top: 50%;
  transform: translateY(-50%);
  display: none;
  width: 7.4cqw;
  height: 7.4cqw;
  border-radius: 50%;
  background: var(--blue);
  place-items: center;
  transition: transform 0.16s ease;
}

.send svg {
  width: 62%;
}

/* processing ellipsis */
.adots i {
  display: inline-block;
  font-style: normal;
  animation: adot 1.2s infinite;
}

.adots i:nth-child(2) {
  animation-delay: 0.2s;
}

.adots i:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes adot {
  0%,
  60%,
  100% {
    opacity: 0.25;
  }
  30% {
    opacity: 1;
  }
}

/* ---------- Messages surface (demos 01 + 05) ---------- */

.app-messages {
  background: #fff;
}

.msg-head {
  position: relative;
  display: grid;
  justify-items: center;
  padding-inline: 4cqw;
  padding-bottom: 1.6cqw;
  border-bottom: 1px solid #ebebee;
  background: rgba(250, 250, 251, 0.95);
}

.msg-back {
  position: absolute;
  left: 4cqw;
  top: calc(var(--chrome-top) + 2.6cqw);
  width: 2.6cqw;
  color: var(--blue);
}

/* In flow: the avatar + name column gives the header its real height,
   so it can never slide under the island or over the first message. */
.msg-id {
  display: grid;
  justify-items: center;
  gap: 0.9cqw;
}

.avatar {
  width: 9.6cqw;
  height: 9.6cqw;
  border-radius: 50%;
  background: linear-gradient(180deg, #a7abb5, #8e93a0);
  color: #fff;
  display: grid;
  place-items: center;
  font-size: 4.4cqw;
  font-weight: 600;
}

.gavatars {
  display: flex;
}

.gavatars .avatar {
  width: 8.2cqw;
  height: 8.2cqw;
  font-size: 3.6cqw;
  border: 0.5cqw solid #fafafb;
}

.gavatars .avatar + .avatar {
  margin-left: -2.6cqw;
}

.av-a {
  background: linear-gradient(180deg, #4fa3a5, #3c8486);
}

.av-s {
  background: linear-gradient(180deg, #cf8d4e, #b57538);
}

.av-l {
  background: linear-gradient(180deg, #8d85c9, #6f66b0);
}

.msg-name {
  font-size: 2.9cqw;
  color: #3c3c43;
}

.thread {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 1.1cqw;
  padding: 2cqw 3.8cqw 1.4cqw;
  overflow: hidden;
}

.stamp {
  align-self: center;
  color: #8e8e93;
  font-size: 2.9cqw;
  font-weight: 500;
  margin-bottom: 1cqw;
}

.sender {
  color: #8e8e93;
  font-size: 2.8cqw;
  margin: 0.6cqw 0 -0.3cqw 3.4cqw;
}

.msg {
  max-width: 74%;
  padding: 2cqw 3.6cqw 2.2cqw;
  border-radius: 4.6cqw;
  font-size: 4.05cqw;
  line-height: 1.32;
  letter-spacing: -0.01em;
}

.msg.in {
  align-self: flex-start;
  background: #e9e9eb;
  color: #000;
  border-bottom-left-radius: 1.4cqw;
}

.msg.out {
  align-self: flex-end;
  background: var(--blue);
  color: #fff;
  border-bottom-right-radius: 1.4cqw;
}

.meta {
  align-self: flex-end;
  color: #8e8e93;
  font-size: 2.8cqw;
  font-weight: 500;
  margin-right: 1cqw;
}

.reaction {
  align-self: flex-end;
  margin: -1.2cqw 2cqw 0 0;
  padding: 0.7cqw 1.6cqw;
  border: 1px solid #d8d8dc;
  border-radius: 999px;
  background: #fff;
  color: #5f6368;
  font-size: 2.7cqw;
  font-weight: 600;
}

/* group-chat sticker */
.sticker-line {
  align-self: flex-end;
  margin: 1cqw 0 0;
}

/* No shadow or surface behind the artwork: the sticker's white field
   merges into the white thread so only its die-cut edge reads. */
.sent-sticker {
  width: 34cqw;
  height: auto;
}

.gen-box {
  display: none;
  flex: none;
  width: 6.9cqw;
  height: 6.9cqw;
  border-radius: 1.8cqw;
  background: linear-gradient(100deg, #ece9e2 32%, #faf8f2 48%, #ece9e2 64%);
  background-size: 220% 100%;
  animation: shimmer 1.15s linear infinite;
}

@keyframes shimmer {
  from {
    background-position: 120% 0;
  }
  to {
    background-position: -100% 0;
  }
}

.gen-label {
  display: none;
  margin-left: 2.2cqw;
  color: #8e8e93;
  font-size: 3.7cqw;
}

.compose-sticker {
  display: none;
  width: 8.8cqw;
  height: auto;
  border-radius: 1.6cqw;
}

/* ---------- Notes surface (demo 02) ---------- */

.app-notes {
  background: #fbfaf5;
  color: #33322e;
}

.notes-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-inline: 4.4cqw;
  padding-bottom: 1.8cqw;
  color: #c08a00;
}

.notes-back {
  display: inline-flex;
  align-items: center;
  gap: 1.4cqw;
  font-size: 4.2cqw;
}

.notes-back svg {
  width: 2.4cqw;
}

.notes-tools {
  display: inline-flex;
  gap: 4cqw;
}

.notes-tools svg {
  width: 5.2cqw;
}

.notes-title {
  padding: 2.4cqw 5cqw 0;
  font-size: 5.6cqw;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.notes-time {
  padding: 1cqw 5cqw 0;
  color: #9b9891;
  font-size: 3.2cqw;
}

.notes-p {
  padding: 2.6cqw 5cqw 0;
  font-size: 4.05cqw;
  line-height: 1.45;
}

.ncaret {
  display: inline-block;
  background: #c08a00;
}

/* ---------- Mail surface (demo 03) ---------- */

.app-mail {
  background: #fff;
  font-size: 4.05cqw;
}

.mail-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-inline: 4.4cqw;
  padding-bottom: 2cqw;
}

.mail-cancel {
  color: var(--blue);
}

.mail-title {
  font-weight: 600;
}

.mail-up {
  width: 7.6cqw;
  color: var(--blue);
}

.mail-field {
  display: flex;
  gap: 1.6cqw;
  padding: 2.4cqw 4.6cqw;
  border-top: 1px solid #ececef;
  font-size: 3.9cqw;
}

.mail-label {
  color: #8e8e93;
}

.mail-chip {
  color: var(--blue);
}

.mail-body {
  flex: 1;
  min-height: 0;
  padding: 3cqw 4.6cqw;
  border-top: 1px solid #ececef;
  line-height: 1.45;
}

.mail-ins {
  margin-top: 2.6cqw;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
}

.mail-ins .typed {
  border-radius: 0.8cqw;
  background: rgba(0, 122, 255, 0.22);
  box-shadow: 0 0 0 0.4cqw rgba(0, 122, 255, 0.22);
}

.dots {
  display: none;
  gap: 1cqw;
  align-items: center;
}

.dots i {
  width: 1.7cqw;
  height: 1.7cqw;
  border-radius: 50%;
  background: #b6b6bc;
  animation: adot 1.2s infinite;
}

.dots i:nth-child(2) {
  animation-delay: 0.2s;
}

.dots i:nth-child(3) {
  animation-delay: 0.4s;
}

.mcaret {
  background: var(--blue);
}

/* ---------- Team-chat surface (demo 04) ---------- */

.app-team {
  background: #fff;
}

.team-head {
  display: grid;
  gap: 0.4cqw;
  padding-inline: 4.6cqw;
  padding-bottom: 2cqw;
  border-bottom: 1px solid #ececef;
}

.team-title {
  font-size: 4.7cqw;
  font-weight: 700;
  letter-spacing: -0.015em;
}

.team-sub {
  color: #8e8e93;
  font-size: 3.2cqw;
}

.team-thread {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 3cqw;
  padding: 2.6cqw 4.6cqw;
  overflow: hidden;
}

.trow {
  display: flex;
  gap: 2.6cqw;
}

.tavatar {
  flex: none;
  width: 8.8cqw;
  height: 8.8cqw;
  border-radius: 2.6cqw;
  color: #fff;
  display: grid;
  place-items: center;
  font-size: 4cqw;
  font-weight: 600;
}

.ta-p {
  background: #3c8486;
}

.ta-t {
  background: #b57538;
}

.tname {
  font-size: 3.6cqw;
  font-weight: 600;
}

.tname span {
  margin-left: 1.2cqw;
  color: #8e8e93;
  font-size: 2.9cqw;
  font-weight: 400;
}

.ttext {
  margin-top: 0.5cqw;
  font-size: 3.95cqw;
  line-height: 1.35;
}

.assist {
  margin: 0 4.6cqw 1.6cqw;
  font-size: 3cqw;
  color: var(--muted);
}

.assist > span {
  display: none;
  align-items: center;
  gap: 1.3cqw;
  padding: 1cqw 2.6cqw;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--card);
}

.assist .assist-done {
  display: inline-flex;
}

.assist-mark {
  color: var(--signal);
  font-weight: 700;
}

.team-composer {
  padding-top: 0;
}

/* =============================================================
   Speech bubbles — true visual overlays in the device stage. They are
   removed from flow and reserve no app, phone, keyboard, or caption space.
   Each sits over the keyboard's safe outer edge and points toward Caret.
   ============================================================= */

.demo-stage {
  position: relative;
  container-type: inline-size;
}

.demo-stage .phone {
  width: 86%;
}

.bubble-left .demo-stage .phone {
  margin-left: auto;
}

.bubble-right .demo-stage .phone {
  margin-right: auto;
}

.bubble {
  position: absolute;
  z-index: 5;
  /* Per-demo offsets below align the bubble bottom to the keyboard top. */
  top: auto;
  max-width: 74%;
  min-width: 48%;
  margin: 0;
  padding: 0.5em 0.9em 0.55em 1.8em;
  border: 1px solid rgba(20, 22, 26, 0.16);
  border-radius: 12px;
  background: var(--card);
  box-shadow:
    0 1px 2px rgba(20, 22, 26, 0.06),
    0 10px 22px -14px rgba(20, 22, 26, 0.35);
  color: var(--ink);
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: clamp(9.5px, 4.5cqw, 13.5px);
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1.35;
  text-align: left;
  transition: opacity 0.22s ease, transform 0.22s ease;
}

/* The overlay is anchored to the natural phone geometry. No app padding,
   spacer, min-height, or grid row is used to make room for it. */
.demo--messages .bubble { bottom: 31.6%; }
.demo--notes .bubble { bottom: 31.3%; }
.demo--mail .bubble { bottom: 31.4%; }
.demo--team .bubble { bottom: 31.4%; }
.demo--brunch .bubble { bottom: 31.3%; }

.bubble-left .bubble {
  left: 0;
}

/* Shorter left-side phrases need a small inward nudge to preserve the
   same 12–25% outside-phone relationship as the longer phrases. */
.bubble-left.demo--messages .bubble {
  left: 7%;
  max-width: 54%;
}

.bubble-left.demo--brunch .bubble {
  left: 2%;
  max-width: 52%;
}

.bubble-right.demo--team .bubble {
  right: -5%;
  max-width: 52%;
}

.bubble-right .bubble {
  right: 0;
}

/* terracotta voice dot, marking the first line */
.bubble::before {
  content: "";
  position: absolute;
  top: 0.98em;
  left: 0.85em;
  width: 0.38em;
  height: 0.38em;
  border-radius: 50%;
  background: var(--signal);
}

/* tail aimed diagonally toward the keyboard's central record control */
.bubble::after {
  content: "";
  position: absolute;
  bottom: -5px;
  width: 8px;
  height: 8px;
  border-right: 1px solid rgba(20, 22, 26, 0.16);
  border-bottom: 1px solid rgba(20, 22, 26, 0.16);
  background: var(--card);
  transform: rotate(45deg);
}

.bubble-left .bubble::after {
  right: 13%;
}

.bubble-right .bubble::after {
  left: 13%;
}

.bubble-text {
  display: inline;
}

@keyframes bubble-arrive {
  from {
    opacity: 0;
    transform: translateY(9px) scale(0.965);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes dot-pulse {
  0%,
  100% {
    transform: scale(1);
    opacity: 1;
  }
  50% {
    transform: scale(1.5);
    opacity: 0.55;
  }
}

/* =============================================================
   Demo state machines (driven by demos.js setting data-state).
   Default markup — no JS, or reduced motion — is the complete
   final state of every loop. `.live` demos start from idle.
   ============================================================= */

/* pause CSS animations while a demo is off-screen */
.demo.demo-paused * {
  animation-play-state: paused !important;
}

/* --- lifecycle overlays --- */

.demo.live:not([data-phase="speech"]) .bubble {
  opacity: 0;
  pointer-events: none;
}

.demo.live[data-phase="stop"] .bubble {
  transform: translateY(5px) scale(0.97);
}

.demo.live[data-phase="speech"] .bubble {
  animation: bubble-arrive 300ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}

.demo.live[data-phase="speech"] .bubble::before {
  animation: dot-pulse 1.1s ease-in-out infinite;
}

/* --- reset dissolve --- */

.demo.live[data-state="reset"] .app {
  opacity: 0;
}

/* --- keyboard: mode + lifecycle states --- */

.ckb-hint .h-listen {
  align-items: baseline;
  justify-content: center;
  gap: 1.2cqw;
}

.ckb-hint .h-listen b,
.ckb-hint .h-transcribing,
.ckb-hint .h-asking,
.ckb-hint .h-imagining {
  font-size: 2.78cqw;
  font-weight: 760;
  letter-spacing: 0.14em;
}

.ckb-timer {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 2.74cqw;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  color: #9b4a28;
}

/* Ask and Imagine remain selected throughout their complete loop. */
.demo.live .ckb--ask .ckb-pill { left: 34.83%; }
.demo.live .ckb--imagine .ckb-pill { left: 66%; }
.demo.live .ckb--ask .ckb-tab--ask,
.demo.live .ckb--imagine .ckb-tab--imagine {
  color: #141519;
  font-weight: 700;
}
.demo.live .ckb--ask .ckb-tab--dictate,
.demo.live .ckb--imagine .ckb-tab--dictate {
  color: #6f7480;
  font-weight: 500;
}
.demo.live .ckb--ask .ckb-hint .h-base,
.demo.live .ckb--imagine .ckb-hint .h-base { display: none; }
.demo.live .ckb--ask .ckb-hint .h-ask,
.demo.live .ckb--imagine .ckb-hint .h-imagine { display: block; }

/* Idle cue is visibly invitational, but quieter than active recording. */
.demo.live:is([data-phase="idle"], [data-phase="context"]) .ckb-record {
  animation: tap-invite 1.8s ease-in-out infinite;
}

/* Physical start and stop taps compress the control and emit a short ring. */
.demo.live:is([data-phase="start"], [data-phase="stop"]) .ckb-record {
  animation: mic-press 220ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

/* Listening and speech are the only genuinely recording phases. */
.demo.live:is([data-phase="listening"], [data-phase="speech"]) .ckb-record {
  animation: rec-pulse 1.25s ease-out infinite;
  box-shadow: 0 0.35cqw 2.9cqw rgba(119, 55, 27, 0.42);
  transform: scale(1.08);
}

.demo.live:is([data-phase="listening"], [data-phase="speech"]) .ckb-record::after {
  opacity: 1;
  transform: scale(1);
}

.demo.live:is([data-phase="listening"], [data-phase="speech"], [data-phase="processing"]) .ckb .ckb-hint :is(.h-base, .h-ask, .h-imagine) {
  display: none;
}

.demo.live:is([data-phase="listening"], [data-phase="speech"]) .ckb-hint .h-listen {
  display: flex;
}

.demo.live[data-phase="processing"] .ckb:not(.ckb--ask):not(.ckb--imagine) .ckb-hint .h-transcribing,
.demo.live[data-phase="processing"] .ckb--ask .ckb-hint .h-asking,
.demo.live[data-phase="processing"] .ckb--imagine .ckb-hint .h-imagining {
  display: block;
}

.demo.live:is([data-phase="listening"], [data-phase="speech"]) .ckb-dots i {
  background: #c55b2d;
  animation: wave-voice 780ms ease-in-out infinite alternate;
}

.demo.live:is([data-phase="listening"], [data-phase="speech"]) .ckb-dots i:nth-child(2n) { animation-duration: 620ms; }
.demo.live:is([data-phase="listening"], [data-phase="speech"]) .ckb-dots i:nth-child(3n) { animation-duration: 920ms; }
.demo.live:is([data-phase="listening"], [data-phase="speech"]) .ckb-dots i:nth-child(4n) { animation-delay: -320ms; }
.demo.live:is([data-phase="listening"], [data-phase="speech"]) .ckb-dots i:nth-child(5n) { animation-delay: -510ms; }
.demo.live:is([data-phase="listening"], [data-phase="speech"]) .ckb-dots--r i { animation-direction: alternate-reverse; }

.demo.live:is([data-phase="stop"], [data-phase="processing"]) .ckb-dots i {
  background: #b56a48;
  animation: wave-settle 760ms ease-in-out infinite;
}

.demo.live[data-phase="stop"] .ckb-record::after {
  opacity: 0.55;
  transform: scale(0.8);
}

.demo.live[data-phase="processing"] .ckb-record {
  box-shadow: 0 0 0 1.1cqw rgba(192, 88, 43, 0.12);
  transform: scale(0.94);
}

@keyframes tap-invite {
  0%, 100% { box-shadow: 0 0.3cqw 2.8cqw rgba(80, 62, 50, 0.35); transform: scale(1); }
  48% { box-shadow: 0 0 0 1.6cqw rgba(192, 88, 43, 0.12), 0 0.3cqw 2.8cqw rgba(80, 62, 50, 0.3); transform: scale(1.075); }
}

@keyframes mic-press {
  0% { box-shadow: 0 0 0 0 rgba(192, 88, 43, 0.35); transform: scale(1); }
  45% { box-shadow: 0 0 0 1.4cqw rgba(192, 88, 43, 0.2); transform: scale(0.86); }
  100% { box-shadow: 0 0 0 2.2cqw rgba(192, 88, 43, 0); transform: scale(1.04); }
}

@keyframes rec-pulse {
  0% { box-shadow: 0 0 0 0 rgba(192, 88, 43, 0.36); }
  58% { box-shadow: 0 0 0 1.1cqw rgba(192, 88, 43, 0.16); }
  100% { box-shadow: 0 0 0 2.8cqw rgba(192, 88, 43, 0); }
}

@keyframes wave-voice {
  0% { transform: scaleY(1); opacity: 0.7; }
  100% { transform: scaleY(7.8); opacity: 1; }
}

@keyframes wave-settle {
  0%, 100% { transform: scaleY(1.3); opacity: 0.55; }
  50% { transform: scaleY(3.2); opacity: 0.9; }
}

/* --- demo 01: Messages --- */

.demo--messages.live:is([data-state="idle1"], [data-state="start1"], [data-state="listening1"], [data-state="speech1"], [data-state="stop1"], [data-state="processing1"], [data-state="insert1"]) .sent-msg--one,
.demo--messages.live:is([data-state="idle1"], [data-state="start1"], [data-state="listening1"], [data-state="speech1"], [data-state="stop1"], [data-state="processing1"], [data-state="insert1"], [data-state="send1"]) .incoming-one,
.demo--messages.live:is([data-state="idle1"], [data-state="start1"], [data-state="listening1"], [data-state="speech1"], [data-state="stop1"], [data-state="processing1"], [data-state="insert1"], [data-state="send1"], [data-state="incoming1"], [data-state="idle2"], [data-state="start2"], [data-state="listening2"], [data-state="speech2"], [data-state="stop2"], [data-state="processing2"], [data-state="insert2"]) .sent-msg--two,
.demo--messages.live:not(:is([data-state="incoming2"], [data-state="hold"], [data-state="reset"])) .incoming-two {
  display: none;
}

.demo--messages.live[data-state="send1"] .sent-msg--one,
.demo--messages.live[data-state="send2"] .sent-msg--two {
  animation: msg-lift 0.42s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}

.demo--messages.live[data-state="incoming1"] .incoming-one,
.demo--messages.live[data-state="incoming2"] .incoming-two {
  animation: soft-in 0.36s ease both;
}

.demo--messages.live:is([data-state="insert1"], [data-state="insert2"]) .tcaret {
  display: inline-block;
}

.demo--messages.live:is([data-state="insert1"], [data-state="insert2"]) .ph {
  display: none;
}

.demo--messages.live:is([data-state="insert1"], [data-state="insert2"]) .send {
  display: grid;
}

.demo--messages.live:is([data-state="send1"], [data-state="send2"]) .send {
  transform: translateY(-50%) scale(0.8);
}

@keyframes msg-lift {
  from {
    opacity: 0;
    transform: translateY(130%) scale(0.92);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes soft-in {
  from {
    opacity: 0;
    transform: translateY(30%);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* --- demo 02: Notes --- */

.demo--notes .ncaret {
  display: inline-block;
}

/* --- demo 03: Mail --- */

.demo--mail.live[data-state="processing"] .dots {
  display: inline-flex;
}

.demo--mail.live[data-state="insert"] .mcaret {
  display: inline-block;
}

.demo--mail.live:is([data-state="idle"], [data-state="start"], [data-state="listening"], [data-state="speech"], [data-state="stop"], [data-state="processing"], [data-state="insert"]) .mail-ins .typed {
  background: transparent;
  box-shadow: none;
}

/* --- demo 04: team chat --- */

.demo--team.live:is([data-state="idle"], [data-state="start"], [data-state="listening"], [data-state="speech"], [data-state="stop"], [data-state="processing"], [data-state="insert"]) .assist .assist-done,
.demo--team.live:not([data-state="processing"]) .assist .assist-working {
  display: none;
}

.demo--team.live[data-state="processing"] .assist .assist-working {
  display: inline-flex;
}

.demo--team.live:is([data-state="done"], [data-state="hold"]) .assist .assist-done {
  animation: soft-in 0.4s ease both;
}

.demo--team .tcaret {
  display: inline-block;
}

.demo--team.live:not([data-state="insert"]) .tcaret {
  display: none;
}

.demo--team .ph {
  display: none;
}

.demo--team.live:not(:is([data-state="insert"], [data-state="done"], [data-state="hold"], [data-state="reset"])) .ph {
  display: block;
}

/* --- demo 05: group chat + Imagine --- */

.demo--brunch.live:is([data-state="idle"], [data-state="context"], [data-state="start"], [data-state="listening"], [data-state="speech"], [data-state="stop"], [data-state="processing"], [data-state="insert"], [data-state="press"]) .sticker-line,
.demo--brunch.live:is([data-state="idle"], [data-state="context"], [data-state="start"], [data-state="listening"], [data-state="speech"], [data-state="stop"], [data-state="processing"], [data-state="insert"], [data-state="press"], [data-state="send"]) :is(.reply-msg, .reply-sender),
.demo--brunch.live:not(:is([data-state="react"], [data-state="hold"], [data-state="reset"])) .reaction,
.demo--brunch.live[data-state="idle"] :is(.brunch-context-two, .brunch-context-two-sender) {
  display: none;
}

.demo--brunch.live[data-state="send"] .sent-sticker {
  animation: msg-lift 0.6s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}

.demo--brunch.live:is([data-state="reply"], [data-state="react"], [data-state="hold"]) .reply-msg {
  animation: soft-in 0.42s ease both;
}

.demo--brunch.live[data-state="react"] .reaction {
  animation: soft-in 0.36s ease both;
}

.demo--brunch.live[data-state="processing"] .gen-box {
  display: block;
}

.demo--brunch.live[data-state="processing"] .gen-label {
  display: inline;
}

.demo--brunch.live:is([data-state="insert"], [data-state="press"]) .compose-sticker {
  display: block;
}

.demo--brunch.live[data-state="insert"] .compose-sticker {
  animation: sticker-in 0.5s cubic-bezier(0.2, 0.7, 0.25, 1.2) both;
}

.demo--brunch.live:is([data-state="insert"], [data-state="press"]) .send {
  display: grid;
}

.demo--brunch.live[data-state="press"] .send {
  transform: translateY(-50%) scale(0.8);
}

.demo--brunch.live:is([data-state="processing"], [data-state="insert"], [data-state="press"]) .ph {
  display: none;
}

@keyframes sticker-in {
  from {
    opacity: 0;
    transform: scale(0.45);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* ---------- hero + privacy band ---------- */

.hero {
  display: grid;
  gap: clamp(40px, 6vw, 72px);
  padding-top: clamp(28px, 3.5vw, 52px);
  padding-bottom: var(--band);
}

.hero h1 {
  max-width: 12em;
  font-size: clamp(40px, 4.2vw, 56px);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.04;
  text-wrap: balance;
}

/* Two lines on desktop; below 900px the break is removed and text wraps freely. */
.hero-br { display: none; }
@media (min-width: 900px) {
  .hero-br { display: inline; }
}

.type-caret {
  display: inline-block;
  width: clamp(3px, 0.05em, 5px);
  height: 0.78em;
  margin-left: 0.08em;
  background: var(--signal);
  vertical-align: -0.05em;
  animation: caret-blink 1.15s steps(1) infinite;
}

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

.lead {
  max-width: 30em;
  margin-top: clamp(18px, 2vw, 26px);
  color: var(--muted);
  font-size: clamp(17px, 1.4vw, 19.5px);
  line-height: 1.6;
}

.annotation {
  max-width: 32em;
  margin-top: clamp(34px, 4vw, 52px);
  padding-top: clamp(28px, 3.2vw, 40px);
  border-top: 1px solid var(--line);
}

.custody {
  max-width: 30em;
  margin-top: 26px;
}

.custody > div {
  display: grid;
  grid-template-columns: minmax(8.5em, max-content) 1fr;
  gap: 6px 16px;
  align-items: baseline;
  padding-block: 11px;
  border-top: 1px solid var(--line);
}

.custody dt {
  color: var(--ink);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.custody dd {
  color: var(--muted);
  font-size: 14.5px;
  line-height: 1.5;
}

.phone-figure {
  width: min(100%, 352px);
  margin-inline: auto;
}

@media (min-width: 900px) {
  .hero {
    grid-template-columns: minmax(0, 1fr) clamp(320px, 28vw, 396px);
    column-gap: clamp(48px, 6vw, 92px);
    align-items: start;
  }

  .hero-phone {
    width: 100%;
    margin-inline: 0;
    margin-top: 6px;
  }
}

/* ---------- paired feature rows ---------- */

.pair {
  display: grid;
  gap: 30px;
  padding-block: var(--band);
  border-top: 1px solid var(--line);
}

.pair-block {
  display: grid;
  justify-items: center;
  width: min(100%, 34em);
  margin-inline: auto;
  text-align: center;
}

.pair-block .kicker {
  justify-content: center;
}

.pair-block .copy {
  margin-inline: auto;
}

.pair-block .kicker + h2 {
  font-size: clamp(24px, 2.3vw, 31px);
}

.pair-divider {
  width: min(160px, 56%);
  height: 1px;
  margin: 8px auto;
  border: 0;
  background: var(--line);
}

/* ---------- agent harness compatibility row ---------- */

.harnesses {
  display: grid;
  gap: 13px;
  justify-items: center;
  margin-top: 26px;
}

.harness-note {
  margin: 0;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.harness-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  max-width: 30em;
  margin: 0;
  padding: 0;
  list-style: none;
}

.harness {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 34px;
  padding: 0 13px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--card);
  color: var(--ink);
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: -0.008em;
  line-height: 1;
  white-space: nowrap;
}

/* Official harness marks: the artwork inlined from the vendored
   monochrome SVGs in assets/harness/, drawn in the pill's ink color
   via currentColor at original proportions. */
.harness .h-mark {
  width: 15px;
  height: 15px;
  flex: none;
  opacity: 0.82;
}

/* Below the editorial desktop breakpoint, direct DOM order is the visual
   order: feature 02, its demo, feature 03, its demo (and likewise 04/05). */
.pair > .demo {
  width: min(100%, 352px);
}

.pair > .demo-a {
  margin-bottom: clamp(14px, 4vw, 28px);
}

@media (min-width: 900px) {
  .pair {
    grid-template-columns:
      clamp(250px, 23vw, 300px)
      minmax(0, 1fr)
      clamp(250px, 23vw, 300px);
    grid-template-rows: auto 1px auto;
    column-gap: clamp(36px, 4vw, 56px);
    row-gap: clamp(26px, 3vw, 36px);
    align-items: center;
  }

  .pair > .feature-a {
    grid-column: 2;
    grid-row: 1;
  }

  .pair > .feature-b {
    grid-column: 2;
    grid-row: 3;
  }

  .pair > .pair-divider {
    grid-column: 2;
    grid-row: 2;
    margin: 0 auto;
  }

  .pair > .demo-a {
    grid-column: 1;
    grid-row: 1 / 4;
  }

  .pair > .demo-b {
    grid-column: 3;
    grid-row: 1 / 4;
  }

  .pair > .demo-a,
  .pair > .demo-b {
    align-self: center;
    width: 100%;
    margin: 0;
  }
}

/* ---------- closing ---------- */

.closing {
  display: grid;
  gap: clamp(28px, 3.5vw, 40px);
  justify-items: start;
  padding-block: clamp(72px, 9vw, 120px);
  border-top: 1px solid var(--line);
}

.closing h2 {
  max-width: 17.5em;
  font-size: clamp(32px, 3.9vw, 52px);
  font-weight: 600;
  letter-spacing: -0.028em;
  line-height: 1.1;
  text-wrap: balance;
}

.closing .phrase {
  white-space: nowrap;
}

/* ---------- footer ---------- */

.site-footer {
  display: flex;
  min-height: 96px;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  border-top: 1px solid var(--line);
}

.site-footer .brand {
  font-size: 13px;
  gap: 8px;
}

.site-footer .brand-mark {
  width: 18px;
  height: 18px;
}

.site-footer p {
  color: var(--muted);
  font-size: 12px;
}

/* ---------- small screens ---------- */

@media (max-width: 480px) {
  :root {
    --gutter: 20px;
    --band: 56px;
    --header-h: 68px;
  }

  .brand {
    gap: 10px;
    font-size: 17px;
  }

  .brand-mark {
    width: 28px;
    height: 28px;
  }

  .site-header .button {
    min-height: 40px;
    padding-inline: 16px;
    font-size: 14px;
  }

  .hero {
    padding-top: 24px;
  }

  .hero h1 {
    font-size: clamp(34px, 10.5vw, 42px);
  }

  .lead {
    font-size: 17px;
  }

  .kicker + h2 {
    font-size: clamp(25px, 7.5vw, 30px);
  }

  .phone {
    padding: 8px;
  }

  .phone::before {
    top: calc(8px + 1.5%);
  }

  .phone::after {
    box-shadow: 0 0 0 0 #24272d, 0 42px 0 0 #24272d;
  }

  .closing {
    padding-block: 84px;
  }

  .closing h2 {
    font-size: clamp(30px, 9.5vw, 36px);
  }

  .site-footer {
    min-height: 84px;
  }
}

@media (max-width: 360px) {
  .custody > div {
    grid-template-columns: 1fr;
    gap: 4px;
  }
}

@media (max-width: 340px) {
  :root {
    --gutter: 16px;
  }

  .brand {
    font-size: 16px;
  }

  .brand-mark {
    width: 25px;
    height: 25px;
  }

  .site-header .button {
    padding-inline: 13px;
    font-size: 13px;
  }

  .hero h1 {
    font-size: 33px;
  }

  .kicker + h2 {
    font-size: 24px;
  }

  .closing h2 {
    font-size: 29px;
  }
}

/* ---------- reduced motion: static, complete final states ---------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }

  .type-caret,
  .tcaret,
  .ncaret {
    animation: none !important;
  }

  /* demos.js never arms `.live` under reduced motion, so every demo
     renders its complete final markup */

  .bubble {
    opacity: 1 !important;
    animation: none !important;
    transform: none !important;
  }

  .bubble .bubble-text {
    animation: none !important;
    clip-path: none !important;
  }
}

/* ---------- coming-soon dialog (Download Caret CTAs) ---------- */

.coming-soon {
  margin: auto;
  padding: 0;
  border: 0;
  width: min(420px, calc(100vw - 32px));
  background: transparent;
  overscroll-behavior: contain;
}

.coming-soon::backdrop {
  background: rgba(20, 22, 26, 0.45);
}

/* lock page scroll while the dialog is open (modal.js toggles the class) */
html.modal-open,
html.modal-open body {
  overflow: hidden;
}

.coming-soon-panel {
  position: relative;
  padding: clamp(24px, 7vw, 36px);
  border: 1px solid var(--line);
  border-radius: 22px;
  background: var(--card);
  box-shadow: 0 24px 60px rgba(20, 22, 26, 0.18);
}

/* focus lands on the panel when the dialog opens; the dialog's labelling
   announces it, so no ring is needed on the container itself */
.coming-soon-panel:focus {
  outline: none;
}

.coming-soon-close {
  position: absolute;
  top: 14px;
  right: 14px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  transition: background-color 140ms ease, color 140ms ease;
}

.coming-soon-close svg {
  width: 16px;
  height: 16px;
}

.coming-soon-close:hover {
  background: var(--signal-soft);
  color: var(--ink);
}

.coming-soon-mark {
  width: 40px;
  height: 40px;
  margin-bottom: 18px;
}

.coming-soon-title {
  font-size: clamp(24px, 6vw, 30px);
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.12;
}

.coming-soon-copy {
  margin-top: 12px;
  color: var(--muted);
  font-size: 16px;
  line-height: 1.55;
}

.coming-soon-follow {
  width: 100%;
  margin-top: 24px;
}

@media (prefers-reduced-motion: no-preference) {
  .coming-soon[open] {
    animation: coming-soon-in 180ms ease-out;
  }

  .coming-soon[open]::backdrop {
    animation: coming-soon-fade 180ms ease-out;
  }
}

@keyframes coming-soon-in {
  from {
    opacity: 0;
    transform: translateY(10px) scale(0.97);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes coming-soon-fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
