@import url('https://fonts.googleapis.com/css2?family=Inter:opsz,wght@14..32,100..900&display=swap');
@import "tailwindcss";
@import "tw-animate-css";

@custom-variant dark (&:is(.dark *));

@layer base {
  .tiptap :where(p, a, div, h1, h2, h3, h4, h5, h6, ul, ol, li, blockquote) {
    all: revert;
  }
}

:root {
  --radius: 0.5rem;
  --foreground: oklch(0.15 0.01 260);
  --background: oklch(1 0 0);
  --card: oklch(1 0 0);
  --card-foreground: oklch(0.15 0.01 260);
  --popover: oklch(1 0 0);
  --popover-foreground: oklch(0.15 0.01 260);
  --primary: oklch(0.45 0.01 260);
  --primary-foreground: oklch(1 0 0);
  --secondary: oklch(0.96 0.005 260);
  --secondary-foreground: oklch(0.25 0.01 260);
  --muted: oklch(0.97 0.003 260);
  --muted-foreground: oklch(0.55 0.01 260);
  --accent: oklch(0.96 0.005 260);
  --accent-foreground: oklch(0.20 0.01 260);
  --destructive: oklch(0.577 0.245 27.325);
  --border: oklch(0.92 0.005 260);
  --input: oklch(0.92 0.005 260);
  --ring: oklch(0.55 0.01 260);
  --chart-1: oklch(0.55 0.15 250);
  --chart-2: oklch(0.60 0.12 160);
  --chart-3: oklch(0.65 0.10 30);
  --chart-4: oklch(0.50 0.14 300);
  --chart-5: oklch(0.58 0.08 200);
  --sidebar: oklch(0.98 0.002 260);
  --sidebar-foreground: oklch(0.15 0.01 260);
  --sidebar-primary: oklch(0.45 0.01 260);
  --sidebar-primary-foreground: oklch(1 0 0);
  --sidebar-accent: oklch(0.96 0.005 260);
  --sidebar-accent-foreground: oklch(0.20 0.01 260);
  --sidebar-border: oklch(0.92 0.005 260);
  --sidebar-ring: oklch(0.55 0.01 260);
}

.dark {
  --background: oklch(0.13 0.01 260);
  --foreground: oklch(0.95 0.005 260);
  --card: oklch(0.16 0.01 260);
  --card-foreground: oklch(0.95 0.005 260);
  --popover: oklch(0.16 0.01 260);
  --popover-foreground: oklch(0.95 0.005 260);
  --primary: oklch(0.85 0.005 260);
  --primary-foreground: oklch(0.13 0.01 260);
  --secondary: oklch(0.22 0.01 260);
  --secondary-foreground: oklch(0.95 0.005 260);
  --muted: oklch(0.20 0.01 260);
  --muted-foreground: oklch(0.60 0.01 260);
  --accent: oklch(0.22 0.01 260);
  --accent-foreground: oklch(0.95 0.005 260);
  --destructive: oklch(0.704 0.191 22.216);
  --border: oklch(0.26 0.01 260);
  --input: oklch(0.26 0.01 260);
  --ring: oklch(0.60 0.01 260);
  --chart-1: oklch(0.60 0.15 250);
  --chart-2: oklch(0.55 0.12 160);
  --chart-3: oklch(0.58 0.10 30);
  --chart-4: oklch(0.52 0.14 300);
  --chart-5: oklch(0.55 0.08 200);
  --sidebar: oklch(0.14 0.01 260);
  --sidebar-foreground: oklch(0.95 0.005 260);
  --sidebar-primary: oklch(0.85 0.005 260);
  --sidebar-primary-foreground: oklch(0.13 0.01 260);
  --sidebar-accent: oklch(0.22 0.01 260);
  --sidebar-accent-foreground: oklch(0.95 0.005 260);
  --sidebar-border: oklch(0.26 0.01 260);
  --sidebar-ring: oklch(0.60 0.01 260);
}

