
/* ==========================================================================
   PLATFORM PAGES                    Figma humV0zBvd9Q3QRc4N4QDUH · 9924:22916
   Shared by ai-visibility-tracking.html, agentic-workflows.html,
   ai-search-optimization.html, prompt-research.html and copilot.html. The
   hero card, section header, white card, chip and dark-bento primitives are
   the comps' own colours and radii; buttons, headings, reveal and chrome are
   the site's, so the five pages read as one product.
   ========================================================================== */
.zr-pp{
  --pp-hair : #E4E9F0;   /* card and input border            */
  --pp-ink  : #1F2328;   /* titles                           */
  --pp-body : #525252;   /* running copy                     */
  --pp-dim  : #7A8494;   /* captions, table heads            */
  --pp-frame: #F6F7F9;   /* the soft frame around card rows  */
  --pp-mono : 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-family:var(--zr-font);
}
.zr-pp *, .zr-pp *::before, .zr-pp *::after{ box-sizing:border-box; }
.zr-pp__wrap{ width:min(1248px,100%); margin:0 auto; padding-inline:var(--zr-pad); }

/* ── hero ─────────────────────────────────────────────────────────────────
   Every comp draws the hero as a card inset 20px from the viewport with the
   nav pill floating over it — the homepage does the same. Two rules follow
   from that and are worth stating once:

   · the card is 20px from *every* edge, the top included. The nav's layout
     box is 104px (40 margin + 64 pill), so the lift is 84px, not 104 — a
     104px lift put the card's top edge at y=0 and the pill looked stuck to
     the ceiling of the screen.
   · on a desktop viewport the card is exactly one screen tall: 100svh less
     the 20px top and bottom insets. min-height, never height, so a hero
     whose copy outgrows the screen still grows instead of clipping.
   ───────────────────────────────────────────────────────────────────────── */
.zr-pp__hero{
  --pp-lift:84px;
  position:relative; isolation:isolate;
  margin:20px; margin-top:calc(-1 * var(--pp-lift));
  padding:calc(var(--pp-lift) + clamp(28px,3.4vw,56px)) clamp(20px,3vw,48px) clamp(44px,4.6vw,76px);
  border-radius:var(--zr-r-lg); overflow:clip;
  background:#fff;
  display:grid; align-content:center;
}
@media (min-width:900px){
  .zr-pp__hero{ min-height:calc(100svh - 40px); }
  /* Safari < 15.4 and every engine without svh: vh is close enough on a
     desktop viewport, where there is no retracting URL bar to account for. */
  @supports not (height:100svh){ .zr-pp__hero{ min-height:calc(100vh - 40px); } }
}

/* ── the scroll cue ───────────────────────────────────────────────────────
   A one-screen hero centres its copy and leaves the bottom third empty,
   which on a first visit reads as "that is the page". One hairline, drawn
   downward on a loop, is enough to say there is more — no chevron, no mouse
   outline, nothing that needs explaining. Desktop only, because that is the
   only place the hero is a full screen, and off under reduced motion.
   ───────────────────────────────────────────────────────────────────────── */
@media (min-width:900px){
  .zr-pp__hero::after{
    content:""; position:absolute; z-index:1; pointer-events:none;
    left:50%; bottom:30px; translate:-50% 0;
    width:1px; height:46px; border-radius:1px;
    background:linear-gradient(180deg, rgba(31,35,40,0) 0%, rgba(31,35,40,.34) 55%, rgba(31,35,40,0) 100%);
    animation:zr-pp-cue 2.8s cubic-bezier(.5,0,.5,1) 1.8s infinite;
  }
}
@keyframes zr-pp-cue{
  0%  { opacity:0; transform:translateY(-14px) scaleY(.45); }
  30% { opacity:1; }
  70% { opacity:1; }
  100%{ opacity:0; transform:translateY(14px)  scaleY(1); }
}
@media (prefers-reduced-motion:reduce){
  .zr-pp__hero::after{ display:none; }
  .zr-pp__burst, .zr-pp__glow, .zr-pp__aurora{ animation:none !important; }
}

/* ── hero backdrop ────────────────────────────────────────────────────────
   One backdrop for all twenty pages, built from the comps' own language
   (Figma humV0zBvd9Q3QRc4N4QDUH · 9921:22915): a pale tinted field, the
   four-point burst sitting *inside* the card, a fine speckle over both, and
   a white pool under the copy so the headline never lands on a colour.

   The burst used to be three ribbons stretched edge to edge with
   preserveAspectRatio="none", which squashed them into a lopsided heart and
   ran them off the right edge. It is now the comps' actual silhouette
   (assets/hero-burst.svg, the export the MCP hero already used), masked so
   CSS paints it, sized against the card's *height* and inset from the right
   — so it is whole on any viewport, and nothing is cropped.

   Palette per page: --b1..--b4 are the burst's four arms, --tint the field.
   ───────────────────────────────────────────────────────────────────────── */