@theme inline {
  --color-background: var(--background);
  --color-foreground: var(--foreground);
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;
  --font-display: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --font-serif: Georgia, 'Times New Roman', serif;
  --ease-bezier: cubic-bezier(.53,-0.14,.16,1.78);
  --color-sidebar-ring: var(--sidebar-ring);
  --color-sidebar-border: var(--sidebar-border);
  --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
  --color-sidebar-accent: var(--sidebar-accent);
  --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
  --color-sidebar-primary: var(--sidebar-primary);
  --color-sidebar-foreground: var(--sidebar-foreground);
  --color-sidebar: var(--sidebar);
  --color-chart-5: var(--chart-5);
  --color-chart-4: var(--chart-4);
  --color-chart-3: var(--chart-3);
  --color-chart-2: var(--chart-2);
  --color-chart-1: var(--chart-1);
  --color-ring: var(--ring);
  --color-input: var(--input);
  --color-border: var(--border);
  --color-destructive: var(--destructive);
  --color-accent-foreground: var(--accent-foreground);
  --color-accent: var(--accent);
  --color-muted-foreground: var(--muted-foreground);
  --color-muted: var(--muted);
  --color-secondary-foreground: var(--secondary-foreground);
  --color-secondary: var(--secondary);
  --color-primary-foreground: var(--primary-foreground);
  --color-primary: var(--primary);
  --color-popover-foreground: var(--popover-foreground);
  --color-popover: var(--popover);
  --color-card-foreground: var(--card-foreground);
  --color-card: var(--card);
  --radius-sm: calc(var(--radius) - 4px);
  --radius-md: calc(var(--radius) - 2px);
  --radius-lg: var(--radius);
  --radius-xl: calc(var(--radius) + 4px);
  --radius-2xl: calc(var(--radius) + 8px);
  --radius-3xl: calc(var(--radius) + 12px);
  --radius-4xl: calc(var(--radius) + 16px);
}

body {
  color: var(--foreground);
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: 'cv02', 'cv03', 'cv04', 'cv11';
}

/* ── Loading spinner ─────────────────────── */

svg.loading {
  width: 3.25em;
  transform-origin: center;
  animation: rotate4 2s linear infinite;
 }

svg.loading circle {
  fill: none;
  stroke-width: 2;
  stroke-dasharray: 1, 200;
  stroke-dashoffset: 0;
  stroke-linecap: round;
  animation: dash4 1.5s ease-in-out infinite;
}

@keyframes rotate4 {
  100% { transform: rotate(360deg); }
}

@keyframes dash4 {
  0% { stroke-dasharray: 1, 200; stroke-dashoffset: 0; }
  50% { stroke-dasharray: 90, 200; stroke-dashoffset: -35px; }
  100% { stroke-dashoffset: -125px; }
}

/* ── Auth sky + animations ───────────────────────
   The auth showcase pane uses an airy sky (same palette as the marketing
   site hero): CSS gradient layers + pre-rendered WebP clouds. No animated
   SVG feTurbulence/feDisplacementMap (those rendered inconsistently in
   Safari/Firefox and were slow); this is GPU-cheap and identical everywhere. */

.sky-base {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(ellipse 140% 130% at 60% 18%,
    #7dd3fc 0%,
    #38bdf8 20%,
    #0ea5e9 40%,
    #0284c7 62%,
    #075985 84%,
    #0c4a6e 100%
  );
}

.sky-breathe {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(ellipse 130% 120% at 60% 16%,
    rgba(186, 230, 253, 0.80) 0%,
    rgba(56, 189, 248, 0.40) 20%,
    rgba(14, 165, 233, 0.16) 40%,
    transparent 62%
  );
  animation: sky-breathe 30s ease-in-out infinite;
}

@keyframes sky-breathe {
  0%, 100% { opacity: 0.7; transform: scale(1); }
  50%      { opacity: 0.45; transform: scale(1.05); }
}

.sun-glow {
  position: absolute;
  top: -6%;
  right: -4%;
  width: 420px;
  height: 420px;
  border-radius: 9999px;
  pointer-events: none;
  filter: blur(36px);
  background: radial-gradient(circle,
    rgba(253, 230, 138, 0.34) 0%,
    rgba(253, 186, 116, 0.12) 32%,
    rgba(186, 230, 253, 0.05) 55%,
    transparent 70%
  );
  animation: sun-pulse 22s ease-in-out infinite;
}

@keyframes sun-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.6; transform: scale(1.10); }
}

/* Drifting pre-rendered WebP clouds (browser-perfect <img>) */
.cloud-drift {
  position: absolute;
  pointer-events: none;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
  animation-direction: alternate;
  will-change: transform;
}

@keyframes cloud-glide-1 { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(40px, -10px, 0); } }
@keyframes cloud-glide-2 { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(-38px, 8px, 0); } }

.cloud-1 { animation-name: cloud-glide-1; animation-duration: 36s; }
.cloud-2 { animation-name: cloud-glide-2; animation-duration: 44s; }

@keyframes card-float {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes fade-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

/* AI writing surfaces — a text shimmer for "thinking/writing" status labels
   and a caret blink for streaming text. Both quiet down under
   prefers-reduced-motion. */
@keyframes ai-shimmer {
  from { background-position: 200% 0; }
  to { background-position: -200% 0; }
}
.ai-shimmer-text {
  background: linear-gradient(90deg, #64748b 30%, #0ea5e9 50%, #64748b 70%);
  background-size: 200% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: ai-shimmer 1.8s linear infinite;
}
@keyframes ai-caret-blink {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0; }
}
.ai-caret {
  animation: ai-caret-blink 1s steps(1) infinite;
}
/* Soft diagonal light sweep over an input while AI writes into it. */
.ai-sheen {
  background: linear-gradient(
    100deg,
    transparent 25%,
    rgba(14, 165, 233, 0.09) 45%,
    rgba(56, 189, 248, 0.14) 50%,
    rgba(14, 165, 233, 0.09) 55%,
    transparent 75%
  );
  background-size: 220% 100%;
  animation: ai-shimmer 1.6s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  .ai-shimmer-text { animation: none; background: none; color: #64748b; }
  .ai-caret { animation: none; }
  .ai-sheen { animation: none; background: rgba(14, 165, 233, 0.06); }
}

/* 3x3 dot-grid activity indicator (adapted from Temani Afif's css-loaders
   "l26"). Native geometry is a ~52px square block, so the dot + box-shadow
   grid lives on a ::before that is scaled down (origin 0 0, after the
   centering translateX) and centered inside a fixed 18px box so it sits
   inline on a nav row. currentColor tints all nine dots. */
.campaign-grid {
  display: inline-block;
  position: relative;
  width: 14px;
  height: 14px;
  vertical-align: middle;
}

.campaign-grid::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 4px;
  aspect-ratio: 1;
  border-radius: 50%;
  color: currentColor;
  transform-origin: 0 0;
  transform: scale(0.26) translateX(-38px);
  box-shadow:
    19px -19px 0 0px, 38px -19px 0 0px, 57px -19px 0 0px,
    19px 0     0 5px, 38px 0     0 5px, 57px 0     0 5px,
    19px 19px  0 0px, 38px 19px  0 0px, 57px 19px  0 0px;
  animation: campaign-grid 3.5s infinite linear;
}

@keyframes campaign-grid {
  12.5% { box-shadow:
    19px -19px 0 0px, 38px -19px 0 0px, 57px -19px 0 5px,
    19px 0     0 5px, 38px 0     0 0px, 57px 0     0 5px,
    19px 19px  0 0px, 38px 19px  0 0px, 57px 19px  0 0px; }
  25%   { box-shadow:
    19px -19px 0 5px, 38px -19px 0 0px, 57px -19px 0 5px,
    19px 0     0 0px, 38px 0     0 0px, 57px 0     0 0px,
    19px 19px  0 0px, 38px 19px  0 5px, 57px 19px  0 0px; }
  50%   { box-shadow:
    19px -19px 0 5px, 38px -19px 0 5px, 57px -19px 0 0px,
    19px 0     0 0px, 38px 0     0 0px, 57px 0     0 0px,
    19px 19px  0 0px, 38px 19px  0 0px, 57px 19px  0 5px; }
  62.5% { box-shadow:
    19px -19px 0 0px, 38px -19px 0 0px, 57px -19px 0 0px,
    19px 0     0 5px, 38px 0     0 0px, 57px 0     0 0px,
    19px 19px  0 0px, 38px 19px  0 5px, 57px 19px  0 5px; }
  75%   { box-shadow:
    19px -19px 0 0px, 38px -19px 0 5px, 57px -19px 0 0px,
    19px 0     0 0px, 38px 0     0 0px, 57px 0     0 5px,
    19px 19px  0 0px, 38px 19px  0 0px, 57px 19px  0 5px; }
  87.5% { box-shadow:
    19px -19px 0 0px, 38px -19px 0 5px, 57px -19px 0 0px,
    19px 0     0 0px, 38px 0     0 5px, 57px 0     0 0px,
    19px 19px  0 5px, 38px 19px  0 0px, 57px 19px  0 0px; }
}

/* Flame flicker — the warmup ("heat") motif for the sidebar Accounts row.
   Deliberately a DIFFERENT motion than .campaign-grid so each nav row reads
   distinct. A small living-flame wobble: scale + tilt + opacity, anchored at
   the base so it dances like a candle. Tint via currentColor (orange). */
.flame-flicker {
  transform-origin: center bottom;
  animation: flame-flicker 1.1s ease-in-out infinite;
}

@keyframes flame-flicker {
  0%, 100% { transform: scale(1) rotate(-1.5deg); opacity: 0.82; }
  25%      { transform: scale(1.09) rotate(1.5deg); opacity: 1; }
  50%      { transform: scale(0.97) rotate(-1deg); opacity: 0.9; }
  75%      { transform: scale(1.05) rotate(1deg); opacity: 1; }
}

/* Sidebar status halo: a quiet-but-connected workspace (READY) breathes —
   the glow swells and fades on a slow cycle so it visibly reads as alive. */
.status-breathe {
  animation: status-breathe 2.2s ease-in-out infinite;
}
@keyframes status-breathe {
  0%, 100% { transform: scale(0.6); opacity: 0.9; }
  50%      { transform: scale(1.4); opacity: 0.2; }
}

@media (prefers-reduced-motion: reduce) {
  .sky-breathe, .sun-glow, .cloud-drift, .animate-card-float, .animate-fade-in, .campaign-grid::before, .flame-flicker, .status-breathe { animation: none !important; }
}

/* ── Utilities ─────────────────────── */

@layer utilities {
  .no-scrollbar::-webkit-scrollbar {
    display: none;
  }
  .no-scrollbar {
    -ms-overflow-style: none;
    scrollbar-width: none;
  }

  .animate-card-float {
    animation: card-float 0.8s cubic-bezier(0.16, 1, 0.3, 1) both;
  }

  .animate-fade-in {
    animation: fade-in 0.5s ease both;
  }

}

.bg-email {
  background-image: url("data:image/svg+xml;utf8,%3Csvg%20viewBox%3D%220%200%20280%20256%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M170.241%2026.7461C173.21%2021.6919%20172.626%2018.8475%20173.784%2015.9756C174.496%2014.2117%20176.829%2014.1236%20177.834%2015.7385C180.648%2020.2595%20180.845%2026.7813%20177.013%2032.9134C173.481%2038.5661%20167.776%2039.8645%20163.614%2040.1136C161.729%2040.2265%20160.289%2038.5329%20161.394%2037.0014C163.36%2034.2764%20167.36%2031.6502%20170.241%2026.7461Z%22%20fill%3D%22%23FA9955%22%2F%3E%3Cpath%20d%3D%22M102.297%2024.6341C100.509%2014.4962%20105.013%208.82327%20109.477%205.22381C111.149%203.87595%20113.354%205.56809%20112.995%207.68538C112.606%209.98423%20112.439%2012.7392%20112.954%2015.6565C114.168%2022.541%20129.311%2032.3976%20130.311%2038.0672C130.907%2041.4479%20129.872%2046.1555%20127.942%2050.0239C126.917%2052.0788%20123.275%2050.5138%20122.889%2048.2502C122.874%2048.1667%20122.86%2048.0825%20122.845%2047.9975C121.872%2042.4782%20104.844%2039.078%20102.297%2024.6341Z%22%20fill%3D%22%23FA9955%22%2F%3E%3Cpath%20d%3D%22M190.692%2035.3663C192.809%2032.8656%20196.747%2033.1772%20197.811%2036.2765C198.721%2038.928%20199.501%2042.171%20199.501%2045.5001C199.5%2052.8707%20195.089%2056.8593%20201.348%2064.7111C202.416%2066.0499%20204.23%2066.5175%20205.859%2065.9894C221.601%2060.8854%20233.732%2052.3052%20236.001%2045.5001C239.068%2036.2981%20249.421%2056.6435%20240.291%2074.5695H148.49C147.967%2074.0823%20147.438%2073.5952%20146.899%2073.1105C145.12%2071.5102%20142.395%2071.617%20140.783%2073.3849C140.428%2073.774%20140.075%2074.1695%20139.723%2074.5695H43.9332C36.546%2060.0341%2029.9746%2042.7756%2035.5006%2045.5001C44.5572%2049.9658%2063.0006%2071.7725%2078.0631%2071.7726C85.5998%2071.7724%2086.173%2067.228%2090.5006%2063.5001C99.6418%2055.6251%2073.3363%2042.5028%2071.9068%2037.4191C71.6139%2036.3754%2073.086%2036.0973%2074.1529%2036.2902C79.7761%2037.3067%2098.1925%2040.9002%20105.001%2045.5001C110.232%2049.0351%20118.762%2056.9295%20124.123%2062.0538C126.481%2064.3068%20130.394%2063.5148%20131.65%2060.505L139.017%2042.8478C140.464%2039.3796%20145.084%2039.1142%20146.842%2042.4357C151.392%2051.0308%20155.783%2058.0803%20167.913%2056.0402C168.132%2056.0032%20168.357%2055.945%20168.568%2055.8741L169.258%2055.6427C178.23%2049.2942%20186.089%2040.8031%20190.692%2035.3663Z%22%20fill%3D%22url%28%23paint0_linear_1_188%29%22%2F%3E%3Cpath%20d%3D%22M124.869%20207.402C136.048%20217.634%20153.243%20217.457%20164.209%20206.997L190.655%20181.768L264.935%20250.395C259.677%20253.934%20253.347%20256%20246.533%20256H33C27.1193%20256%2021.5991%20254.46%2016.8174%20251.764L94.709%20179.798L124.869%20207.402ZM84.3457%20170.312L6.31152%20242.409C2.34327%20236.962%200%20230.255%200%20223V116.803C1.8303e-06%20109.946%202.09091%20103.578%205.66992%2098.3017L84.3457%20170.312ZM275.444%20100.884C278.049%20105.604%20279.533%20111.03%20279.533%20116.803V223C279.533%20229.344%20277.741%20235.269%20274.638%20240.3L200.805%20172.085L275.444%20100.884ZM246.533%2083.8027C253.916%2083.8027%20260.733%2086.2271%20266.23%2090.3232L154.546%20196.867C148.909%20202.245%20140.068%20202.335%20134.321%20197.075L15.8262%2088.6181C20.8292%2085.5631%2026.709%2083.8027%2033%2083.8027H246.533Z%22%20fill%3D%22url%28%23paint1_linear_1_188%29%22%2F%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22paint0_linear_1_188%22%20x1%3D%22142.191%22%20y1%3D%2218.9244%22%20x2%3D%22142.191%22%20y2%3D%22208.992%22%20gradientUnits%3D%22userSpaceOnUse%22%3E%3Cstop%20stop-color%3D%22%23FAA057%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23F03838%22%2F%3E%3C%2FlinearGradient%3E%3ClinearGradient%20id%3D%22paint1_linear_1_188%22%20x1%3D%22139.767%22%20y1%3D%2283.8027%22%20x2%3D%22139.767%22%20y2%3D%22256%22%20gradientUnits%3D%22userSpaceOnUse%22%3E%3Cstop%20stop-color%3D%22%237293FF%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%232C3EFF%22%2F%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3C%2Fsvg%3E");
}

.ripple {
  position: relative;
  overflow: hidden;
}

.ripple-effect-span {
  position: absolute;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.3;
  transform: scale(0);
  transition: .8s ease-out;
}
.ripple-effect-span.in{
  transform: scale(4);
  opacity: 0.08;
}
.ripple-effect-span.out{
  transition: .3s;
  opacity: 0;
}

.tiptap p{
  margin: 0;
}

/* Campaign Step composer body (TipTap editor + the rendered Preview pane).
   Tailwind preflight strips list markers + heading sizes, so restore them. */
.tiptap-body { word-break: break-word; }
.tiptap-body p { margin: 0 0 0.6em; }
.tiptap-body p:last-child { margin-bottom: 0; }
.tiptap-body h2 { font-size: 1.25rem; line-height: 1.3; font-weight: 600; margin: 0.5em 0 0.3em; color: #0f172a; }
.tiptap-body h3 { font-size: 1.08rem; line-height: 1.3; font-weight: 600; margin: 0.5em 0 0.3em; color: #0f172a; }
.tiptap-body ul { list-style: disc; padding-left: 1.25rem; margin: 0.4em 0; }
.tiptap-body ol { list-style: decimal; padding-left: 1.25rem; margin: 0.4em 0; }
.tiptap-body li { margin: 0.15em 0; }
.tiptap-body li > p { margin: 0; }
.tiptap-body a { color: #0284c7; text-decoration: underline; }
.tiptap-body strong { font-weight: 600; }
.tiptap-body:focus { outline: none; }

/* Merge-tag chips shown inside the composer editor. Only the node-view button
   carries .tpl-var; the resolved `<span data-var>` in the Preview pane is left
   unstyled on purpose so it reads as the plain value it will send as. */
.tpl-var-wrap { vertical-align: baseline; }
.tiptap-body .tpl-var {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
  height: 1.25rem;
  padding: 0 0.375rem;
  border-radius: 0.25rem;
  border: 1px solid #e2e8f0; /* slate-200 */
  background: #f8fafc; /* slate-50 */
  color: #475569; /* slate-600 */
  font-size: 11px;
  line-height: 1;
  font-weight: 500;
  white-space: nowrap;
  vertical-align: baseline;
  cursor: pointer;
  user-select: none;
  transition: background-color 0.12s, border-color 0.12s, color 0.12s;
}
.tiptap-body .tpl-var:hover,
.tiptap-body .tpl-var.tpl-var-active {
  border-color: #7dd3fc; /* sky-300 */
  background: #f0f9ff; /* sky-50 */
  color: #0369a1; /* sky-700 */
}

/* AI blocks — per-recipient generated copy. A restrained sky tint (with a
   sparkle icon) distinguishes them from the slate merge chips without leaving
   the house theme. No gradients or glow. */
.tpl-ai-wrap { vertical-align: baseline; }
.tiptap-body .tpl-ai {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  height: 1.25rem;
  padding: 0 0.4rem;
  border-radius: 0.25rem;
  border: 1px solid #bae6fd; /* sky-200 */
  background: #f0f9ff; /* sky-50 */
  color: #0369a1; /* sky-700 */
  font-size: 11px;
  line-height: 1;
  font-weight: 500;
  white-space: nowrap;
  vertical-align: baseline;
  cursor: pointer;
  user-select: none;
  transition: background-color 0.12s, border-color 0.12s, color 0.12s;
}
.tiptap-body .tpl-ai:hover,
.tiptap-body .tpl-ai.tpl-ai-active {
  border-color: #7dd3fc; /* sky-300 */
  background: #e0f2fe; /* sky-100 */
  color: #075985; /* sky-800 */
}
/* Unconfigured AI block: a dashed edge nudges the user to set it up. */
.tiptap-body .tpl-ai.tpl-ai-empty {
  border-style: dashed;
}

/* Conditional (logic) chips — a heavier neutral slate so they read as structure,
   distinct from the light merge chips and the sky AI chips. Sky hover accent. */
.tpl-if-wrap { vertical-align: baseline; }
.tiptap-body .tpl-if {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  height: 1.25rem;
  padding: 0 0.4rem;
  border-radius: 0.25rem;
  border: 1px solid #cbd5e1; /* slate-300 */
  background: #f1f5f9; /* slate-100 */
  color: #334155; /* slate-700 */
  font-size: 11px;
  line-height: 1;
  font-weight: 500;
  white-space: nowrap;
  vertical-align: baseline;
  cursor: pointer;
  user-select: none;
  transition: background-color 0.12s, border-color 0.12s, color 0.12s;
}
.tiptap-body .tpl-if:hover,
.tiptap-body .tpl-if.tpl-if-active {
  border-color: #7dd3fc; /* sky-300 */
  background: #f0f9ff; /* sky-50 */
  color: #0369a1; /* sky-700 */
}

/* Campaign flow canvas — smoothly glide nodes when the layout recomputes
   (adding/deleting a step, "Tidy up"). The transition is killed while dragging
   so node drag stays 1:1 with the cursor. Scoped to .campaign-flow so other
   React Flow surfaces are unaffected. */
.campaign-flow .react-flow__node {
  transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
}
.campaign-flow.rf-dragging .react-flow__node {
  transition: none;
}

@layer base {
  * {
    @apply border-border outline-ring/50;
  }
  body {
    @apply bg-background text-foreground;
  }
}

/* iOS Safari auto-zooms the page when a focused control has font-size < 16px.
   Force 16px on phones (!important beats Tailwind text-[12.5px] utilities);
   desktop type is untouched. */
@media (max-width: 767px) {
  input, select, textarea, [contenteditable="true"] { font-size: max(16px, 1em) !important; }
}