.zr-pp__hero{
  --b1:#3B8BFF;   /* core          */
  --b2:#57C98A;   /* upper-left    */
  --b3:#F7B267;   /* lower         */
  --b4:#B39BF5;   /* upper-right   */
  --tint:#EAF2FE; /* the field     */
  --tint2:#F6F3FF;
  /* …and the silhouette that light is cut to. Every page used to wear the
     same four-point star; each one now carries the mark of an assistant it
     talks about, in a corner of its own, so twenty-three heroes are not the
     same picture twenty-three times. Two knobs come with the shape:
     --mark-boost multiplies every opacity, --mark-soft every blur. A solid
     star takes the full wash; a line-art knot like OpenAI's is mostly hole,
     so it wants a little more weight and a lot less blur to stay a shape. */
  --mark:url(/assets/hero-burst.svg);
  --mark-ar:1132/1077;
  --mark-fall:62% 62% at 54% 52%;   /* the falloff, tuned to the shape */
  --mark-boost:1;
  --mark-soft:1;
  --mark-in:clamp(10px,2.4vw,52px); /* a corner mark's inset */
}
.zr-pp__bg{
  position:absolute; inset:0; z-index:0;
  pointer-events:none; border-radius:inherit; overflow:hidden;
}
.zr-pp__bg > span{ position:absolute; display:block; }

/* the field: two soft pools that drift against each other */
.zr-pp__aurora{
  inset:-12%;
  background:
    radial-gradient(46% 58% at 12% 26%, var(--tint) 0%, rgba(255,255,255,0) 68%),
    radial-gradient(52% 62% at 88% 74%, var(--tint2) 0%, rgba(255,255,255,0) 70%),
    linear-gradient(168deg, var(--tint) 0%, #FFFFFF 52%, var(--tint2) 100%);
  animation:zr-pp-drift 34s var(--zr-ease,ease-in-out) infinite;
}
@keyframes zr-pp-drift{
  0%,100%{ transform:translate3d(0,0,0) scale(1); }
  50%    { transform:translate3d(-1.6%,1.2%,0) scale(1.05); }
}

/* the burst, and the halo it throws. Both are the same silhouette; the halo
   is the blurred, larger, fainter copy the comp paints underneath. */
.zr-pp__burst,
.zr-pp__glow{
  top:50%; right:clamp(10px,4vw,78px);
  height:min(70%, 620px); aspect-ratio:var(--mark-ar);
  /* two masks intersected: the silhouette, and a radial falloff that makes
     the four arm tips dissolve instead of ending in a point. Without the
     falloff the shape reads as a sticker no matter how much blur it carries
     — this is what the comp's own 0.49-opacity, 50px-blur star is doing. */
  -webkit-mask-image:var(--mark), radial-gradient(var(--mark-fall), #000 22%, rgba(0,0,0,.35) 62%, rgba(0,0,0,0) 88%);
          mask-image:var(--mark), radial-gradient(var(--mark-fall), #000 22%, rgba(0,0,0,.35) 62%, rgba(0,0,0,0) 88%);
  -webkit-mask-size:contain, 100% 100%;  mask-size:contain, 100% 100%;
  -webkit-mask-repeat:no-repeat;         mask-repeat:no-repeat;
  -webkit-mask-position:center;          mask-position:center;
  -webkit-mask-composite:source-in;      mask-composite:intersect;
  background:
    radial-gradient(40% 40% at 70% 60%, var(--b1) 0%, rgba(255,255,255,0) 72%),
    radial-gradient(36% 32% at 33% 25%, var(--b2) 0%, rgba(255,255,255,0) 74%),
    radial-gradient(32% 40% at 42% 90%, var(--b3) 0%, rgba(255,255,255,0) 74%),
    radial-gradient(44% 42% at 72% 16%, var(--b4) 0%, rgba(255,255,255,0) 76%),
    var(--b1);
  translate:0 -50%;
  transform-origin:52% 50%;
  will-change:transform;
}
/* soft, not loud: the comp's star is a wash the copy sits beside, not a
   graphic competing with it. 44px of blur is what turns the silhouette from
   a shape into light — below about 30 it reads as a sticker. */
.zr-pp__burst{
  opacity:calc(.62 * var(--mark-boost));
  filter:blur(calc(clamp(26px,3.4vw,52px) * var(--mark-soft))) saturate(1.06);
}
.zr-pp__glow{
  height:min(96%, 880px);
  opacity:calc(.18 * var(--mark-boost));
  filter:blur(calc(clamp(44px,6vw,88px) * var(--mark-soft)));
}
@keyframes zr-pp-burst{
  0%,100%{ transform:rotate(-2.6deg) scale(1); }
  50%    { transform:rotate(2.6deg)  scale(1.05); }
}
/* it arrives with the hero rather than being there already: the entrance
   runs once, then hands over to the loop at the angle it finished on. */
.zr-pp__burst{ animation:zr-pp-rise 1.25s var(--zr-ease-out-quart,cubic-bezier(.165,.84,.44,1)) both,
                          zr-pp-burst 30s ease-in-out 1.25s infinite; }
.zr-pp__glow { animation:zr-pp-rise 1.6s  var(--zr-ease-out-quart,cubic-bezier(.165,.84,.44,1)) both,
                          zr-pp-burst 34s ease-in-out 1.6s infinite reverse; }
/* the entrance only moves transform — opacity stays on the element, so the
   loop picks it up at exactly the weight the rule set. */
@keyframes zr-pp-rise{
  from{ transform:rotate(-10deg) scale(.82); }
  to  { transform:rotate(-2.6deg) scale(1); }
}

/* the speckle the comps carry over the whole card */
/* The comp's card carries a fine speckle. At 4px with an overlay blend it
   moired into a visible grid over the burst — 3px, a half-pixel dot and a
   plain low opacity read as grain instead of as a pattern. */
.zr-pp__grain{
  inset:0; opacity:.34;
  background-image:radial-gradient(rgba(255,255,255,.85) .5px, rgba(255,255,255,0) .9px);
  background-size:3px 3px;
}

/* a white pool under the copy — the headline never sits on an arm */
.zr-pp__veil{
  inset:0;
  background:radial-gradient(56% 80% at 14% 48%, rgba(255,255,255,.96) 0%, rgba(255,255,255,.72) 40%, rgba(255,255,255,0) 74%);
}
.zr-pp__hero--center .zr-pp__veil{
  background:radial-gradient(62% 58% at 50% 42%, rgba(255,255,255,.94) 0%, rgba(255,255,255,.62) 46%, rgba(255,255,255,0) 78%);
}
/* a centred hero has copy where a right-hand burst would be loudest, so the
   burst moves out and down and loses a little weight */
/* a centred hero puts the copy exactly where a centred burst would be, so
   the burst drops to the lower right and reads as a corner light instead. */
.zr-pp__hero--center .zr-pp__burst,
.zr-pp__hero--center .zr-pp__glow{
  top:auto; bottom:clamp(10px,2.4vw,44px); right:clamp(10px,2.4vw,52px);
  translate:0 0; height:min(56%, 470px);
}
.zr-pp__hero--center .zr-pp__glow { height:min(78%, 640px); opacity:calc(.15 * var(--mark-boost)); }
.zr-pp__hero--center .zr-pp__burst{ opacity:calc(.5 * var(--mark-boost)); }

/* ── which corner the mark sits in ───────────────────────────────────────
   The two rules above are the defaults: centre-right on a split hero,
   lower-right on a centred one. --tl/--tr/--bl/--br pin it to a corner
   instead. Corner placement always drops to the centred hero's smaller
   size — a full-height mark tucked into a corner is cropped by the card. */
.zr-pp__hero--tl .zr-pp__burst, .zr-pp__hero--tl .zr-pp__glow,
.zr-pp__hero--tr .zr-pp__burst, .zr-pp__hero--tr .zr-pp__glow,
.zr-pp__hero--bl .zr-pp__burst, .zr-pp__hero--bl .zr-pp__glow,
.zr-pp__hero--br .zr-pp__burst, .zr-pp__hero--br .zr-pp__glow{
  top:auto; right:auto; bottom:auto; left:auto;
  translate:0 0; height:min(56%, 470px);
}
.zr-pp__hero--tl .zr-pp__glow,
.zr-pp__hero--tr .zr-pp__glow,
.zr-pp__hero--bl .zr-pp__glow,
.zr-pp__hero--br .zr-pp__glow{ height:min(78%, 640px); }
.zr-pp__hero--tl .zr-pp__burst, .zr-pp__hero--tl .zr-pp__glow{ top:var(--mark-in);    left:var(--mark-in);  }
.zr-pp__hero--tr .zr-pp__burst, .zr-pp__hero--tr .zr-pp__glow{ top:var(--mark-in);    right:var(--mark-in); }
.zr-pp__hero--bl .zr-pp__burst, .zr-pp__hero--bl .zr-pp__glow{ bottom:var(--mark-in); left:var(--mark-in);  }
.zr-pp__hero--br .zr-pp__burst, .zr-pp__hero--br .zr-pp__glow{ bottom:var(--mark-in); right:var(--mark-in); }
/* a mark in a top corner sits where the nav's glass bar crosses the card,
   so it comes down a shade rather than competing with the menu */
.zr-pp__hero--tl .zr-pp__burst,
.zr-pp__hero--tr .zr-pp__burst{ opacity:calc(.44 * var(--mark-boost)); }
/* …and a second, cooler one rises from the far left so the card is lit from
   both corners rather than weighted into one. */
.zr-pp__hero--center .zr-pp__aurora{
  background:
    radial-gradient(44% 56% at 6% 82%, var(--tint2) 0%, rgba(255,255,255,0) 66%),
    radial-gradient(50% 52% at 92% 8%, var(--tint) 0%, rgba(255,255,255,0) 68%),
    linear-gradient(172deg, var(--tint) 0%, #FFFFFF 46%, var(--tint2) 100%);
}

/* ── per-page palettes ────────────────────────────────────────────────────
   Five families, so twenty pages still read as one site: product (blue),
   research (indigo), optimize (green), automate (violet) and company
   (slate-blue). Each keeps the burst's four arms in the same order. */
.zr-pp--tracking { --b1:#3B8BFF; --b2:#64D2A2; --b3:#F5B168; --b4:#A78BFA; --tint:#E9F1FE; --tint2:#F4F1FF; }
.zr-pp--prompts  { --b1:#5B7CFA; --b2:#4FC3E8; --b3:#F2A0C8; --b4:#9C8CF7; --tint:#ECEFFE; --tint2:#EFF8FC; }
.zr-pp--optimize { --b1:#3BA0F5; --b2:#5FD08A; --b3:#F7C566; --b4:#8FB8FA; --tint:#E8F6F5; --tint2:#EFF6FF; }
.zr-pp--workflows{ --b1:#4C7BFF; --b2:#7FD3F0; --b3:#C9B0FA; --b4:#8A6DF5; --tint:#EAF0FF; --tint2:#F2EEFF; }
.zr-pp--copilot  { --b1:#6D5BF6; --b2:#4FA8F5; --b3:#F49BC4; --b4:#B79BFA; --tint:#F0ECFE; --tint2:#EDF4FF; }
.zr-pp--about,
.zr-pp--changelog,
.zr-pp--roadmap  { --b1:#4B85F0; --b2:#8FB9F7; --b3:#D9C3F7; --b4:#A3C4FA; --tint:#EEF2FB; --tint2:#F4F0FD; }
.zr-pp--cases,
.zr-pp--case     { --b1:#3E7DF2; --b2:#6FD0B2; --b3:#F6BE86; --b4:#9DB8FB; --tint:#EAF1FD; --tint2:#EFFAF6; }
.zr-pp--compare,
.zr-pp--vs       { --b1:#4276E8; --b2:#7FA8F5; --b3:#F0B7A0; --b4:#B3A6F7; --tint:#EDF1FB; --tint2:#F7F1F6; }
.zr-pp--tools    { --b1:#2FA7C9; --b2:#66D2A6; --b3:#F5CB74; --b4:#8DC0F7; --tint:#E7F5F8; --tint2:#F0FAF3; }
.zr-pp--sol      { --b1:#4A79F5; --b2:#74CBEF; --b3:#EFAFCB; --b4:#9E90F8; --tint:#EBF0FE; --tint2:#F3EFFD; }

/* ── the hero marks ───────────────────────────────────────────────────────
   The silhouettes are the same brand marks the engine lists carry, exported
   flat into assets/hero-mark-*.svg. Nothing here paints them: they only cut
   the page's own four-arm gradient, so a ChatGPT hero and a Claude hero are
   still the same palette and still read as one site.

   All six sit on a 24x24 square and reach further into their box than the
   star does, so they take a wider falloff. --boost and --soft are per-shape:
   the rule of thumb is that the thinner the line work, the more weight and
   the less blur it needs before it stops being a shape and turns to fog. */
.zr-pp__hero--gpt,
.zr-pp__hero--claude,
.zr-pp__hero--perplexity,
.zr-pp__hero--copilot,
.zr-pp__hero--grok,
.zr-pp__hero--mistral{ --mark-ar:1; --mark-fall:70% 70% at 50% 50%; }

/* the knot is the thinnest of them: barely any of its box is ink, so it
   carries the most weight and the least blur of the set */
.zr-pp__hero--gpt       { --mark:url(/assets/hero-mark-gpt.svg);        --mark-boost:1.24; --mark-soft:.58; }
/* the sunburst is the densest of them — it needs holding *back*, or a
   corner of the card turns into a firework */
.zr-pp__hero--claude    { --mark:url(/assets/hero-mark-claude.svg);     --mark-boost:.82;  --mark-soft:1.1; }
.zr-pp__hero--perplexity{ --mark:url(/assets/hero-mark-perplexity.svg); --mark-boost:1.1;  --mark-soft:.9;  }
.zr-pp__hero--copilot   { --mark:url(/assets/hero-mark-copilot.svg);    --mark-boost:1.06; --mark-soft:.78; }
.zr-pp__hero--grok      { --mark:url(/assets/hero-mark-grok.svg);       --mark-boost:1.18; --mark-soft:.64; }
/* …and the one made of squares needs the blur back, or the right angles
   read as pixels rather than as light */
.zr-pp__hero--mistral   { --mark:url(/assets/hero-mark-mistral.svg);    --mark-boost:1.1;  --mark-soft:.9;  }

.zr-pp__hero-grid{
  position:relative; z-index:1;
  display:grid; grid-template-columns:minmax(0,548px) minmax(0,1fr);
  gap:clamp(32px,4vw,72px); align-items:center;
  width:min(1248px,100%); margin:0 auto;
}
.zr-pp__copy{ display:flex; flex-direction:column; align-items:flex-start; gap:20px; }
.zr-pp__eyebrow{
  display:inline-flex; align-items:center; gap:8px;
  padding:6px 14px; border:1px solid var(--pp-hair); border-radius:999px;
  background:rgba(255,255,255,.85); font-size:13px; line-height:18px; color:var(--pp-body);
}
.zr-pp__eyebrow--red{ color:#B42318; border-color:#F4D3D0; }
.zr-pp__h1{
  margin:0; text-wrap:balance;
  font-size:clamp(34px,4.4vw,58px); font-weight:500; line-height:1.12;
  letter-spacing:-.032em;
  background:var(--zr-head-grad);
  -webkit-background-clip:text; background-clip:text; color:transparent; -webkit-text-fill-color:transparent;
}
.zr-pp__lede{ margin:0; max-width:520px; font-size:16.5px; line-height:26px; color:var(--pp-body); text-wrap:pretty; }
.zr-pp__cta{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin-top:4px; }
.zr-pp__field{ margin-top:4px; }
.zr-pp__note{ margin:-8px 0 0; font-size:13px; color:var(--pp-dim); }
.zr-pp__btn{
  display:inline-flex; align-items:center; gap:10px;
  height:48px; padding-inline:24px; border-radius:10px;
  font-size:15px; font-weight:500; text-decoration:none; cursor:pointer; white-space:nowrap;
  transition:background .16s linear, box-shadow .16s linear, border-color .16s linear;
}
.zr-pp__btn svg{ width:20px; height:20px; flex:0 0 auto; }
.zr-pp__btn--primary{
  border:0; background:var(--zr-blue); color:#fff;
  box-shadow:0 1px 1px rgba(0,0,0,.1), inset 0 3px 14px rgba(255,255,255,.35);
}
.zr-pp__btn--primary:hover{ background:#0D55DD; box-shadow:0 1px 1px rgba(0,0,0,.1), inset 0 3px 14px rgba(255,255,255,.5); }
.zr-pp__btn--ghost{ border:1px solid var(--pp-hair); background:#fff; color:var(--pp-ink); box-shadow:0 1px 2px rgba(0,0,0,.06); }
.zr-pp__btn--ghost:hover{ border-color:#C9D6F2; background:#FAFBFD; }
.zr-pp__btn:active{ translate:0 1px; }
.zr-pp__visual{ min-width:0; }

/* ── sections ─────────────────────────────────────────────────────────── */
.zr-pp__sec{ padding-block:clamp(52px,5.6vw,92px); }
.zr-pp__sec--flush{ padding-top:0; }
.zr-pp__head{
  display:flex; flex-direction:column; align-items:center; text-align:center; gap:14px;
  max-width:820px; margin:0 auto clamp(28px,3.2vw,48px);
}
.zr-pp__head--left{ align-items:flex-start; text-align:left; margin-inline:0; }
.zr-pp__kicker{
  display:inline-flex; align-items:center; gap:6px; padding:5px 13px;
  border:1px solid var(--pp-hair); border-radius:999px; background:#fff;
  font-size:12.5px; line-height:18px; color:var(--pp-body);
}
.zr-pp__kicker--red { color:#B42318; border-color:#F4D3D0; }
.zr-pp__kicker--blue{ color:var(--zr-blue); border-color:#CFE0FF; }
.zr-pp__h2{
  margin:0; text-wrap:balance;
  font-size:clamp(28px,3.4vw,46px); font-weight:500; line-height:1.16;
  letter-spacing:-.03em;
  background:var(--zr-head-grad);
  -webkit-background-clip:text; background-clip:text; color:transparent; -webkit-text-fill-color:transparent;
}
.zr-pp__h3{ margin:0; font-size:clamp(22px,2.2vw,28px); font-weight:500; line-height:1.25; letter-spacing:-.024em; color:var(--pp-ink); }
.zr-pp__sub{ margin:0; max-width:720px; font-size:16.5px; line-height:26px; color:var(--pp-dim); text-wrap:pretty; }
.zr-pp__sub b{ font-weight:500; color:var(--pp-ink); }
.zr-pp__head .zr-pp__btn{ margin-top:6px; }
.zr-pp__more{
  display:inline-flex; align-items:center; gap:6px; margin-top:18px;
  font-size:15px; font-weight:500; color:var(--zr-blue); text-decoration:none;
}
.zr-pp__more svg{ width:18px; height:18px; transition:translate .25s var(--zr-ease); }
.zr-pp__more:hover svg{ translate:4px 0; }
.zr-pp__center{ display:flex; justify-content:center; }

/* the soft frame the comps put around a row of white cards */
.zr-pp__frame{ padding:10px; border-radius:24px; background:var(--pp-frame); border:1px solid #EEF1F5; }
.zr-pp__card{ background:#fff; border:1px solid #EDF1F7; border-radius:18px; box-shadow:0 6px 16px -6px rgba(31,36,41,.05); }

/* chips — the comps' status colours */
.zr-chip{
  display:inline-flex; align-items:center; gap:6px;
  padding:3px 9px; border-radius:7px;
  font-size:12px; font-weight:500; line-height:16px; white-space:nowrap;
  background:#F1F3F6; color:#4B5563;
}
.zr-chip i{ width:6px; height:6px; border-radius:50%; background:currentColor; display:inline-block; flex:0 0 auto; }
.zr-chip--green { background:#E4F7EC; color:#0F7A45; }
.zr-chip--blue  { background:#E8F0FE; color:#1D4ED8; }
.zr-chip--red   { background:#FDECEC; color:#B42318; }
.zr-chip--amber { background:#FFF3E0; color:#9A5B00; }
.zr-chip--violet{ background:#F0EBFF; color:#5B3FD9; }
.zr-chip--mono  { font-family:var(--pp-mono); font-weight:400; letter-spacing:.01em; }
.zr-mono{ font-family:var(--pp-mono); }

/* the engine marks — the sprite is single-colour, each brand paints its own */
.zr-eng{ display:inline-flex; align-items:center; gap:9px; min-width:0; font-size:14px; font-weight:500; color:var(--pp-ink); }
.zr-eng svg{ width:18px; height:18px; flex:0 0 auto; color:var(--_c,#6B7280); }
.zr-eng--gpt    { --_c:#10A37F; }
.zr-eng--gemini { --_c:#4E8BF5; }
.zr-eng--pplx   { --_c:#20808D; }
.zr-eng--claude { --_c:#D97757; }
.zr-eng--copilot{ --_c:#0F6CBD; }

/* a favicon stand-in: the site's initial on its own colour (see mcp.html) */
.zr-fav{
  display:grid; place-items:center; width:18px; height:18px; flex:0 0 auto;
  border-radius:5px; background:var(--fav,#9AA1AC); color:#fff;
  font-size:10px; font-weight:600; font-style:normal; line-height:1;
}
.zr-fav svg{ width:11px; height:11px; color:#fff; }

/* skeleton lines for a mock page */
.zr-skel{ display:flex; flex-direction:column; gap:10px; }
.zr-skel i{ display:block; height:10px; width:var(--w,80%); border-radius:5px; background:var(--sk,rgba(255,255,255,.14)); }

/* ── the dark bento ────────────────────────────────────────────────────── */
.zr-bento{ display:grid; grid-template-columns:repeat(12, minmax(0,1fr)); gap:16px; }
.zr-dk{
  position:relative; isolation:isolate; overflow:clip;
  display:flex; flex-direction:column; justify-content:flex-end;
  min-height:300px; padding:28px; border-radius:24px;
  color:#fff; background:#0B0C10;
}
/* the grain every dark card in the comps carries */
.zr-dk::after{
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none; opacity:.4;
  background-image:radial-gradient(rgba(255,255,255,.09) .6px, transparent .9px);
  background-size:3px 3px;
}
.zr-dk--indigo{ background:radial-gradient(110% 80% at 18% 0%, #1E1F7A 0%, #121236 38%, #0B0C10 78%); }
.zr-dk--wine  { background:radial-gradient(110% 80% at 18% 0%, #4A0F1E 0%, #22070F 40%, #0B0C10 80%); }
.zr-dk--teal  { background:radial-gradient(110% 80% at 18% 0%, #0E5C63 0%, #093A40 38%, #0B0C10 80%); }
.zr-dk--forest{ background:radial-gradient(110% 80% at 18% 0%, #123B2A 0%, #0B2419 40%, #0B0C10 82%); }
.zr-dk--ocean { background:radial-gradient(110% 80% at 18% 0%, #0B3C7A 0%, #0A2247 40%, #0B0C10 82%); }
.zr-dk--plum  { background:radial-gradient(110% 80% at 18% 0%, #3B1360 0%, #1E0B33 40%, #0B0C10 82%); }
.zr-dk__viz{ flex:1 1 auto; display:flex; flex-direction:column; margin:-4px -4px 22px; min-height:0; }
.zr-dk h3{ margin:0 0 10px; font-size:clamp(19px,1.7vw,23px); font-weight:500; line-height:1.25; letter-spacing:-.02em; color:#fff; }
.zr-dk p { margin:0; font-size:15px; line-height:24px; color:rgba(255,255,255,.72); text-wrap:pretty; }
.zr-glass{ border:1px solid rgba(255,255,255,.1); border-radius:14px; background:rgba(255,255,255,.05); }
/* a horizontal bar, --v is the fill */
.zr-bar{ position:relative; display:block; height:8px; border-radius:999px; background:rgba(255,255,255,.12); overflow:hidden; }
.zr-bar::after{ content:""; position:absolute; inset:0; width:var(--v,50%); border-radius:inherit; background:linear-gradient(90deg,#1463F5,#0091FF); }
.zr-bar--light{ background:#E9EEF6; }
.zr-bar--light::after{ background:linear-gradient(90deg,#1463F5,#5AA5FF); }

/* ── an AI answer, as the product shows it back ───────────────────────────
   Tracking uses it to explain a mention against a citation; Optimization
   uses two of them side by side as before-and-after proof. */
.zr-answer{ padding:22px; }
.zr-answer__q{ display:flex; justify-content:flex-end; }
.zr-answer__q span{ padding:12px 16px; border-radius:12px; background:#F3F4F6; font-size:14.5px; font-weight:500; color:var(--pp-ink); }
.zr-answer__meta{ display:flex; justify-content:flex-end; align-items:center; gap:10px; margin-top:8px; font-size:12px; color:var(--pp-dim); }
.zr-answer__meta svg{ width:14px; height:14px; color:#9AA1AC; }
.zr-answer__thought{ display:flex; align-items:center; gap:6px; margin-top:22px; font-size:13px; color:var(--pp-dim); }
.zr-answer__thought svg{ width:12px; height:12px; }
.zr-answer__body{ display:flex; gap:12px; margin-top:12px; }
.zr-answer__av{ display:grid; place-items:center; width:26px; height:26px; flex:0 0 auto; border-radius:50%; background:#E7F5EF; color:#10A37F; }
.zr-answer__av svg{ width:14px; height:14px; }
.zr-answer__body p{ margin:0 0 10px; font-size:14px; line-height:22px; color:var(--pp-body); }
.zr-answer__body p b{ font-weight:600; color:var(--pp-ink); }
.zr-answer__acts{ display:flex; gap:12px; color:#9AA1AC; }
.zr-answer__acts svg{ width:15px; height:15px; }
.zr-answer__src{ margin-top:18px; }
.zr-answer__srch{ display:flex; align-items:center; gap:6px; font-family:var(--pp-mono); font-size:11px; letter-spacing:.1em; color:#9AA1AC; }
.zr-answer__srch svg{ width:12px; height:12px; }
.zr-answer__src ul{ list-style:none; margin:10px 0 0; padding:0; display:flex; flex-direction:column; gap:9px; }
.zr-answer__src li{ display:flex; align-items:center; gap:10px; font-family:var(--pp-mono); font-size:12px; color:var(--pp-body); min-width:0; }
.zr-answer__src li span{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.zr-answer__src li .zr-chip{ margin-left:auto; }

/* ── a two-column band: copy beside a short list of links ────────────────
   Closes the Copilot, About and solutions pages. */
/* The band carries the homepage radar's own backdrop rather than the flat
   grey it used to sit on, so the copy inverts to white over it.

   The radar itself ramps #0091FF straight to white, which is fine under a
   40px hero headline and not fine under 14.5px body copy — white on #0091FF
   is 2.3:1. This uses both of the blues .scanner declares, --blue-deep into
   --blue, and holds --blue back to 85% so the top of the ramp stays deep
   where the text is: 5.5:1 on the kicker, 5.0:1 on the heading and 4.5:1 on
   the paragraph of the longest of the three bands. Move those stops and
   re-measure the paragraph — it is the one that binds. The rows below are
   white cards, and the shot lands on the pale end where its own chrome
   meets the panel. */
.zr-tools{
  display:grid; grid-template-columns:minmax(0,1.2fr) minmax(0,1fr);
  align-items:center; gap:clamp(20px,3vw,48px); padding:clamp(24px,3vw,40px);
  border-radius:24px; border:1px solid #0064D6;
  background:linear-gradient(180deg, #0064D6 0%, var(--zr-blue-lit) 85%, #fff 100%);
}
/* a white pill with the deep blue inside it, like the radar's own button */
.zr-tools .zr-pp__kicker{ border-color:transparent; background:#fff; color:#0064D6; }
.zr-tools .zr-pp__h3{ margin-top:12px; color:#fff; }
.zr-tools p{ margin:10px 0 0; font-size:14.5px; line-height:22px; color:#fff; text-wrap:pretty; }

/* The screenshot runs the width of the panel and is cut by its bottom edge,
   so it reads as the app continuing past the page rather than as a picture
   someone pasted into the box. The panel's own radius does the clipping;
   the image carries its rounded top in its alpha. */
.zr-tools--shot{ align-items:start; overflow:hidden; padding-bottom:0; row-gap:clamp(20px,2.5vw,32px); }
.zr-tools__shot{ grid-column:1 / -1; height:clamp(150px,25vw,360px); }
.zr-tools__shot img{
  display:block; width:100%; height:auto;
  box-shadow:0 0 0 1px rgba(23,33,54,.05), 0 26px 50px -34px rgba(23,33,54,.45);
  border-radius:15px 15px 0 0;
}
.zr-tools__list{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:8px; }
.zr-tools__list li{ display:flex; align-items:center; gap:12px; padding:12px 14px; border-radius:12px; background:#fff; border:1px solid #EDF1F7; font-size:14px; color:var(--pp-ink); }
.zr-tools__list li i{ display:grid; place-items:center; width:28px; height:28px; flex:0 0 auto; border-radius:8px; background:#E8F0FE; color:var(--zr-blue); }
.zr-tools__list li i svg{ width:15px; height:15px; }
.zr-tools__list li .zr-chip{ margin-left:auto; }
.zr-tools__list a{ color:var(--zr-blue); text-decoration:none; }

@media (max-width:1280px){
  .zr-cp{ grid-template-columns:minmax(0,1fr); }
  .zr-cp__feed{ display:none; }
}

/* ── the case studies + quote block is the homepage's, reused ─────────── */
.zr-pp + .zr-cases{ padding-top:clamp(8px,1.6vw,20px); }

/* ── responsive ───────────────────────────────────────────────────────── */
@media (max-width:1200px){
  .zr-pp__hero-grid{ grid-template-columns:minmax(0,1fr) minmax(0,1.15fr); }
  .zr-pp__h1{ font-size:clamp(34px,4vw,48px); }
}
@media (max-width:1040px){
  .zr-pp__hero-grid{ grid-template-columns:minmax(0,1fr); gap:40px; }
  .zr-pp__copy{ align-items:center; text-align:center; }
  .zr-pp__lede{ max-width:600px; }
  .zr-pp__cta{ justify-content:center; }
  .zr-pp__visual{ width:min(660px,100%); margin:0 auto; }
  .zr-tools{ grid-template-columns:minmax(0,1fr); }
  .zr-bento{ grid-template-columns:repeat(6, minmax(0,1fr)); }
}
@media (max-width:720px){
  .zr-bento{ grid-template-columns:minmax(0,1fr); }
  .zr-dk{ min-height:0; padding:22px; }
  .zr-pp__frame{ padding:6px; border-radius:18px; }
}
/* ── the hero on a small screen ───────────────────────────────────────────
   The nav's layout box is 96px here, so a 84px lift lands the card 12px from
   the top — the same inset it keeps on the other three sides. The burst is
   sized against the card's *width* rather than its height: at phone
   proportions a height-sized burst is wider than the card and gets clipped
   on both edges, which is exactly the thing being fixed. */
/* every hero folds back to one placement on a phone — a corner mark at this
   width is either clipped or sitting on the copy. Selectors match the corner
   rules' weight (two classes) and come later, so they win. */
@media (max-width:900px){
  .zr-pp__hero .zr-pp__burst,
  .zr-pp__hero .zr-pp__glow{
    top:auto; left:auto; translate:0 0;
    bottom:clamp(22px,4vw,40px); right:clamp(18px,3.4vw,36px);
    width:min(64%, 380px); height:auto;
  }
  .zr-pp__hero .zr-pp__glow{ width:min(92%, 520px); }
  .zr-pp__burst{ opacity:calc(.52 * var(--mark-boost)); }
  .zr-pp__grain{ opacity:.22; }
  .zr-pp__veil{
    background:radial-gradient(76% 54% at 50% 34%, rgba(255,255,255,.94) 0%, rgba(255,255,255,.64) 52%, rgba(255,255,255,0) 84%);
  }
}
@media (max-width:620px){
  /* margin is a shorthand: it has to restate the lift or the card drops
     below the nav instead of sliding under it. */
  .zr-pp__hero{
    --pp-lift:84px;
    margin:12px; margin-top:calc(-1 * var(--pp-lift));
    padding-top:calc(var(--pp-lift) + 36px);
  }
}
