/*
 * multiagentry.com
 *
 * Static: HTML, CSS and images. No JavaScript, no CMS, no build step.
 *
 * THAT IS A SECURITY DECISION. This site shares a document root with verify.php
 * — the licence endpoint every install heartbeats against — and that docroot's
 * .htaccess denies everything it does not name. A CMS here would mean rewrite
 * rules competing with those denials, and a plugin vulnerability on the
 * marketing site would sit next to the licence server. Nothing here executes.
 *
 * And it cannot acquire JavaScript later by accident: that .htaccess grants
 * html|css|png|jpe?g|gif|svg|webp|ico|woff2?|txt|webmanifest and nothing else,
 * so a .js file would be served a 403. Every effect below is static CSS because
 * that is the only kind of effect this docroot can have.
 *
 * ===========================================================================
 * BUMP MAGY_ASSET_V IN inc/header.php WHEN THIS FILE CHANGES
 * ===========================================================================
 *
 * This host runs an origin cache that served a stale stylesheet for hours after
 * the file on disk had changed — the whole site rendered with the previous
 * design, the deploy reported success, and the only way to see the new CSS was
 * a query string. Nothing about that failure is visible from the server side, so
 * the version in the <link> is the only reliable defence. It lives in one place
 * now; in the HTML version it had to be bumped in each file separately, which is
 * exactly the kind of edit that gets done in three files out of four.
 *
 * ===========================================================================
 * TWO COLOUR FAMILIES, ONE STRUCTURAL VOCABULARY
 * ===========================================================================
 *
 * This comment used to say the palette here was the app's own, and that a token
 * added here belonged in app.css and the dashboard as well. That has not been
 * true since the marketing palette was forked on purpose, and a maintenance
 * instruction that is false is worse than none — it tells the next person to
 * propagate a warm marketing grey into the product UI.
 *
 * The actual boundary:
 *
 *   COLOUR is not shared. app/src/renderer/app.css and server/licences.php run
 *   the app's NUVA palette (#f6f6fa ground, #14141f ink, blue-tinted greys).
 *   This file runs the marketing palette: warm paper, warm ink. The dashboard is
 *   part of the product and belongs on the product's side of that line.
 *
 *   STRUCTURE is shared. --s1..--s7, --motion-fast/--motion/--motion-slow,
 *   --ease and --r-xs are copied byte for byte from app.css so those names mean
 *   one thing on every surface. A new step belongs in both.
 *
 * The iris #5a4fe8 is the exception that proves it: it is the brand, so it is
 * identical in all three, and only its tints differ.
 */

:root {
  /* ------------------------------------------------------------------ brand */
  --accent: #5a4fe8;
  --accent-hover: #4a3fd6;
  --accent-soft: #eceafb;
  --accent-wash: #f6f5fd;
  --accent-ink: #3d33b5;          /* 7.58:1 on --accent-soft — small text on tint */
  --accent-glow: color-mix(in oklab, var(--accent) 22%, transparent);

  /*
   * COOL PAPER — premium ad landing.
   *
   * Warm beige bands (#f0efeb / #ecebe8) read as stained cardboard next to the
   * iris brand. Cool near-white greys (Apple / Linear register) keep white
   * white and still separate sections without looking muddy.
   */
  --bg: #ffffff;
  --bg-2: #f7f7f8;                /* cool soft — one quiet step from white */
  --bg-3: #efeff1;                /* adjacent soft pairs only */
  --surface: #ffffff;
  --surface-2: #fafafa;
  --surface-3: #f2f2f4;
  --border: #e8e8ea;
  --border-strong: #d4d4d8;

  /*
   * Warm ink to match. Contrast against the four grounds above, measured:
   *
   *   --text    17.89 / 16.54 / 15.56 / 15.28
   *   --text-2   9.88 /  9.14 /  8.59 /  8.44
   *   --muted    5.40 /  4.99 /  4.69 /  4.61   <- the tightest in the system
   *
   * --muted on --bg-3 is the one to watch. It passes AA with room to spare and
   * would fail if a fifth, darker ground were ever added. Do not add one.
   */
  --text: #14141a;
  --text-2: #3f3f46;
  --muted: #71717a;

  /*
   * --text was being used directly as a BACKGROUND in two places — the active
   * billing-cycle pill and the diagram tooltips. Both are deliberate inversions,
   * but neither said so, which means lightening --text for softer body copy
   * would silently have broken white-on-dark contrast in a tooltip nobody was
   * looking at. Naming the inverted pair makes that edit safe.
   */
  --on-accent: #ffffff;
  --invert-bg: var(--text);
  --invert-fg: #ffffff;

  --ok: #0b7a55;
  --ok-bg: #e4f5ee;               /* 4.57:1 on --bg-3 */

  --agent-claude: #5a4fe8;
  --agent-cursor: #0f9d8f;
  --agent-codex: #c2612c;

  /* ------------------------------------------------------------------- type */

  /*
   * INTER AS A VARIABLE FONT, WITH THE SYSTEM STACK BEHIND IT.
   *
   * The app uses a system stack because its renderer's CSP forbids a webfont it
   * has no licence to ship. A public page has neither constraint, and Segoe UI
   * was the single biggest reason this did not look like the sites it is
   * modelled on.
   *
   * It was loaded at four static weights — 400, 500, 600, 700 — while the rules
   * below ask for 450, 550, 560, 620, 630, 640, 650 and 680. Every one of those
   * snapped. The file claimed twelve weights and rendered three, which is most
   * of why the typography read as generic, and it paid four requests and 188 KB
   * for the privilege. One variable file is 71 KB with the opsz axis included.
   *
   * Never narrow the axis range in the URL: wght@300..800 returns the identical
   * file as wght@100..900, so a narrower range costs the same and buys less.
   */
  --font: "Inter", "Segoe UI Variable Text", -apple-system, BlinkMacSystemFont,
          "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  /*
   * THE DISPLAY FACE. ONE LINE, AND IT CHANGES THE WHOLE REGISTER.
   *
   * This was Instrument Serif for one deploy. The owner then pointed at a
   * geometric grotesque wordmark and asked for headings and nav to match it, so
   * the serif is gone: a serif headline over a geometric wordmark is two
   * different voices arguing.
   *
   * Plus Jakarta Sans, variable 400-800, 26 KB latin. Wide apertures, near-
   * circular bowls, flat terminals — the register cursor.com and x.ai are in.
   * It carries headings, the nav, the section kickers and the stat figures;
   * Inter keeps the body and every dense UI mock, because Inter is the better
   * tested of the two at 12px inside a diagram cell and swapping the body face
   * is the change most likely to make the illustration blocks look subtly off.
   *
   * Alternates measured at the same time, all on Google Fonts, all one request:
   * Figtree 19 KB, Space Grotesk 21 KB, Manrope 24 KB, Outfit 31 KB. Changing
   * face is this line plus the &family= in inc/header.php and index.php.
   */
  --font-display: "Plus Jakarta Sans", "Segoe UI Variable Display", -apple-system,
                  BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;

  --mono: "Cascadia Mono", ui-monospace, "SF Mono", Consolas, "Liberation Mono", monospace;

  /*
   * Ten sizes, replacing thirty-six hand-picked literals. Fluid only where the
   * size genuinely has to change across the range — a fluid 13px is just 12px on
   * a phone, which is why the small end is fixed. Endpoints are 390 and 1440.
   */
  --t-micro: 0.75rem;             /* 12 */
  --t-xs: 0.8125rem;              /* 13 */
  --t-sm: 0.875rem;               /* 14 */
  --t-md: 0.9375rem;              /* 15 */
  --t-base: 1rem;                 /* 16 */
  --t-lg: clamp(1.0625rem, 1rem + 0.22vw, 1.1875rem);       /* 17 -> 19 */
  --t-h3: clamp(1.1875rem, 1.05rem + 0.56vw, 1.5rem);       /* 19 -> 24 */
  --t-h2: clamp(1.75rem, 1.31rem + 1.8vw, 2.75rem);         /* 28 -> 44 */
  --t-h1: clamp(2.5rem, 1.62rem + 3.6vw, 4.5rem);           /* 40 -> 72 */
  --t-display: clamp(2.75rem, 1.65rem + 4.5vw, 5.25rem);    /* 44 -> 84 */

  /* x.ai runs its entire homepage on two weights, 400 and 550. Five is already
     generous — resist adding a sixth. */
  --w-body: 400;
  --w-med: 500;
  --w-semi: 550;
  --w-bold: 620;
  --w-head: 660;

  --lh-tight: 1.04;
  --lh-head: 1.14;
  --lh-snug: 1.35;
  --lh-body: 1.6;
  --lh-loose: 1.7;

  /*
   * Inter's own optical tracking curve. The old file set -0.045em on the h1,
   * tighter than Inter's own -3.0% at that size, and everything 12px and under
   * inherited the body's -0.011em — so 10.5px text was set TIGHTER than 16px
   * text. Small text wants more space, not less, which is what --tr-micro is.
   */
  --tr-display: -0.038em;
  --tr-h2: -0.03em;
  --tr-h3: -0.022em;
  --tr-body: -0.011em;
  --tr-sm: -0.004em;
  --tr-micro: 0.006em;
  --tr-caps: 0.085em;

  /* ---------------------------------------------------------------- spacing */

  /* --s1..--s7 are byte-identical to app/src/renderer/app.css. --s8 and up are
     marketing-only: the app has no page this tall. */
  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 24px;
  --s6: 32px;
  --s7: 48px;
  --s8: 64px;
  --s9: 80px;
  --s10: 96px;
  --s11: 128px;

  /* Three beats, not one. Every gap on this page used to be the same 104px,
     which is a large part of why it read as a list rather than an argument. */
  --sec-y: clamp(72px, 3.2rem + 5.33vw, 128px);
  --sec-y-sm: clamp(56px, 2.75rem + 3.05vw, 88px);
  --sec-y-lg: clamp(96px, 3.95rem + 8.4vw, 184px);
  --gutter: clamp(20px, 4vw, 32px);

  --wrap: 1140px;
  --wrap-wide: 1280px;            /* the product shot, wider than the copy */
  --wrap-text: 760px;
  --nav-h: 54px;

  /* ----------------------------------------------------------------- radius */

  /* Five steps was right; two of the values were not. 8 and 12 are four pixels
     apart and indistinguishable, while 18 -> 26 was a gap nothing sat in, and 26
     on a 1140px frame reads app-store rather than developer-tool. */
  --r-xs: 6px;
  --r-sm: 8px;
  --r: 12px;
  --r-lg: 16px;
  --r-xl: 22px;
  --r-full: 999px;

  /* -------------------------------------------------------------- elevation */

  /*
   * The shadow colour was rgba(20,20,31) — a blue-black inherited from the app's
   * #14141f, which never matched this file's own ink even when the ink was cold.
   * On warm paper a blue shadow goes green-grey. Derived from --text now.
   *
   * --edge is the one nobody expects to matter: a 1px inset white highlight
   * along the top of a raised surface. It does more for how expensive a frame
   * looks than the glow behind it does.
   */
  --shadow-rgb: 24 24 28;
  --shadow-xs: 0 1px 2px rgb(var(--shadow-rgb) / .04);
  --shadow-sm: 0 1px 2px rgb(var(--shadow-rgb) / .04), 0 2px 6px rgb(var(--shadow-rgb) / .04);
  --shadow: 0 1px 2px rgb(var(--shadow-rgb) / .04), 0 8px 20px -6px rgb(var(--shadow-rgb) / .08);
  --shadow-md: 0 2px 4px rgb(var(--shadow-rgb) / .04), 0 14px 32px -10px rgb(var(--shadow-rgb) / .12);
  --shadow-lg: 0 4px 8px rgb(var(--shadow-rgb) / .03), 0 24px 48px -16px rgb(var(--shadow-rgb) / .14);
  --shadow-nav: 0 1px 0 rgb(var(--shadow-rgb) / .04), 0 8px 24px -14px rgb(var(--shadow-rgb) / .08);
  --edge: inset 0 1px 0 rgb(255 255 255 / .85);

  /* Two rings, not one. A flat accent ring on a violet button is violet on
     violet; the white spacer cuts it out of whatever ground it lands on. */
  --ring: 0 0 0 2px var(--bg), 0 0 0 4px color-mix(in oklab, var(--accent) 34%, transparent);

  /* ----------------------------------------------------------------- motion */

  /* Names, values and curves copied from app/src/renderer/app.css, whose own
     comment says the point is to give the reduced-motion rule a single set of
     values to neutralise. This file is the surface that never got them: it had
     three hardcoded durations and no curve at all. */
  --motion-fast: 120ms;
  --motion: 200ms;
  --motion-slow: 380ms;
  --ease: cubic-bezier(.2, .8, .3, 1);
  --ease-in: cubic-bezier(.4, 0, 1, 1);
  --ease-out: cubic-bezier(0, 0, .2, 1);

  /* ----------------------------------------------------------------- layers */

  /* Was 0, 1, 2, 20 and 30 scattered through the file. The diagram tooltip sat
     at 20 and the sticky nav at 30 — and tooltips open upward, so a cell near
     the top of the viewport opened its tip behind a translucent blurred bar.
     Popovers win. */
  --z-under: -1;
  --z-base: 0;
  --z-raised: 1;
  --z-sticky: 30;
  --z-pop: 40;

  /* ------------------------------------------------------------------ grain */

  /*
   * About 230 bytes and zero requests, which is the whole reason it is inline:
   * the docroot's .htaccess denies anything it does not name, so a new asset
   * file is a new rule in a security-relevant file.
   *
   * It is here because it stops large soft gradients from banding, and banding
   * is what gives a CSS glow away. Applied to the hero and the closing band
   * only — a fixed full-viewport turbulence overlay is measurably slow on
   * mid-range Android and sits over body copy for no benefit.
   */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
}

/* =========================================================== the base layer */

*, *::before, *::after { box-sizing: border-box; }

html {
  /* Kept for the no-JS path. inc/footer.php sets scroll-behavior: auto when the
     momentum script starts, because JS then owns the easing for the wheel and
     for anchors both — two curves running at once is worse than either. */
  scroll-behavior: smooth;
  /*
   * CLIP, NOT HIDDEN, AND THE DIFFERENCE MATTERS HERE.
   *
   * The hero's ambient light is an absolutely positioned pseudo-element inset by
   * -25% on each side, so it overflowed the viewport horizontally and the page
   * could grow a horizontal scrollbar — which on a trackpad reads as the page
   * fighting the gesture.
   *
   * overflow: hidden would fix it and break the sticky nav: hidden creates a
   * scroll container, and a sticky element sticks to its nearest scrolling
   * ancestor rather than the viewport. clip creates no scroll container, so the
   * nav keeps working.
   */
  overflow-x: clip;
  /*
   * There was no scroll-margin anywhere in this file, and the page has a sticky
   * nav and seven in-page anchors. Every one of them landed with its own kicker
   * and heading hidden behind the bar — including all five nav links.
   */
  scroll-padding-top: calc(var(--nav-h) + var(--s5));
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: var(--w-body) var(--t-base)/var(--lh-body) var(--font);
  letter-spacing: var(--tr-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /*
   * ss01 is Open Digits — it opens the 4, 6 and 9, and it is why the prices and
   * the stat figures look considered. cv10 gives the capital G a spur.
   *
   * cv05 and cv11 were here and are deliberately gone. cv11 is Inter's
   * SINGLE-STOREY a, the geometric letterform — and cursor.com, x.ai and Linear
   * all run the default double-storey one, so that token was quietly pushing
   * this page away from the register it was trying to reach. cv05 is
   * lower-case-l-with-a-tail, a disambiguation feature meant for code and dense
   * UI, which at 72px reads as a terminal tic.
   */
  font-feature-settings: "ss01" 1, "cv10" 1;
  font-optical-sizing: auto;
}

h1, h2, h3, h4 {
  margin: 0 0 var(--s3);
  font-family: var(--font-display);
  font-weight: var(--w-bold);
  line-height: var(--lh-head);
  letter-spacing: var(--tr-h2);
  text-wrap: balance;
  text-transform: capitalize;
}

h1 {
  font-size: var(--t-h1);
  font-weight: 700;
  line-height: var(--lh-tight);
  letter-spacing: var(--tr-display);
}
h2 { font-size: var(--t-h2); font-weight: 700; }
h3 { font-size: var(--t-h3); letter-spacing: var(--tr-h3); }

/* Display figures in the proof board follow the same title case. */
.strip-cell b,
.strip-hook-title {
  text-transform: capitalize;
}

p { margin: 0 0 var(--s4); text-wrap: pretty; }

a { color: var(--accent); text-decoration: none; }
a:hover {
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
}

/*
 * The same guard as on html, because the one up there is a bet on how the root
 * element's overflow propagates to the viewport — and that bet was lost once
 * already. body is not the scroll container, so clipping here clips body's own
 * children, and clip (unlike hidden) creates no scroll container, so the sticky
 * nav still sticks to the viewport.
 *
 * NEITHER OF THESE SHOULD EVER BE LOAD-BEARING. If something starts overflowing
 * again, fix the element: website/test/overflow.test.js measures it in real
 * Chromium and names the element and the number of pixels.
 */
body { overflow-x: clip; }

/*
 * No page-wide ambient fog. Fixed multi-lobe radials behind every section made
 * the ad landing look stained (violet + warm lobes through white bands). Section
 * grounds are solid now; depth comes from hairlines and card elevation instead.
 */

.mono { font-family: var(--mono); font-feature-settings: normal; letter-spacing: 0; }

/* Small text wants more space than the body, not less. */
.scale, .vs-tag, .chip, .shot-sub, .shot-server, .price-sub, .copy,
.foot-cols h3, .link-pill, .announce-tag, .plan-tag { letter-spacing: var(--tr-micro); }

/* Figures that are meant to be compared against each other, and nothing else.
   Tabular figures in running prose look like a spreadsheet. */
.price, .strip b, .clockbar-head b, .abil-total b, .scale, .vs-count {
  font-variant-numeric: tabular-nums;
}

/* Belt and braces with scroll-padding-top above. */
[id] { scroll-margin-top: calc(var(--nav-h) + var(--s5)); }

/* ------------------------------------------------------------- preview bar */

/*
 * Only on /home/, the unlaunched copy of this page.
 *
 * It exists because a screenshot of a preview and a screenshot of the live site
 * are otherwise the same picture, and somebody will eventually send one to a
 * customer. Loud enough to be impossible to miss, small enough not to get in
 * the way of reviewing the page under it.
 */
.preview-bar {
  padding: 9px 20px;
  background: #2b2440;
  color: #d8d3ff;
  text-align: center;
  font-size: var(--t-xs); font-weight: 500;
}
.preview-bar a {
  display: inline-block; padding-block: 4px;
  color: #fff; text-decoration: underline;
}

/* --------------------------------------------------------- announcement */

.announce {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 10px 20px;
  background: var(--bg-2);
  border-bottom: 1px solid var(--border);
  color: var(--text-2); font-size: var(--t-xs);
}
.announce:hover { text-decoration: none; background: var(--surface-3); }
.announce-tag {
  padding: 2px 9px; border-radius: var(--r-full);
  background: var(--accent); color: #fff;
  font-size: var(--t-micro); font-weight: 650; letter-spacing: .02em;
}
.announce-arrow { color: var(--accent); }

/* ------------------------------------------------------------------- nav */

/*
 * OPAQUE, AND THERE IS NO BACKDROP FILTER HERE ANY MORE.
 *
 * It was 86% translucent with backdrop-filter: saturate(1.6) blur(12px), which
 * is the single most expensive thing a sticky element can do on a long page: the
 * blur source is whatever is underneath, so every frame of every scroll means a
 * full-width recomposite plus a 12px gaussian — and underneath it, at the time,
 * were dozens of elements animating on scroll. That combination is what made the
 * page stutter.
 *
 * A translucent bar without the blur is worse than either option, because the
 * content behind it shows through sharp. So: opaque. It costs nothing per frame,
 * and cursor.com's nav is effectively opaque for the same reason.
 */
.nav {
  position: sticky; top: 0; z-index: var(--z-sticky);
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  box-shadow: var(--shadow-nav);
}
.nav-inner {
  max-width: var(--wrap); margin: 0 auto; padding: var(--s3) var(--gutter);
  display: flex; align-items: center; gap: 32px;
}
/*
 * THE SUPPLIED WORDMARK, NOT A MARK PLUS A TYPED NAME.
 *
 * This was <img src="mark-64.png"> followed by <span>Multiagentry</span>, which
 * drew the brand name twice — once as it is drawn in the logo, and once in
 * whatever the site's own heading face happened to be. The asset already
 * contains both the knot and the word, set as the logo is meant to be set, so
 * the only correct amount of markup here is one image.
 *
 * Sized by height with width auto: logo-320.png is 320x62, and pinning the
 * height is what keeps it on the nav's baseline whatever the source resolution
 * becomes later.
 */
.brand { display: flex; align-items: center; padding-block: 4px; }
.brand img { display: block; height: 26px; width: auto; }
.brand:hover { text-decoration: none; opacity: .82; }
.brand:focus-visible { outline: none; box-shadow: var(--ring); border-radius: var(--r-sm); }

.nav-links { display: flex; gap: var(--s5); font-size: var(--t-sm); align-items: center; }
/*
 * padding-block, not line-height, so the row keeps its height while the hit area
 * clears WCAG 2.2's 24px minimum. Measured at 390px these were 22px tall — which
 * looks fine and misses on a thumb. Same for the footer links below.
 */
.nav-links a { color: var(--text-2); padding-block: 6px; }
.nav-links a:hover { color: var(--text); text-decoration: none; }

/* ---------------------------------------------------- the nav dropdown */

.nav-group { position: relative; }
.nav-group-btn {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 6px 0;
  border: 0; background: none;
  color: var(--text-2);
  font: inherit; font-size: var(--t-sm);
  cursor: pointer;
}
.nav-group-btn:hover { color: var(--text); }
.nav-group-btn svg {
  width: 12px; height: 12px;
  transition: transform var(--motion-fast) var(--ease-out);
}
.nav-group.open .nav-group-btn { color: var(--text); }
.nav-group.open .nav-group-btn svg { transform: rotate(180deg); }

.nav-menu {
  display: none;
  position: absolute; left: 0; top: calc(100% + 10px);
  min-width: 232px;
  padding: 6px;
  border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface);
  box-shadow: var(--shadow-md);
  z-index: var(--z-pop);
}
.nav-group.open .nav-menu { display: block; }
.nav-menu a {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--s4);
  padding: 9px 10px; border-radius: var(--r-xs);
  color: var(--text); font-size: var(--t-sm); text-decoration: none;
}
.nav-menu a:hover { background: var(--surface-2); }
/* The screen count. Tabular, so the two numbers line up under each other. */
.nav-menu a i {
  flex: none;
  color: var(--muted); font-size: var(--t-micro); font-style: normal;
  font-variant-numeric: tabular-nums;
}

.nav-cta { margin-left: auto; display: flex; gap: 8px; }

/*
 * The mobile menu button. Hidden here and revealed at the 980px breakpoint, so
 * the desktop nav is what exists by default and the phone layout is the
 * exception — not the other way round, which is how a burger ends up briefly
 * visible on a desktop during load.
 */
.nav-burger {
  display: none;
  order: 3;                       /* after the CTA, nearest the right edge */
  width: 44px; height: 44px;      /* a real thumb target, not a 24px icon */
  margin-left: var(--s2);
  padding: 0;
  border: 1px solid var(--border); border-radius: var(--r-xs);
  background: var(--surface);
  cursor: pointer;
  flex-direction: column; align-items: center; justify-content: center; gap: 4px;
}
.nav-burger span {
  display: block; width: 18px; height: 2px; border-radius: 2px;
  background: var(--text);
  transition: transform var(--motion-fast) var(--ease-out),
              opacity var(--motion-fast) var(--ease-out);
}
/* Into a cross while open. The middle bar goes rather than rotating with the
   others, which is what stops it showing as a thick stub in the centre. */
.nav-open .nav-burger span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.nav-open .nav-burger span:nth-child(2) { opacity: 0; }
.nav-open .nav-burger span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* --------------------------------------------------------------- buttons */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 12px 22px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--text);
  /* line-height is explicit because the font shorthand this replaced set it to
     normal, and without it a button inherits the body's 1.6 and grows. */
  font-family: var(--font); font-size: var(--t-sm); font-weight: var(--w-semi);
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
  transition: background 140ms, border-color 140ms, transform 120ms, box-shadow 140ms;
}
.btn:hover { background: var(--surface-3); text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: none; box-shadow: var(--ring); }

.btn--primary {
  background: var(--accent); border-color: var(--accent); color: var(--on-accent);
  box-shadow: 0 1px 2px rgb(90 79 232 / .3), 0 10px 24px -10px rgb(90 79 232 / .6);
}
.btn--primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
/* Composed, not replaced: the base rule's focus ring alone would have flattened
   the button's own glow at the moment it gained focus. */
.btn--primary:focus-visible {
  box-shadow: var(--ring), 0 10px 24px -10px rgb(90 79 232 / .6);
}

.btn--quiet { border-color: transparent; background: transparent; color: var(--text-2); }
.btn--quiet:hover { background: var(--surface-3); color: var(--text); }

/*
 * A real WhatsApp button, and NOT in #25D366.
 *
 * White on WhatsApp's brand green is about 2:1, which fails AA by a distance,
 * and this one carries a label rather than just a mark. #0e7a6e is the same
 * green darkened until white on it reaches about 5.3:1: it still reads as
 * WhatsApp beside the glyph, and the words can actually be read.
 */
.btn--wa {
  background: #0e7a6e; border-color: #0e7a6e; color: #fff;
  box-shadow: 0 1px 2px rgb(14 122 110 / .3), 0 10px 24px -10px rgb(14 122 110 / .5);
}
.btn--wa:hover { background: #0c6b60; border-color: #0c6b60; }
.btn--wa:focus-visible {
  box-shadow: var(--ring), 0 10px 24px -10px rgb(14 122 110 / .5);
}

/* Quiet WhatsApp secondary — keeps brand green without fighting the primary. */
.btn--wa-outline {
  background: var(--surface);
  border-color: color-mix(in oklab, #0e7a6e 42%, var(--border-strong));
  color: #0c6b60;
  box-shadow: var(--shadow-xs);
  gap: 8px;
}
.btn--wa-outline:hover {
  background: color-mix(in oklab, #0e7a6e 8%, var(--surface));
  border-color: #0e7a6e;
  color: #0a5c52;
  text-decoration: none;
}
.btn--wa-outline:focus-visible {
  box-shadow: var(--ring);
}

.btn--sm { padding: 8px 15px; font-size: var(--t-xs); }
.btn--lg { padding: 15px 28px; font-size: var(--t-md); }

/* ------------------------------------------------------- sections, grounds */

/*
 * The section element IS the container — there is no separate wrapper class.
 * Three beats of vertical rhythm rather than one flat 104px.
 */
/*
 * EVERY SECTION IS FULL BLEED, and the width cap is done with padding rather
 * than with max-width. That is the difference between a background that reaches
 * the edge of the screen and one that stops in a 1140px box.
 *
 * It used to be max-width plus a handful of opt-in classes that undid it, so
 * every ground class added afterwards had to remember to join that list. .g-deep
 * did not, and the section painted a warm band 1140px wide with white gutters
 * either side of it.
 *
 * max() keeps the gutter on a narrow screen and becomes the centring margin on a
 * wide one, and unlike max-width it cannot care whether the section is a block
 * or a grid.
 */
section {
  max-width: none;
  padding-block: var(--sec-y);
  padding-inline: max(var(--gutter), (100% - var(--wrap)) / 2);
  background: var(--ground, transparent);
}
.sec-tight { padding-block: var(--sec-y-sm); }
.sec-loud { padding-block: var(--sec-y-lg); }

/*
 * SECTION GROUNDS — solid, one step, hairline. No feathered fades.
 *
 * Soft transparent→colour→transparent bands stacked into muddy seams and made
 * cards look like they floated over a stain. Premium landings alternate white
 * and one soft paper with a clean edge.
 */
.g-paper { --ground: var(--bg); }
.g-warm, .alt {
  --ground: var(--bg-2);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.g-deep {
  --ground: var(--bg-2);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

/* Closing / pricing punctuation: a quiet iris wash, not a lilac fog. */
.g-tint {
  --ground: linear-gradient(180deg, #f5f4fc 0%, var(--bg) 100%);
  border-top: 1px solid color-mix(in oklab, var(--accent) 12%, var(--border));
  border-bottom: 1px solid color-mix(in oklab, var(--accent) 12%, var(--border));
}

.g-wash {
  --ground: var(--bg-2);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

/* Adjacent soft sections: deepen the second; drop the double hairline. */
.alt + .alt,
.g-deep + .g-deep,
.g-warm + .g-warm,
.alt + .g-deep,
.g-deep + .alt {
  border-top: 0;
  --ground: var(--bg-3);
}

/* Grain only on the hero, and barely there — noise hides banding on soft light,
   but at ad-landing size it reads as dirt. */
.g-grain { position: relative; isolation: isolate; }
.g-grain::after {
  content: "";
  position: absolute; inset: 0; z-index: var(--z-under);
  background-image: var(--grain);
  background-size: 180px 180px;
  opacity: .018;
  pointer-events: none;
}

/* ------------------------------------------------------------------- hero */

/*
 * FULL BLEED, with the copy still on the grid.
 *
 * The ambient light is a child of this element, so when the hero was capped at
 * --wrap the light stopped 150px short of each edge on a wide screen and the
 * page had two pale gutters either side of a lit middle. Padding rather than a
 * width cap: the background reaches the viewport, the text does not.
 */
.hero {
  position: relative;
  isolation: isolate;
  overflow: hidden; /* keep hero light inside the hero — no fog leaking into the gap */
  padding-block: clamp(40px, 1.5rem + 3.4vw, 80px) var(--s5);
  text-align: center;
}
.hero > * { max-width: var(--wrap); margin-inline: auto; }

/*
 * THE AMBIENT LIGHT.
 *
 * The old version was a single centred radial with filter: blur(44px) over it.
 * A 44px blur on a box this size forces a compositing layer and re-rasterises
 * on every resize, and it still read as a lit rectangle with an edge.
 *
 * Three overlapping soft-stop radials do it better for no filter cost. What
 * actually makes the difference, in order:
 *
 *   1. ASYMMETRY. One centred lobe is what makes a CSS glow look fake. There
 *      are two violet lobes here, off-centre and different sizes.
 *   2. A MASK FALLOFF, so the light dies into the paper instead of ending.
 *   3. A WARM COUNTERLIGHT on the other side, so it is not one flat violet fog.
 *   4. Grain, above, so none of it bands.
 *
 * Nothing here animates. A slowly drifting gradient is the most reliable way to
 * make a light hero look cheap, and it costs a permanent compositing layer for
 * something nobody notices after four seconds.
 */
/*
 * IT USED TO BE INSET -25% HORIZONTALLY, AND THAT MADE THE WHOLE SITE SCROLL
 * SIDEWAYS.
 *
 * A quarter of the hero's width past each edge is a quarter of the viewport of
 * content nobody asked for. Measured in Chromium: 86px of horizontal scroll at
 * 360px wide, 252px at 1024px, 143px at 1440px — the number moves with the
 * viewport because the hero is fluid until it reaches --wrap.
 *
 * overflow-x: clip on html did NOT stop it, and that is the part worth
 * remembering: overflow on the root element propagates to the viewport, and
 * relying on that to hide a layout mistake is a bet on one browser's reading of
 * a subtle rule. The fix is to not overflow. The box stops at the hero's own
 * edges now and the gradients are scaled to compensate — it lost a third of its
 * width, so each lobe gains half again and the two off-centre ones are moved to
 * the same absolute positions they used to occupy. The light is unchanged.
 *
 * It still extends VERTICALLY on purpose, so the glow carries down behind the
 * product shot. Vertical overflow costs nothing; the page scrolls that way.
 */
.hero::before {
  content: "";
  position: absolute;
  inset: -12% 0 20%;
  z-index: var(--z-under);
  pointer-events: none;
  background:
    radial-gradient(70% 48% at 50% 0%,
      color-mix(in oklab, var(--accent) 12%, transparent) 0%,
      color-mix(in oklab, var(--accent) 3%, transparent) 42%,
      transparent 72%);
  -webkit-mask-image: radial-gradient(100% 70% at 50% 8%, #000 38%, transparent 100%);
  mask-image: radial-gradient(100% 70% at 50% 8%, #000 38%, transparent 100%);
}

/*
 * The eyebrow. cursor.com has nothing here, but "Cursor" is a word its readers
 * already know and "Multiagentry" is not — so the first question a stranger has
 * is what KIND of thing this is, and the h1 answers a different one.
 */
.eyebrow {
  display: inline-flex; align-items: center; gap: var(--s2);
  margin: 0 auto var(--s5);
  padding: 6px 14px 6px 11px;
  border: 1px solid var(--border);
  border-radius: var(--r-full);
  background: color-mix(in oklab, var(--surface) 78%, transparent);
  box-shadow: var(--shadow-xs), var(--edge);
  color: var(--text-2);
  font-size: var(--t-xs); font-weight: var(--w-med);
  letter-spacing: var(--tr-micro);
}
.eyebrow i {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 16%, transparent);
}

/*
 * The h1's size, family and tracking come from the base layer. What is here is
 * the measure and the muted third line.
 *
 * IT USED TO SET max-width: 17ch AND CARRY AN EXPLICIT <br>, and the two fought:
 * 17ch at the clamp maximum is about 626px while the headline is about 1040px,
 * so it wrapped before reaching the break and the non-breaking spaces pushed
 * "live site." onto a line of its own. Three or four lines, none of them chosen.
 * The markup owns the breaks now, so the measure only has to be wide enough not
 * to introduce its own.
 */
/*
 * 30ch, and text-wrap is OFF here.
 *
 * The longest of the three lines is "It never sees the password." at 27
 * characters, and 24ch was close enough to it that the line could wrap at some
 * widths and not others — which is the same class of bug as the 17ch this
 * replaced, just less often.
 *
 * text-wrap: balance comes from the shared heading rule and has to be undone
 * for this one element: balancing re-breaks the text between forced breaks, so
 * it can turn a deliberate three-line headline into four. Every other heading
 * on the page keeps it, because every other heading wraps on its own.
 */
h1 {
  max-width: 30ch; margin-inline: auto;
  text-wrap: normal;
}
h1 span { display: block; color: var(--muted); }

.lede {
  max-width: 58ch;
  margin: var(--s5) auto var(--s7);
  color: var(--text-2);
  font-size: var(--t-lg);
  line-height: var(--lh-snug);
}

.cta { display: flex; gap: var(--s3); justify-content: center; flex-wrap: wrap; }
.fineprint { margin: var(--s5) 0 0; color: var(--muted); font-size: var(--t-sm); }

/* ------------------------------------------------------- the product shot */

/*
 * A drawn app window rather than a screenshot. A PNG goes stale the first time
 * a screen changes and nobody notices; this is built from the app's own tokens,
 * so it drifts only when they do.
 */
/*
 * WIDER THAN THE COPY, and flush against the hero above it. Both are cursor.com's
 * shape: nothing sits between the buttons and the product, and the product is
 * visibly wider than the sentence that introduced it.
 */
.shot-stage {
  position: relative;
  max-width: var(--wrap-wide);
  margin: 0 auto;
  padding: var(--s4) var(--gutter) var(--s8);
}
/* No floating glow above the demo — it sat in empty white and looked broken. */
.shot-glow { display: none; }
/*
 * The screenshot frame.
 *
 * REAL SCREENSHOTS, prepared by website/ss/prepare-shots.ps1 — which replaces
 * the pre-rename mark and, more importantly, every real client name and URL
 * with dummies. The raw shots in website/ss are never deployed.
 */
.shot {
  position: relative; z-index: 1;
  margin: 0;
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  background: var(--surface);
  /* The inset white top edge is doing more work here than the glow behind it. */
  box-shadow: var(--shadow-lg), var(--edge);
  overflow: hidden;
}
.shot picture { display: block; }
.shot img { display: block; width: 100%; height: auto; }

/* 16:9 YouTube embed in the product slot under the hero. */
.shot--video { background: #0b0d10; }
.shot-video {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #0b0d10;
}
.shot-video iframe {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0;
  display: block;
}

/* Used inside a section that already has its own spacing and needs no glow. */
.shot--plain { box-shadow: var(--shadow); border-radius: var(--r-lg); }

.shot-cap {
  margin: 18px auto 0; max-width: 58ch;
  text-align: center; color: var(--muted); font-size: var(--t-sm);
}

/* ------------------------------------------------ floating demo + modal */

.demo-fab {
  position: fixed;
  z-index: 54;
  left: max(16px, env(safe-area-inset-left));
  right: auto;
  bottom: max(16px, env(safe-area-inset-bottom));
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px 12px 14px;
  border: 1px solid color-mix(in oklab, #fff 18%, transparent);
  border-radius: 999px;
  background: #121318;
  color: #fff;
  font: inherit;
  font-size: var(--t-sm);
  font-weight: 620;
  letter-spacing: 0.01em;
  cursor: pointer;
  box-shadow: 0 14px 32px -16px rgb(0 0 0 / .45);
}
.demo-fab:hover { background: color-mix(in oklab, var(--text) 88%, #fff); }
.demo-fab:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
.demo-fab svg { flex-shrink: 0; }

.demo-modal {
  padding: 0;
  border: 0;
  background: transparent;
  max-width: min(960px, calc(100vw - 32px));
  width: 100%;
}
.demo-modal::backdrop {
  background: color-mix(in oklab, #0b0d10 72%, transparent);
  backdrop-filter: blur(4px);
}
.demo-modal__panel {
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  background: var(--surface);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.demo-modal__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--border);
}
.demo-modal__head h2 {
  margin: 0;
  font-size: var(--t-base);
  font-weight: 640;
}
.demo-modal__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px; height: 36px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  color: var(--text);
  cursor: pointer;
}
.demo-modal__close:hover { background: var(--surface); }
.demo-modal__close:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.demo-modal__frame {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #0b0d10;
}
.demo-modal__frame iframe {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0;
  display: block;
}

@media (max-width: 520px) {
  .demo-fab span { display: none; }
  .demo-fab { padding: 14px; border-radius: 50%; }
}
@media (max-width: 720px) {
  .demo-fab {
    bottom: max(84px, calc(72px + env(safe-area-inset-bottom)));
  }
}

body:has(.demo-modal[open]) .demo-fab { visibility: hidden; pointer-events: none; }
/* Keep demo clear of the open chat panel on narrow screens. */
body:has(.magy-chat.is-open) .demo-fab {
  opacity: 0.35;
  pointer-events: none;
}

.shot-bar {
  display: flex; align-items: center; gap: 7px;
  padding: 12px 18px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
}
.shot-bar i { width: 10px; height: 10px; border-radius: 50%; background: var(--border-strong); }
.shot-bar span { margin-left: 12px; color: var(--muted); font-size: var(--t-micro); font-weight: 560; }

.shot-body { display: grid; grid-template-columns: 216px 1fr; min-height: 340px; }

.shot-side {
  padding: 18px 14px; background: var(--surface-2);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
}
.shot-brand { display: flex; align-items: center; gap: 8px; font-size: var(--t-xs); font-weight: 640; }
.shot-sub { display: block; margin: 1px 0 16px 25px; color: var(--muted); font-size: var(--t-micro); }
.shot-side ul { list-style: none; margin: 0; padding: 0; }
.shot-side li {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 10px; margin-bottom: 1px; border-radius: var(--r-sm);
  color: var(--text-2); font-size: var(--t-xs);
}
.shot-side li i { width: 14px; height: 14px; border-radius: var(--r-xs); background: var(--border-strong); }
.shot-side li.on { background: var(--accent-soft); color: var(--accent); font-weight: 620; }
.shot-side li.on i { background: var(--accent); }
.shot-server {
  margin-top: auto; padding: 9px 10px;
  display: flex; align-items: center; gap: 8px;
  color: var(--muted); font-size: var(--t-micro);
}

.shot-main { padding: 20px 22px; }
.shot-head { display: flex; align-items: center; gap: 9px; margin-bottom: 15px; }
.shot-head b { font-size: var(--t-md); margin-right: 4px; }

.chip {
  padding: 3px 10px; border-radius: var(--r-full);
  background: var(--surface-3); color: var(--muted);
  font-size: var(--t-micro); font-weight: 620; white-space: nowrap;
}
.chip--ok { background: var(--ok-bg); color: var(--ok); }

.shot-row {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 15px; margin-bottom: 9px;
  border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface);
}
.shot-row--muted { background: var(--surface-2); }
.dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.dot--ok { background: var(--ok); box-shadow: 0 0 0 3px var(--ok-bg); }
.dot--idle { background: var(--border-strong); box-shadow: 0 0 0 3px var(--surface-3); }
.shot-col { flex: 1; min-width: 0; }
.shot-col b { display: block; font-size: var(--t-xs); }
.shot-col span {
  display: block; color: var(--muted); font-size: var(--t-micro);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ---------------------------------------------------------------- numbers */

.strip {
  position: relative;
  isolation: isolate;
  padding: clamp(36px, 5vw, 64px) max(var(--gutter), (100% - var(--wrap-wide)) / 2);
  --ground: #14151a;
  background:
    radial-gradient(90% 70% at 12% 0%, color-mix(in oklab, var(--accent) 28%, transparent), transparent 55%),
    radial-gradient(70% 60% at 88% 100%, color-mix(in oklab, #3d3f4a 55%, transparent), transparent 50%),
    linear-gradient(180deg, #1a1b21 0%, #121318 100%);
  border-top: 1px solid #0c0d10;
  border-bottom: 1px solid #0c0d10;
  overflow: hidden;
}
.strip-board {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(220px, 0.95fr) minmax(0, 1.7fr);
  max-width: var(--wrap-wide);
  margin-inline: auto;
  border-radius: clamp(18px, 2.2vw, 28px);
  overflow: hidden;
  box-shadow:
    0 1px 0 rgb(255 255 255 / .06) inset,
    0 24px 48px -20px rgb(0 0 0 / .55);
}
.strip-hook {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 28px;
  padding: clamp(28px, 3.5vw, 40px);
  background:
    linear-gradient(160deg, color-mix(in oklab, var(--accent) 88%, #fff) 0%, var(--accent) 42%, var(--accent-ink) 100%);
  color: #fff;
}
.strip-hook-title {
  margin: 0;
  max-width: 12ch;
  font-size: clamp(1.55rem, 1.2rem + 1.4vw, 2.15rem);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.035em;
  color: #fff;
  text-wrap: balance;
}
.strip-hook-cta {
  align-self: flex-start;
  background: #fff;
  border-color: #fff;
  color: var(--accent-ink);
  font-weight: 650;
  box-shadow: 0 8px 18px -10px rgb(0 0 0 / .35);
}
.strip-hook-cta:hover {
  background: #f4f4f7;
  border-color: #f4f4f7;
  color: var(--accent-ink);
  text-decoration: none;
}
.strip-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  background: #f7f7f8;
}
.strip-cell {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: clamp(22px, 3vw, 32px) clamp(20px, 2.6vw, 30px);
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  transition: background var(--motion) var(--ease);
}
.strip-cell:nth-child(2n) { border-right: 0; }
.strip-cell:nth-child(n + 3) { border-bottom: 0; }
.strip-cell b {
  display: block;
  font-size: clamp(1.25rem, 1.05rem + 0.7vw, 1.65rem);
  font-weight: 750;
  letter-spacing: -0.035em;
  line-height: 1.15;
  color: var(--accent);
}
.strip-cell span {
  color: var(--text-2);
  font-size: var(--t-sm);
  line-height: var(--lh-body);
  max-width: 28ch;
}
@media (hover: hover) and (pointer: fine) {
  .strip-cell:hover {
    background: color-mix(in oklab, var(--accent-wash) 55%, #fff);
  }
  .strip-hook-cta {
    transition: transform var(--motion) var(--ease), background var(--motion) var(--ease);
  }
  .strip-hook-cta:hover { transform: translateY(-1px); }
}
@media (prefers-reduced-motion: reduce) {
  .strip-cell,
  .strip-hook-cta { transition: none; }
  .strip-hook-cta:hover { transform: none; }
}

/* --------------------------------------------------------------- sections */

/*
 * The kicker, the nav and the stat figures take the display face too. These are
 * the page's labels rather than its prose, and a label set in the body face
 * beside a heading set in the display one is where a two-face system starts to
 * look accidental.
 */
.kicker {
  margin-bottom: .8em;
  font-family: var(--font-display);
  color: var(--accent); font-size: var(--t-micro); font-weight: 700;
  letter-spacing: var(--tr-caps); text-transform: uppercase;
}
.nav-links, .nav-cta .btn, .strip b, .price, .bento-step,
.foot-cols h3, .vs-tag, .plan h3, .abil-total b {
  font-family: var(--font-display);
}
/* h2 size, weight and tracking are all in the base layer now. */
/* The one intermediate heading size, between --t-h3 and --t-h2, where no token
   sits. Used where an h3 has to carry a section on its own. */
.h2-ish { font-size: clamp(1.375rem, 1.1rem + 1.1vw, 1.875rem); }

.section-head { margin-bottom: var(--s7); }
/* A sub-head inside a section that already has one. */
.refusals-head { margin-top: var(--s9); margin-bottom: var(--s5); }
.section-head--center { text-align: center; max-width: 62ch; margin-inline: auto; }
.section-lede { color: var(--text-2); margin: 0; }
.section-head--center .section-lede { margin-inline: auto; max-width: 56ch; }

/*
 * FULL-BLEED GROUND, CONTENT STILL ON THE GRID.
 *
 * This used to re-centre each child with .alt > * { max-width: var(--wrap) },
 * and that had a bug nobody would ever have gone looking for. .alt sets
 * max-width: none at specificity 0,1,0 and beats section's 0,0,1 — fine — but
 * .feature makes the SECTION ITSELF the grid, so capping each child capped each
 * COLUMN at 1140px rather than the pair. On a 1920px screen the registration
 * section's text column was about 900px wide, roughly 140 characters a line,
 * while every other section on the page was 1092px in total.
 *
 * Padding instead of a child cap: one rule, and it cannot care whether the
 * section is a block or a grid.
 */
/* No rule: the ground fades to nothing at both ends, so a hairline would be a
   line floating in the middle of the fade. */

/* ------------------------------------------------------------------ duo */

.duo {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--s5);
  margin-bottom: var(--s5);
}
/* The setup section is headed "Three steps" and contained two tiles. */
.trio { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s5); }
.tile {
  border: 1px solid var(--border); border-radius: var(--r-xl);
  background: var(--bg-2);
  overflow: hidden;
  display: flex; flex-direction: column;
}
.tile-text { padding: 30px 30px 4px; }
.tile-text p { color: var(--text-2); font-size: var(--t-md); margin: 0; }
.tile-visual { padding: 26px 30px 30px; margin-top: auto; }

.mini {
  border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface); box-shadow: var(--shadow-sm);
  overflow: hidden; font-size: var(--t-xs);
}
.mini-row {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 11px 14px; border-bottom: 1px solid var(--border);
}
.mini-row b { font-weight: 600; }
.mini-row span { color: var(--muted); }
.mini-foot {
  padding: 10px 14px; background: var(--surface-2);
  color: var(--ok); font-size: var(--t-micro); font-weight: 600;
  display: flex; align-items: center; gap: 8px;
}
.mini-toggle {
  display: flex; align-items: center; justify-content: space-between;
  padding: 11px 14px; border-bottom: 1px solid var(--border);
}
.mini-toggle:last-child { border-bottom: 0; }
.mini-toggle b { font-weight: 550; color: var(--text-2); }
.mini-toggle i {
  width: 32px; height: 18px; border-radius: var(--r-full);
  background: var(--surface-3); border: 1px solid var(--border-strong);
  position: relative; flex: none;
}
.mini-toggle i::after {
  content: ""; position: absolute; top: 2px; left: 2px;
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--border-strong);
}
.mini-toggle.on b { color: var(--text); font-weight: 620; }
.mini-toggle.on i { background: var(--accent); border-color: var(--accent); }
.mini-toggle.on i::after { left: 16px; background: #fff; }

/* -------------------------------------------------------------- features */

.feature {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 60px; align-items: center;
  padding-top: 40px;
}
/* The padding it used to re-declare here is section's own now. */
.feature--rev .feature-text { order: 2; }
.feature p { color: var(--text-2); }

.panel-mock {
  border: 1px solid var(--border); border-radius: var(--r-lg);
  background: var(--surface); box-shadow: var(--shadow);
  overflow: hidden; font-size: var(--t-xs);
}
.mock-head {
  padding: 13px 16px; background: var(--surface-2);
  border-bottom: 1px solid var(--border); font-weight: 640; font-size: var(--t-xs);
}
.mock-line { padding: 12px 16px; border-bottom: 1px solid var(--border); color: var(--text-2); }
.mock-line em { font-style: normal; font-family: var(--mono); font-size: var(--t-micro); color: var(--text); }
.mock-line s { color: var(--muted); }
.mock-line .tick { color: var(--ok); font-weight: 700; margin-right: 6px; }
.mock-line--mark { background: var(--accent-wash); color: var(--accent); font-weight: 620; }
.mock-line--dim { color: var(--muted); }
.mock-line .cross { color: var(--agent-codex); font-weight: 700; margin-right: 6px; }
.mock-line--bad { color: var(--text); }
.mock-foot { padding: 13px 16px; background: var(--surface-2); color: var(--accent); font-weight: 620; }

.agents { display: grid; gap: 12px; }
.agent {
  display: flex; align-items: center; gap: 13px;
  padding: 17px 19px;
  border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface); box-shadow: var(--shadow-sm);
}
.agent i { width: 10px; height: 28px; border-radius: var(--r-full); flex: none; }
.agent b { font-size: var(--t-sm); }
.agent span { margin-left: auto; color: var(--ok); font-size: var(--t-micro); font-weight: 620; }
.agent--claude i { background: var(--agent-claude); }
.agent--cursor i { background: var(--agent-cursor); }
.agent--codex  i { background: var(--agent-codex); }

/* ------------------------------------------------------------------ grid */

.grid {
  display: grid; gap: 18px;
  grid-template-columns: repeat(auto-fit, minmax(292px, 1fr));
}
/*
 * FOUR CARDS GO 2 AND 2, NOT 3 AND 1.
 *
 * The base .grid is auto-fit minmax(292px, 1fr), which lands on three columns at
 * this wrap width. Six cards divide by three and look deliberate; four do not,
 * and the fourth sitting alone beneath three reads as something that failed to
 * load. Four across would fit at about 265px each, which is too narrow for four
 * lines of prose.
 *
 * Declared AFTER .grid rather than before it with !important: both selectors
 * have the same specificity, so source order decides, and an override that wins
 * on its own can still be beaten by a media query. The one with !important could
 * not, and held two columns all the way down to 390px.
 */
.grid--2 { grid-template-columns: repeat(2, 1fr); }

.grid article {
  padding: 28px;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
}
.grid h3 { font-weight: 650; margin-bottom: .45em; letter-spacing: -0.02em; }
.grid p { margin: 0; color: var(--text-2); font-size: var(--t-md); }

/* ----------------------------------------------------------------- plans */

/* The billing-cycle switch. Yearly is marked "soon" rather than being a tab
 * that shows an invented number: the yearly price has not been decided, and a
 * page that guesses one is a page somebody quotes back at you. */
.cycle {
  display: inline-flex; align-items: center; gap: 4px;
  margin-top: 26px; padding: 4px;
  border: 1px solid var(--border); border-radius: var(--r-full);
  background: var(--surface);
}
.cycle span {
  padding: 7px 18px; border-radius: var(--r-full);
  font-size: var(--t-xs); font-weight: 500;
}
.cycle-on { background: var(--invert-bg); color: var(--invert-fg); }
.cycle-off { color: var(--muted); }
.cycle-off em {
  font-style: normal; font-size: var(--t-micro); font-weight: 600;
  color: var(--accent); margin-left: 4px;
  text-transform: uppercase; letter-spacing: .04em;
}

/*
 * ONE PLAN, ONE PANEL, FULL WIDTH.
 *
 * It was three cards, and three cards is a comparison. A comparison is the right
 * shape when the reader has to choose, and the wrong one when there is nothing to
 * choose: three columns where two are dimmed asks somebody to work out what they
 * are giving up, and the answer is nothing.
 *
 * So: a price rail on the left that never moves, and the whole feature list open
 * beside it in three groups. Nothing is hidden behind a tier, so nothing is
 * hidden behind a hover or a toggle either.
 */
.plan-one {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: minmax(260px, 0.9fr) minmax(0, 1.5fr);
  grid-template-areas:
    "rail feats"
    "foot foot";
  max-width: var(--wrap);
  margin-inline: auto;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-xl);
  background: var(--surface);
  box-shadow: var(--shadow-md), var(--edge);
  overflow: hidden;
}

.plan-one::before {
  content: "";
  position: absolute; inset: 0 0 auto; height: 2px;
  z-index: var(--z-raised);
  background: linear-gradient(90deg,
    transparent 0%,
    color-mix(in oklab, var(--accent) 45%, transparent) 20%,
    color-mix(in oklab, var(--accent) 80%, transparent) 50%,
    color-mix(in oklab, var(--accent) 45%, transparent) 80%,
    transparent 100%);
}

.plan-rail {
  grid-area: rail;
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: clamp(24px, 2.8vw, 36px);
  border-right: 1px solid var(--border);
  background: var(--bg-2);
}
.plan-tag {
  display: inline-flex;
  align-self: flex-start;
  margin-bottom: var(--s4);
  padding: 5px 12px;
  border-radius: var(--r-full);
  border: 1px solid color-mix(in oklab, var(--accent) 22%, var(--border));
  background: var(--surface);
  color: var(--accent-ink);
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
}

.price {
  margin: 0; font-size: clamp(2.75rem, 1.6rem + 4vw, 3.75rem); font-weight: 620;
  letter-spacing: -0.05em; line-height: 1;
}
.price .cur { font-size: 1.75rem; font-weight: 550; vertical-align: .42em; margin-right: 2px; }
.price .per {
  font-size: var(--t-md); font-weight: 450; color: var(--muted);
  letter-spacing: -0.01em;
}
.price-sub {
  color: var(--text-2);
  font-size: var(--t-sm);
  line-height: var(--lh-body);
  margin: .55em 0 0;
  max-width: 34ch;
}

.price-ask {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 1.1rem + 1vw, 1.75rem);
  font-weight: 680;
  line-height: 1.2;
  letter-spacing: -0.03em;
  color: var(--text);
}
.price-ctas {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 0;
  padding-top: 0;
}
.price-ctas .btn { width: 100%; text-align: center; justify-content: center; }
.price-ctas--row {
  flex-direction: row;
  flex-wrap: wrap;
  gap: 10px;
}
.price-ctas--row .btn {
  width: auto;
  flex: 1 1 200px;
}

.docs-body .price-ctas {
  margin: var(--s6) 0 var(--s5);
  padding-top: 0;
}

.plan-nolimit {
  margin: var(--s5) 0 0;
  padding: 14px 16px;
  border: 1px solid color-mix(in oklab, var(--accent) 18%, var(--border));
  border-radius: var(--r);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
}
.plan-nolimit b {
  display: block;
  font-weight: 650;
  font-size: var(--t-md);
  letter-spacing: -0.015em;
  color: var(--accent-ink);
}
.plan-nolimit span {
  display: block;
  margin-top: 4px;
  font-size: var(--t-sm);
  color: var(--text-2);
  line-height: var(--lh-snug);
}

.plan-rail .btn { width: 100%; }
.plan-rail-note {
  margin: var(--s3) 0 0;
  text-align: center;
  font-size: var(--t-micro);
  color: var(--muted);
  letter-spacing: var(--tr-micro);
}

.plan-feats {
  grid-area: feats;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-content: start;
  align-self: stretch;
  gap: var(--s5) var(--s4);
  padding: clamp(24px, 2.8vw, 36px);
  background: var(--surface);
}

.plan-foot {
  grid-area: foot;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 18px clamp(24px, 2.8vw, 36px) 22px;
  border-top: 1px solid var(--border);
  background: var(--surface);
}
.plan-foot .price-ctas {
  width: 100%;
  max-width: 560px;
}
.plan-foot .plan-rail-note { margin-top: 2px; }

.plan-one .plan-group h3 {
  margin: 0 0 var(--s4);
  padding-bottom: var(--s3);
  border-bottom: 1px solid var(--border);
  font-family: var(--font-display);
  font-size: var(--t-micro);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .055em;
  line-height: 1.35;
  color: var(--accent-ink);
  position: relative;
}
.plan-one .plan-group h3::after {
  content: "";
  position: absolute; left: 0; bottom: -1px;
  width: 28px; height: 2px; border-radius: var(--r-full);
  background: var(--accent);
}

.plan-one .plan-group ul { list-style: none; margin: 0; padding: 0; }
.plan-one .plan-group li {
  position: relative;
  padding-left: 26px;
  margin-bottom: 12px;
  color: var(--text-2);
  font-size: var(--t-sm);
  line-height: var(--lh-snug);
  text-wrap: pretty;
}
.plan-one .plan-group li:last-child { margin-bottom: 0; }

.plan-one .plan-group li::before {
  content: "";
  position: absolute; left: 0; top: .2em;
  width: 16px; height: 16px; border-radius: var(--r-full);
  background: color-mix(in oklab, var(--accent) 12%, var(--surface));
  border: 1px solid color-mix(in oklab, var(--accent) 18%, var(--border));
}
.plan-one .plan-group li::after {
  content: "";
  position: absolute; left: 4.5px; top: .55em;
  width: 7px; height: 3.5px;
  border-left: 1.75px solid var(--accent-ink);
  border-bottom: 1.75px solid var(--accent-ink);
  border-bottom-left-radius: 1px;
  transform: rotate(-45deg);
}

.plans-note {
  max-width: 64ch; margin: var(--s6) auto 0;
  text-align: center; color: var(--muted); font-size: var(--t-sm);
}

/* A link in running prose is about 19px tall, well under the 44px a thumb wants.
   Vertical padding on an INLINE box extends the hit area without affecting the
   line box, so this moves nothing and makes every one of them 43px. Doing it
   with inline-block would have stopped long links wrapping mid-sentence. */
.docs-body p a, .docs-body li a, .docs-body td a, .docs-body dd a {
  padding-block: 12px;
}

/* ------------------------------------------------- standalone prose pages */

/* Contact, privacy, terms and refunds. One column, borrowing every type rule
   from .docs-body — only the container is new. */
/*
 * BOTH OF THESE ARE DOUBLED UP ON PURPOSE — .page.page--wide, not .page--wide.
 *
 * They were single class selectors, and both lost. `.page { max-width: 820px }`
 * is ten lines below this one and `.docs-body { max-width: 72ch }` is a thousand
 * lines below it; same specificity, later in the file, so the base rule won and
 * the modifier did nothing at all. /pricing/ has been asking for the wide frame
 * since it was written and getting the 820px one, which is how its plan panel
 * ended up with three 90px columns and headings breaking one word per line.
 *
 * Doubling the class makes the modifier win wherever it is declared, which is
 * the property that matters: the next person to add a rule to .page should not
 * have to know this pairing exists.
 */
.page.page--wide { max-width: var(--wrap); }
.docs-body.docs-body--wide { max-width: none; }
/* Inside the wide page the prose still wants a measure; only the panel and the
   tables are allowed the full width. */
.docs-body--wide > p, .docs-body--wide > ul, .docs-body--wide > ol,
.docs-body--wide > h2, .docs-body--wide > h3, .docs-body--wide > .faq {
  max-width: 72ch;
}
.docs-body--wide > .plan-one { margin-block: var(--s8); }

.page {
  max-width: 820px; margin-inline: auto;
  padding: var(--s8) var(--gutter) var(--s10);
}
.page-updated {
  margin: calc(var(--s7) * -1 + var(--s2)) 0 var(--s8);
  font-size: var(--t-sm); color: var(--muted);
}
.page-more {
  display: flex; flex-wrap: wrap; gap: var(--s2);
  margin-top: var(--s9); padding-top: var(--s6);
  border-top: 1px solid var(--border);
}
.page-more a {
  padding: var(--s2) var(--s4);
  border: 1px solid var(--border); border-radius: var(--r-full);
  background: var(--surface);
  color: var(--text-2); font-size: var(--t-sm); font-weight: var(--w-med);
  text-decoration: none;
  transition: border-color var(--motion-fast) var(--ease-out),
              color var(--motion-fast) var(--ease-out);
}
.page-more a:hover { border-color: var(--border-strong); color: var(--text); }

/* ---------------------------------------------------------- release notes */

/*
 * A rule down the left with a node per release, rather than a stack of cards.
 *
 * THE SHAPE IS CARRYING AN ARGUMENT. The whole job of /changelog/ is to show
 * that releases keep arriving, and a continuous line with dated nodes on it says
 * "a sequence, still going" in a way that separate cards do not — cards read as
 * a set, and a set can be complete.
 *
 * The line is drawn on the <li>, not on the <ol>, and stops at the last one:
 * a rule on the container would hang below the final entry with nothing under
 * it, which reads as a release that failed to load.
 */
.rel-list { list-style: none; margin: var(--s6) 0 0; padding-left: 0; }

.rel {
  position: relative;
  padding-left: var(--s7);
  padding-bottom: var(--s8);
}
/* The rule. Inset by the node's radius so the two meet rather than overlap. */
.rel::before {
  content: "";
  position: absolute; left: 5px; top: var(--s5); bottom: 0;
  border-left: 1px solid var(--border);
}
.rel:last-child { padding-bottom: 0; }
.rel:last-child::before { display: none; }
/* The node. */
.rel::after {
  content: "";
  position: absolute; left: 0; top: calc(var(--s2) + 1px);
  width: 11px; height: 11px;
  border-radius: var(--r-full);
  background: var(--surface);
  border: 2px solid var(--accent);
}

.rel-head {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s2) var(--s4);
  margin-bottom: var(--s3);
}
/* Reset the docs-body h3 rules: inside a flex row it wants no block margin. */
.docs-body .rel-v {
  margin: 0;
  font-family: var(--mono);
  font-size: var(--t-md);
  font-weight: var(--w-semi);
  letter-spacing: 0;
  /* Version strings are the one place tabular figures genuinely help: the
     numbers line up down the page and a glance reads the sequence. */
  font-variant-numeric: tabular-nums;
}
.rel-date {
  color: var(--muted);
  font-size: var(--t-sm);
}
.docs-body .rel-sum { margin: 0 0 var(--s3); color: var(--text); }
.docs-body .rel-items { margin: 0; color: var(--text-2); }
.docs-body .rel-items li { margin-bottom: var(--s2); }

@media (max-width: 560px) {
  .rel { padding-left: var(--s6); }
}

/* ------------------------------------------------------------ comparisons */

/* The four cards on /vs/. auto-fit rather than a fixed column count, so two
   cards sit side by side on a tablet and one on a phone with no breakpoint. */
.vs-grid {
  display: grid; gap: var(--s4);
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  margin: var(--s6) 0 var(--s8);
}
.vs-card {
  display: flex; flex-direction: column; gap: var(--s2);
  padding: var(--s5);
  border: 1px solid var(--border); border-radius: var(--r-lg);
  background: var(--surface);
  text-decoration: none;
  transition: border-color var(--motion-fast) var(--ease-out),
              box-shadow var(--motion-fast) var(--ease-out);
}
.vs-card:hover { border-color: var(--border-strong); box-shadow: var(--shadow-sm); }
.vs-kind {
  color: var(--accent-ink);
  font-family: var(--font-display);
  font-size: var(--t-micro); font-weight: 700;
  letter-spacing: var(--tr-caps); text-transform: uppercase;
}
.vs-name {
  color: var(--text);
  font-family: var(--font-display);
  font-size: var(--t-lg); font-weight: var(--w-semi);
  line-height: var(--lh-snug);
}
.vs-blurb { color: var(--text-2); font-size: var(--t-sm); line-height: var(--lh-snug); }

/* -------------------------------------------------------------- cookie bar */

/*
 * Shown to a minority of readers, so it is built to cost the other ones
 * nothing: the element ships with [hidden] and the script removes it, rather
 * than the reverse.
 */
[hidden] { display: none !important; }

.cbar {
  position: fixed; z-index: var(--z-pop);
  left: 0; right: 0; bottom: 0;
  padding: var(--s4) var(--gutter);
  /* The safe-area inset keeps it clear of the home indicator on an iPhone,
     where the bottom 34px is not reliably tappable. */
  padding-bottom: calc(var(--s4) + env(safe-area-inset-bottom, 0px));
  background: var(--surface);
  border-top: 1px solid var(--border);
  box-shadow: var(--shadow-lg);
}
.cbar-in {
  max-width: var(--wrap); margin-inline: auto;
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--s3) var(--s6);
}
.cbar-t {
  flex: 1 1 320px; margin: 0;
  color: var(--text-2); font-size: var(--t-sm); line-height: var(--lh-snug);
}
.cbar-t a { color: var(--accent-ink); }
/* Buttons never wrap away from each other, and never squash. */
.cbar-b { flex: 0 0 auto; display: flex; gap: var(--s2); }

.cbtn {
  padding: 9px var(--s5);
  border: 1px solid var(--border-strong); border-radius: var(--r-full);
  background: var(--surface);
  color: var(--text);
  font: inherit; font-size: var(--t-sm); font-weight: var(--w-med);
  cursor: pointer;
  /* 44px is the tap target the audit measures against, and a 14px label in a
     9px padding box lands just under it without this. */
  min-height: 44px;
  transition: border-color var(--motion-fast) var(--ease-out),
              background var(--motion-fast) var(--ease-out);
}
.cbtn:hover { border-color: var(--text-2); }
.cbtn--y {
  border-color: var(--accent); background: var(--accent); color: #fff;
}
.cbtn--y:hover { border-color: var(--accent-ink); background: var(--accent-ink); }

@media (max-width: 560px) {
  /* The two buttons take the full row and split it, so neither is the small
     one. Which of them is easier to press is the whole question this element
     gets judged on. */
  .cbar-b { width: 100%; }
  .cbtn { flex: 1; }
}

/* ------------------------------------------------------------------- faq */

.faq { max-width: 780px; margin-inline: auto; }
.faq details {
  border: 1px solid var(--border);
  border-radius: var(--r);
  background: var(--surface);
  margin-bottom: 10px;
  overflow: hidden;
  transition: border-color var(--motion) var(--ease), box-shadow var(--motion) var(--ease);
}
.faq details[open] {
  border-color: color-mix(in oklab, var(--accent) 22%, var(--border));
  box-shadow: var(--shadow-xs);
}
.faq summary {
  padding: 18px 22px;
  cursor: pointer;
  list-style: none;
  font-weight: 600;
  font-size: var(--t-base);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+";
  color: var(--accent);
  font-size: 1.3rem;
  font-weight: 500;
  line-height: 1;
  flex: none;
}
.faq details[open] > summary::after { content: "–"; }
.faq details[open] > summary { padding-bottom: 10px; }
.faq-panel {
  overflow: hidden;
  height: 0;
  transition: height 0.32s var(--ease);
}
.faq-panel p {
  margin: 0;
  padding: 0 22px 18px;
  color: var(--text-2);
  font-size: var(--t-md);
  line-height: var(--lh-body);
}
.faq-panel p + p { margin-top: -6px; }
@media (prefers-reduced-motion: reduce) {
  .faq-panel { transition: none; }
}

/* ------------------------------------------------------------------ band */

.band { text-align: center; }
/* The other place the display serif is used, and the only other one. */
/* The closing headline is h1-sized without being an h1. */
.band h2 {
  font-size: var(--t-h1); font-weight: 700;
  line-height: var(--lh-tight); letter-spacing: var(--tr-display);
}
.band-lede { color: var(--text-2); margin-bottom: 2em; }

/* Under the download button, quieter than it, because most people will email.
   The ones who will not are the ones deciding about a client site today. */
.band-contact {
  margin: var(--s5) 0 0;
  color: var(--muted); font-size: var(--t-sm);
}
.band-contact a {
  color: var(--text); font-weight: var(--w-semi);
  white-space: nowrap;
  /* A phone number in running prose is a 17px-tall tap target on a phone, which
     is half the 44px minimum. Padding out and margin back in enlarges the hit
     area without moving a single word. */
  display: inline-block;
  padding: 13px 4px; margin: -13px -4px;
  text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: color-mix(in oklab, var(--accent) 45%, transparent);
}
.band-contact a:hover { color: var(--accent-ink); }

/* ------------------------------------------------------------- wordmarks */

/* Names as TEXT, never as the companies' marks — see the note in home/index.php.
   A row of real logos under a marketing headline reads as endorsement. */
/* Used by /abilities/ and, until now, styled nowhere. */
.stage-note { max-width: 62ch; margin-inline: auto; color: var(--muted); font-size: var(--t-sm); text-align: center; }

.wordmarks {
  display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s3);
  margin-top: var(--s7);
  padding-top: var(--s6);
  border-top: 1px solid var(--border);
}
.wordmarks span {
  padding: 6px 13px;
  border: 1px solid var(--border);
  border-radius: var(--r-full);
  background: var(--surface);
  color: var(--text-2);
  font-size: var(--t-xs); font-weight: var(--w-med);
  letter-spacing: var(--tr-micro);
}
.steps { counter-reset: s; list-style: none; margin: 0 auto 2.2em; padding: 0; }
.steps--band { max-width: 54ch; text-align: left; }
.steps li {
  counter-increment: s; position: relative;
  padding-left: 42px; margin-bottom: 1.1em; color: var(--text-2);
}
.steps li b { color: var(--text); font-weight: 630; }
.steps li::before {
  content: counter(s);
  position: absolute; left: 0; top: 0;
  width: 26px; height: 26px; display: grid; place-items: center;
  border-radius: 50%; background: var(--accent); color: #fff;
  font-size: var(--t-micro); font-weight: 700;
}

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

footer { border-top: 1px solid var(--border); background: var(--surface); }
.foot-inner {
  max-width: var(--wrap); margin: 0 auto;
  padding: var(--s9) var(--gutter) var(--s5);
}

/*
 * Brand and contact on one side, every destination on the other.
 *
 * It was 300px + 1fr holding four columns, two of which were nine plain <span>s
 * that could not be clicked — a keyword list rather than navigation, and the
 * agents section now carries that content properly. Two real columns, and the
 * brand block gets room to be a brand block.
 */
.foot-top {
  display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.9fr);
  gap: var(--s7) var(--s8);
  padding-bottom: var(--s8);
}

.foot-logo { display: inline-flex; }
.foot-logo img { display: block; height: 30px; width: auto; }
.foot-logo:hover { opacity: .82; text-decoration: none; }
.foot-brand p {
  margin: var(--s4) 0 var(--s5);
  color: var(--muted); font-size: var(--t-sm);
  max-width: 34ch; line-height: var(--lh-snug);
}

/*
 * Email and phone as the footer's call to action, rather than as the fourth and
 * fifth items in a list of links.
 *
 * They wrap rather than shrink: at 360px two chips side by side would each be
 * about 150px and the number would break across a line, and a phone number that
 * has been hyphenated is a phone number nobody dials.
 */
.foot-contact { display: flex; flex-wrap: wrap; gap: var(--s2); }
.foot-chip {
  display: inline-flex; align-items: center; gap: var(--s2);
  padding: var(--s2) var(--s4);
  border: 1px solid var(--border);
  border-radius: var(--r-full);
  background: var(--bg-2);
  color: var(--text); font-size: var(--t-sm); font-weight: var(--w-med);
  white-space: nowrap;
  transition: border-color var(--motion-fast) var(--ease-out),
              background var(--motion-fast) var(--ease-out);
}
.foot-chip svg { width: 15px; height: 15px; flex: none; color: var(--accent); }
.foot-chip:hover {
  text-decoration: none;
  border-color: var(--accent);
  background: var(--accent-wash);
}
.foot-chip:focus-visible { outline: none; box-shadow: var(--ring); }

/*
 * The WhatsApp chip keeps the shape of its neighbours and takes the brand green
 * on the GLYPH only.
 *
 * #25D366 is WhatsApp's own green and it is a graphic colour, not a text one:
 * white on it measures about 2:1, so a filled button in it would fail AA outright
 * and a reader with any contrast difficulty would lose the label. As an icon
 * beside dark text it is recognisable and nothing depends on reading it.
 */
.foot-chip--wa svg { color: #25D366; }
.foot-chip--wa:hover {
  border-color: #25D366;
  background: color-mix(in oklab, #25D366 9%, var(--bg-2));
}

/* --------------------------------------------------------------- social */

.foot-social { display: flex; gap: var(--s2); margin-top: var(--s4); }
.foot-social a {
  display: grid; place-items: center;
  width: 34px; height: 34px;
  border: 1px solid var(--border);
  border-radius: var(--r-full);
  background: var(--bg-2);
  color: var(--muted);
  transition: color var(--motion-fast) var(--ease-out),
              border-color var(--motion-fast) var(--ease-out),
              background var(--motion-fast) var(--ease-out);
}
.foot-social svg { width: 17px; height: 17px; }
.foot-social a:hover {
  color: var(--accent);
  border-color: var(--accent);
  background: var(--accent-wash);
}
.foot-social a:focus-visible { outline: none; box-shadow: var(--ring); }

.foot-cols { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s7) var(--s5); }
.foot-cols h3 {
  margin-bottom: var(--s4);
  color: var(--text); font-size: var(--t-micro); font-weight: 700;
  letter-spacing: var(--tr-caps); text-transform: uppercase;
}
.foot-cols a {
  display: block; width: fit-content;
  padding-block: 5px;
  margin-bottom: 1px;
  color: var(--muted); font-size: var(--t-sm);
  transition: color var(--motion-fast) var(--ease-out);
}
.foot-cols a:hover { color: var(--text); text-decoration: none; }

.foot-bottom {
  display: flex; flex-wrap: wrap; gap: var(--s3) var(--s5);
  justify-content: space-between; align-items: baseline;
  padding-top: var(--s5);
  border-top: 1px solid var(--border);
}
.copy { margin: 0; color: var(--muted); font-size: var(--t-micro); }

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



/*
 * Light only, deliberately. The app is light and so is the dashboard; a
 * marketing site that flipped to dark under prefers-color-scheme would be the
 * one surface of this product that did.
 */


/* ===========================================================================
   THE PIPELINE DIAGRAM

   FLAT, TOP TO BOTTOM, IN READING ORDER. The first version rotated the whole
   deck into an isometric stack: it looked like a product diagram and read like
   nothing at all — every label on a diagonal, cards escaping their container at
   wide widths, and layer two undecipherable without tilting your head. The one
   job this has is to make a stranger understand the flow in ten seconds, and a
   design that has to be decoded first cannot do that at any level of polish.

   The depth that remains is shadow and a ring on the layer that matters, which
   is depth nobody has to decode. See inc/pipeline.php.
   =========================================================================== */

.stack { max-width: 900px; margin: 0 auto; }

/* ------------------------------------------------------------------ a layer */

.lyr {
  position: relative;
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  padding: 24px 26px 26px;
}

/* Layer two is the product. It is the only one given a ring and a tint, so the
   eye lands there first without a single word being read. */
.lyr--key {
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 8%, transparent), var(--shadow);
  background:
    radial-gradient(120% 100% at 50% 0, color-mix(in srgb, var(--accent) 5%, transparent), transparent 60%),
    var(--surface);
}

.lyr--sites { background: var(--surface-2); }

.lyr-head { display: flex; gap: 14px; align-items: flex-start; margin-bottom: 18px; }
.lyr-head b { display: block; font-size: var(--t-md); font-weight: 600; letter-spacing: -0.025em; }
.lyr-head > div > span { color: var(--muted); font-size: var(--t-xs); }

.lyr-no {
  flex: none;
  width: 28px; height: 28px;
  display: grid; place-items: center;
  border-radius: var(--r-sm);
  background: var(--surface-3); color: var(--text-2);
  font-size: var(--t-xs); font-weight: 650;
}
.lyr--key .lyr-no { background: var(--accent); color: #fff; }

.lyr-foot {
  margin: 16px 0 0; padding-top: 14px;
  border-top: 1px solid var(--border);
  color: var(--muted); font-size: var(--t-micro);
}

/* ------------------------------------------------------------------- cells */

.cells { display: grid; gap: 10px; }
.cells--4 { grid-template-columns: repeat(4, 1fr); }

.cell {
  position: relative;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: var(--r);
  background: var(--surface-2);
  cursor: default;
  transition: border-color 140ms, background 140ms, transform 140ms, box-shadow 140ms;
}
.cell:hover, .cell:focus-visible {
  outline: none;
  transform: translateY(-2px);
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  background: var(--surface);
  box-shadow: var(--shadow);
}

.cell .ic { display: block; width: 20px; height: 20px; color: var(--muted); margin-bottom: 9px; }
.cell:hover .ic, .cell:focus-visible .ic { color: var(--accent); }
.cell b { display: block; font-size: var(--t-xs); font-weight: 620; letter-spacing: -0.015em; }
.cell > span { display: block; color: var(--muted); font-size: var(--t-micro); line-height: 1.45; margin-top: 2px; }

/* The credential cell, which is what the barrier below is about. */
.cell--key {
  background: var(--accent-soft);
  border-color: color-mix(in srgb, var(--accent) 32%, transparent);
}
.cell--key .ic, .cell--key b { color: var(--accent); }
.cell--key > span { color: color-mix(in srgb, var(--accent) 78%, var(--text)); }

/* ----------------------------------------------------------------- the tip */

/*
 * ON HOVER **AND** ON KEYBOARD FOCUS. Hover alone leaves the explanation
 * unreachable for anyone not using a mouse, and this is the part of the page
 * that has to survive being read rather than skimmed — so every cell is
 * focusable and the tip answers to both.
 */
.cell .tip {
  position: absolute;
  left: 50%; bottom: calc(100% + 10px);
  transform: translate(-50%, 4px);
  width: 250px;
  padding: 11px 13px;
  border-radius: var(--r);
  background: var(--invert-bg); color: var(--invert-fg);
  font-size: var(--t-micro); line-height: 1.5; font-weight: 400;
  text-align: left;
  box-shadow: var(--shadow-lg);
  opacity: 0; pointer-events: none;
  transition: opacity 160ms, transform 160ms;
  z-index: 20;
}
.cell .tip::after {
  content: "";
  position: absolute; left: 50%; top: 100%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: var(--text);
}
.cell:hover .tip, .cell:focus-visible .tip { opacity: 1; transform: translate(-50%, 0); }

/* The first and last columns would push their tip off the edge. */
.cells--4 > .cell:first-child .tip { left: 0; transform: translate(0, 4px); }
.cells--4 > .cell:first-child:hover .tip,
.cells--4 > .cell:first-child:focus-visible .tip { transform: translate(0, 0); }
.cells--4 > .cell:first-child .tip::after { left: 28px; }

.cells--4 > .cell:last-child .tip { left: auto; right: 0; transform: translate(0, 4px); }
.cells--4 > .cell:last-child:hover .tip,
.cells--4 > .cell:last-child:focus-visible .tip { transform: translate(0, 0); }
.cells--4 > .cell:last-child .tip::after { left: auto; right: 28px; }

/* -------------------------------------------------------------- connectors */

.link {
  position: relative;
  height: 54px;
  display: grid; place-items: center;
}
.link::before {
  content: "";
  position: absolute; top: 0; bottom: 0; left: 50%;
  width: 2px; margin-left: -1px;
  background: linear-gradient(var(--border-strong), color-mix(in srgb, var(--accent) 50%, transparent));
}
/* the arrowhead, so direction is unmistakable */
.link::after {
  content: "";
  position: absolute; bottom: -1px; left: 50%;
  transform: translateX(-50%);
  border: 5px solid transparent;
  border-top-color: color-mix(in srgb, var(--accent) 55%, transparent);
}
.link-pill {
  position: relative; z-index: 2;
  padding: 5px 14px; border-radius: var(--r-full);
  background: var(--surface); border: 1px solid var(--border);
  color: var(--text-2); font-size: var(--t-micro); font-weight: 500;
  box-shadow: var(--shadow-sm);
}

/* ---------------------------------------------------------------- barrier */

/*
 * The line the whole picture exists to draw. Everything else on this page is a
 * feature; this is the product.
 */
.barrier {
  display: grid;
  grid-template-columns: 22px auto;
  gap: 4px 12px;
  align-items: center;
  margin: 18px 0 0;
  padding: 16px 20px;
  border: 1px dashed color-mix(in srgb, var(--accent) 45%, transparent);
  border-radius: var(--r-lg);
  background: var(--accent-wash);
}
.barrier .ic { width: 20px; height: 20px; color: var(--accent); }
.barrier b { font-size: var(--t-sm); font-weight: 620; color: var(--accent); }
.barrier span {
  grid-column: 2;
  color: var(--text-2); font-size: var(--t-micro); line-height: 1.55;
}

/* ------------------------------------------------------------- site grid */

.sitegrid { display: grid; grid-template-columns: repeat(10, 1fr); gap: 7px; }
.sitegrid i {
  height: 30px; border-radius: var(--r-xs);
  background: var(--surface-3); border: 1px solid var(--border);
}
.sitegrid i.on {
  background: color-mix(in srgb, var(--ok) 14%, var(--surface));
  border-color: color-mix(in srgb, var(--ok) 42%, transparent);
}

/* ------------------------------------------------------------- the stages */

/* ------------------------------------------------------------------ bento */

/*
 * SIX COLUMNS, AND THE SPANS ARE THE WHOLE POINT.
 *
 * What was here before was .flows — eight cards of identical size in two
 * columns, one per stage. Eight identical cards tell a reader that eight things
 * matter equally, and these eight do not: building a live Elementor page from a
 * Figma frame is a headline capability and "it remembers the project" supports
 * it. A uniform grid was actively misreporting them.
 *
 * The content did not change. magy_flows() in inc/data.php is the same array;
 * only how much room each entry gets is different, which is a template's
 * business. inc/bento.php holds the spans, and its source order is also the
 * order the cells stack in on a phone.
 */
.bento {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: var(--s4);
}
.b2 { grid-column: span 2; }
.b3 { grid-column: span 3; }
.b4 { grid-column: span 4; }
.b6 { grid-column: span 6; }

.bento-cell {
  display: flex; flex-direction: column;
  padding: var(--s6);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
  transition: border-color var(--motion) var(--ease), box-shadow var(--motion) var(--ease);
}
.bento-cell:hover { border-color: var(--border-strong); box-shadow: var(--shadow); }

/* The full-width cell reads as a strip rather than a card: copy on one side,
   the config file on the other. */
.bento-cell--wide {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: var(--s7); align-items: center;
}

.bento-step {
  margin: 0 0 var(--s3);
  color: var(--accent);
  font-size: var(--t-micro); font-weight: var(--w-head);
  letter-spacing: var(--tr-caps);
  font-variant-numeric: tabular-nums;
}
.bento-cell h3 { margin-bottom: var(--s2); }
.bento-lede {
  margin: 0 0 var(--s3);
  color: var(--text); font-weight: var(--w-med);
  font-size: var(--t-md); line-height: var(--lh-snug);
}
.bento-text p:last-child {
  margin: 0; color: var(--muted);
  font-size: var(--t-sm); line-height: var(--lh-snug);
}

/* Visuals sit on the floor of the cell whatever the copy above them runs to,
   so a row of cells lines up along the bottom as well as the top. */
.bento-visual { margin-top: auto; padding-top: var(--s5); }
.bento-cell--wide .bento-visual { margin-top: 0; padding-top: 0; }

/* ------------------------------------------- a Figma frame and what it becomes */

.figma-duo {
  display: grid; grid-template-columns: 1fr 24px 1fr;
  gap: var(--s3); align-items: center;
}
.fig-pane {
  border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface-2);
  overflow: hidden;
}
.fig-head {
  display: flex; align-items: center; gap: var(--s2);
  padding: var(--s2) var(--s3);
  border-bottom: 1px solid var(--border);
  background: var(--surface-3);
  color: var(--muted); font-size: var(--t-micro); font-weight: var(--w-semi);
}
.fig-dot { width: 7px; height: 7px; border-radius: 2px; background: var(--accent); }
.fig-body { padding: var(--s3); display: grid; gap: var(--s2); }
.fig-bar { height: 8px; border-radius: var(--r-xs); background: var(--border-strong); }
.fig-bar--a {
  width: 72%; height: 12px;
  background: color-mix(in oklab, var(--accent) 34%, var(--surface-3));
}
.fig-bar--b { width: 92%; }
.fig-bar--c { width: 58%; }
.fig-swatches { display: flex; gap: 5px; margin-top: var(--s1); }
.fig-swatches i { width: 14px; height: 14px; border-radius: var(--r-xs); }
.fig-swatches i:nth-child(1) { background: var(--accent); }
.fig-swatches i:nth-child(2) { background: var(--agent-cursor); }
.fig-swatches i:nth-child(3) { background: var(--agent-codex); }

.fig-arrow { color: var(--accent); }
.fig-arrow svg { display: block; width: 24px; height: 10px; }

.el-tree {
  list-style: none; margin: 0 0 var(--s2); padding: 0;
  color: var(--text-2); font-size: var(--t-micro);
}
.el-tree li { padding: 3px 0; }
.el-in { margin-left: var(--s3); }
.el-in--2 { margin-left: var(--s5); }

/* ------------------------------------------------ findings, files, config */

.findings { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s2); }
.findings li {
  display: grid; grid-template-columns: 1fr auto 14px;
  gap: var(--s3); align-items: baseline;
  padding: var(--s2) var(--s3);
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--surface-2);
  font-size: var(--t-micro);
}
.findings b { color: var(--text); font-weight: var(--w-semi); }
.findings span { color: var(--muted); }
.findings .tick { color: var(--ok); font-style: normal; font-weight: 700; }
.findings-foot { margin: var(--s3) 0 0; color: var(--muted); font-size: var(--t-micro); }
.findings-foot .chip { margin-right: 6px; }

.filelist {
  list-style: none; margin: 0; padding: 0;
  border: 1px solid var(--border); border-radius: var(--r-sm);
  overflow: hidden;
}
.filelist li {
  display: flex; justify-content: space-between; gap: var(--s3);
  padding: var(--s2) var(--s3);
  border-bottom: 1px solid var(--border);
  background: var(--surface-2);
  font-size: var(--t-micro);
}
.filelist li:last-child { border-bottom: 0; }
.filelist .mono { color: var(--text-2); font-size: var(--t-micro); }
.filelist i { color: var(--muted); font-style: normal; }
/* The one bad row. Tinted rather than red-on-white, because this is a label in
   a diagram and not an alert the reader has to act on. */
.filelist--bad { background: color-mix(in oklab, var(--agent-codex) 8%, var(--surface)); }
.filelist--bad i { color: var(--agent-codex); font-weight: var(--w-semi); }

.conf {
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--surface-2);
  overflow: hidden;
}
.conf-line {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
  padding: var(--s2) var(--s3);
  border-bottom: 1px solid var(--border);
  font-size: var(--t-micro);
}
.conf-line:last-child { border-bottom: 0; }
.conf-line .mono { font-size: var(--t-micro); }
.conf-line--dim { color: var(--muted); }
.conf-line--lit {
  background: var(--accent-wash);
  color: var(--accent-ink);
  font-weight: var(--w-semi);
  box-shadow: inset 3px 0 0 var(--accent);
}
.conf-line--lit i {
  color: var(--accent); font-style: normal;
  font-size: var(--t-micro); text-transform: uppercase;
  letter-spacing: var(--tr-caps);
}

/* ---------------------------------------------------- before and after ---

   TWO SHAPES, NOT TWO PARAGRAPHS.

   The first version was two plain cards with ten grey blobs in one of them, and
   it said nothing the sentence underneath had not already said. The difference
   between the two ways of working is structural — ten silos against one fan —
   so the picture is structural too, and the repetition on the left is the
   point rather than laziness.
   ------------------------------------------------------------------------- */

.vs {
  display: grid;
  grid-template-columns: 1fr 56px 1fr;
  align-items: stretch;
  gap: 0;
  margin-top: 28px;
}

.vs-panel {
  position: relative;
  padding: 30px 30px 28px;
  border: 1px solid var(--border);
  background: var(--surface);
}

.vs-panel--before {
  border-radius: var(--r-xl) 0 0 var(--r-xl);
  background:
    repeating-linear-gradient(-45deg,
      transparent 0 9px,
      color-mix(in srgb, var(--text) 2%, transparent) 9px 10px),
    var(--surface-2);
}

.vs-panel--after {
  border-radius: 0 var(--r-xl) var(--r-xl) 0;
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 7%, transparent), var(--shadow);
  background:
    radial-gradient(130% 90% at 50% 0, color-mix(in srgb, var(--accent) 6%, transparent), transparent 62%),
    var(--surface);
  z-index: 1;
}

/* ------------------------------------------------------------- the heads */

.vs-top { margin-bottom: 24px; }

.vs-tag {
  display: inline-block; margin-bottom: 14px;
  padding: 4px 12px; border-radius: var(--r-full);
  background: var(--surface-3); color: var(--muted);
  font-size: var(--t-micro); font-weight: 650; letter-spacing: .08em; text-transform: uppercase;
}
.vs-tag--now { background: var(--accent); color: #fff; }

.vs-count { margin: 0; font-size: var(--t-lg); color: var(--muted); letter-spacing: -0.02em; }
.vs-count b { color: var(--text); font-size: 1.5rem; font-weight: 640; }
.vs-count span { color: var(--border-strong); margin: 0 3px; }
.vs-panel--after .vs-count b { color: var(--accent); }

/* ----------------------------------------------------------- the silos */

/* Ten identical columns, each a person wired to their own box. The sameness is
   the message: nothing here is shared with anything else here. */
.silos {
  display: grid; grid-template-columns: repeat(10, 1fr); gap: 6px;
  padding: 18px 0 22px;
  color: var(--border-strong);
}
.silo { display: grid; justify-items: center; gap: 4px; }
.silo .person { width: 17px; height: 21px; color: var(--muted); }
.silo .wire {
  width: 1px; height: 12px;
  background: repeating-linear-gradient(var(--border-strong) 0 2px, transparent 2px 4px);
}
.silo .box {
  /* 4px, not --r-xs: these are 16px tall and 6px would visibly round them.
     This block is approved as drawn — see the note at the top of it. */
  width: 100%; height: 16px; border-radius: 4px;
  background: var(--surface-3); border: 1px solid var(--border-strong);
}

/* -------------------------------------------------------------- the fan */

.fan { padding: 12px 0 20px; }

.fan-top { display: grid; justify-items: center; gap: 8px; margin-bottom: 2px; }
.fan-top .person { width: 20px; height: 25px; color: var(--accent); }
.fan-node {
  padding: 5px 14px; border-radius: var(--r-full);
  background: var(--accent); color: #fff;
  font-size: var(--t-micro); font-weight: 620; letter-spacing: -0.01em;
  box-shadow: 0 6px 16px -6px color-mix(in srgb, var(--accent) 70%, transparent);
}

.fanlines {
  display: block; width: 100%; height: 62px;
  color: color-mix(in srgb, var(--accent) 42%, transparent);
}

.fan-sites { display: grid; grid-template-columns: repeat(10, 1fr); gap: 6px; }
.fan-sites i {
  height: 16px; border-radius: 4px;
  background: color-mix(in srgb, var(--ok) 14%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--ok) 40%, transparent);
}
/* Two rows of ten, so the fan lands on the first row and the second reads as
   "and more of the same". */
.fan-sites i:nth-child(n+11) { opacity: .55; }

/* ------------------------------------------------------------ the words */

.vs-line {
  margin: 0 0 18px; padding-top: 18px;
  border-top: 1px solid var(--border);
  font-size: var(--t-lg); font-weight: 550; letter-spacing: -0.02em;
}
.vs-panel--after .vs-line { color: var(--text); }
.vs-panel--before .vs-line { color: var(--text-2); }

.vs-facts { list-style: none; margin: 0; padding: 0; }
.vs-facts li {
  position: relative; padding-left: 24px; margin-bottom: .5em;
  color: var(--muted); font-size: var(--t-sm); line-height: 1.5;
}
/* A cross for the old way, a tick for the new one, both drawn rather than
   typed so they line up with the text at any size. */
.vs-facts li::before,
.vs-facts li::after { content: ""; position: absolute; }
.vs-facts li::before {
  left: 2px; top: .5em;
  width: 10px; height: 2px; border-radius: 1px;
  background: var(--border-strong);
  transform: rotate(45deg);
}
.vs-facts li::after {
  left: 2px; top: .5em;
  width: 10px; height: 2px; border-radius: 1px;
  background: var(--border-strong);
  transform: rotate(-45deg);
}
.vs-facts--good li::before {
  left: 3px; top: .48em;
  width: 9px; height: 5px;
  background: none; border-radius: 0;
  border-left: 2px solid var(--ok); border-bottom: 2px solid var(--ok);
  transform: rotate(-45deg);
}
.vs-facts--good li::after { display: none; }

/* ------------------------------------------------------ the time bars ---

   ONE SCALE ACROSS BOTH PANELS, 0 to 10 hours. That is the whole reason this
   works: two bars each filling their own box would make 40 minutes and 10 hours
   look like the same quantity of work, which is the usual way a before/after
   comparison lies. Here the fast bar is 6.7% wide because 40 minutes is 6.7% of
   600, and the emptiness to the right of it is the point.
   ------------------------------------------------------------------------- */

.clockbar { margin: 4px 0 20px; }

.clockbar-head {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: 8px;
}
.clockbar-head span {
  color: var(--muted); font-size: var(--t-micro); font-weight: 620;
  letter-spacing: .06em; text-transform: uppercase;
}
.clockbar-head b { font-size: var(--t-lg); font-weight: 640; letter-spacing: -0.03em; }

.track {
  height: 14px;
  border-radius: var(--r-full);
  background: var(--surface-3);
  border: 1px solid var(--border);
  overflow: hidden;
}

.fill { display: block; height: 100%; border-radius: var(--r-full); }

/* The slow one is hatched rather than solid: ten hours is not one smooth run,
   it is a day of stopping and starting. */
.fill--slow {
  background: repeating-linear-gradient(-45deg,
    var(--border-strong) 0 6px,
    color-mix(in srgb, var(--border-strong) 55%, var(--surface)) 6px 12px);
}

.fill--fast {
  background: linear-gradient(90deg, var(--accent), color-mix(in srgb, var(--accent) 70%, #fff));
}
/*
 * THE GLOW WAS BEING PAINTED ZERO PIXELS.
 *
 * It was a box-shadow on .fill--fast, and .track above has overflow: hidden —
 * which clips an outer box-shadow on a child. So the one visual cue that the
 * fast bar is the good outcome had never once rendered. It belongs on the track,
 * which is the element that is allowed to cast outside itself.
 */
.clockbar--fast .track {
  box-shadow: 0 0 18px -6px color-mix(in srgb, var(--accent) 60%, transparent);
}

.scale {
  display: flex; justify-content: space-between;
  margin-top: 6px;
  color: var(--muted); font-size: var(--t-micro);
}

.vs-total {
  margin: -6px 0 18px;
  color: var(--muted); font-size: var(--t-sm);
}
.vs-total b { color: var(--text-2); font-weight: 620; }
.vs-total--good b { color: var(--accent); }

/* ------------------------------------------------------------ the arrow */

.vs-mid { display: grid; place-items: center; }
.vs-arrow {
  width: 40px; height: 40px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--surface); border: 1px solid var(--border);
  color: var(--accent);
  box-shadow: var(--shadow-sm);
}
.vs-arrow svg { width: 18px; height: 18px; }


/* ------------------------------------------------------------- abilities */

.abil { display: grid; gap: 16px; grid-template-columns: repeat(3, 1fr); }
.abil article {
  padding: 24px;
  border: 1px solid var(--border); border-radius: var(--r-lg);
  background: var(--surface);
}
.abil--off { background: var(--surface-2); border-style: dashed; }
.abil h2 { margin-bottom: .5em; }
.abil p { margin: 0; color: var(--muted); font-size: var(--t-md); }

.abil-total {
  display: flex; align-items: baseline; justify-content: center; gap: 12px;
  margin-bottom: 44px;
}
.abil-total b { font-size: var(--t-h1); font-weight: 620; letter-spacing: -0.05em; }
.abil-total span { color: var(--muted); }

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

/* =================================================================== docs */

/*
 * A sidebar and a column of prose. The whole section is one layout and about
 * ninety lines, because documentation that needs more design than that is
 * usually documentation that has not been edited.
 *
 * The sidebar is a <details>. On a phone it collapses, which is the behaviour
 * you want when the nav is thirteen items and the content is why the reader
 * came; from 900px up the CSS removes the marker and forces it open, so it is a
 * plain list and the element it happens to be made of stops mattering. The
 * alternative — a button and a drawer — needs JavaScript, and the only script
 * on this site is the momentum scroll.
 */

.docs {
  display: grid;
  grid-template-columns: 232px minmax(0, 1fr);
  gap: var(--s9);
  max-width: var(--wrap);
  margin-inline: auto;
  padding: var(--s8) var(--gutter) var(--s10);
}

/* ------------------------------------------------------------- the sidebar */

.docs-nav > summary {
  display: none;             /* desktop: it is a list, not a disclosure */
}

/*
 * THE STICKY IS ON THE <details>, NOT ON THE <nav> INSIDE IT, AND THAT IS THE
 * WHOLE FIX.
 *
 * It was on the inner nav and it silently did nothing: position: sticky
 * computed, the element never moved. A sticky box travels inside its CONTAINING
 * BLOCK, and inside <details> the content is laid out in the browser's own
 * shadow slot, which is only as tall as the content. So the nav had a travel
 * range of exactly zero and behaved as static. The outer details was full column
 * height, which is why it looked like it should have worked.
 *
 * Sticking the grid item instead is the ordinary sidebar pattern, and it needs
 * align-self: start with it: a grid item stretches to the row by default, so
 * without that it would be 1600px tall and again have nowhere to travel.
 *
 * (The overflow-x: clip on html and body is NOT what broke this. That was the
 * first suspect, and toggling both off changed nothing: the top nav sticks
 * throughout. Worth recording so nobody removes those guards chasing this.)
 */
.docs-nav {
  position: sticky;
  top: calc(var(--nav-h) + var(--s5));
  align-self: start;
  max-height: calc(100vh - var(--nav-h) - var(--s7));
  overflow-y: auto;
  padding-right: var(--s2);
  /* Thin and quiet. The default bar is 15px of solid grey against a 232px
     column, which is what made the sidebar look like a frame in a frame. */
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
}
.docs-nav::-webkit-scrollbar { width: 6px; }
.docs-nav::-webkit-scrollbar-track { background: transparent; }
.docs-nav::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: var(--r-full);
}
.docs-nav:hover::-webkit-scrollbar-thumb { background: var(--muted); }

/* Tightened so the whole tree fits without scrolling on a 700px viewport, which
   is most laptops once the browser chrome is off. Links stay above the 24px
   minimum hit area. */
.docs-nav h4 {
  margin: var(--s5) 0 var(--s2);
  color: var(--muted);
  font-size: var(--t-micro); font-weight: 700;
  letter-spacing: var(--tr-caps); text-transform: uppercase;
}
.docs-nav h4:first-child { margin-top: 0; }
.docs-nav ul { list-style: none; margin: 0; padding: 0; }
.docs-nav a {
  display: block;
  padding: 5px var(--s3);
  margin-left: calc(var(--s3) * -1);
  border-radius: var(--r-sm);
  color: var(--text-2);
  font-size: var(--t-sm);
  transition: background var(--motion-fast) var(--ease-out),
              color var(--motion-fast) var(--ease-out);
}
.docs-nav a:hover { background: var(--bg-2); color: var(--text); text-decoration: none; }
.docs-nav a.on {
  background: var(--accent-soft);
  color: var(--accent-ink);
  font-weight: var(--w-semi);
}

/* ---------------------------------------------------------------- the page */

/* min-width: 0 for the same reason as the grid track: a grid item will not
   shrink below its min-content unless told it may. */
.docs-body { max-width: 72ch; min-width: 0; }

/* The h1 here is a page title, not the hero headline the base layer sizes it
   as — 72px over a paragraph of documentation is a poster, not a heading. */
.docs-body h1 {
  max-width: none;
  margin-bottom: var(--s4);
  font-size: clamp(1.875rem, 1.4rem + 1.9vw, 2.5rem);
  letter-spacing: var(--tr-h2);
}
.docs-lede { margin: 0 0 var(--s8); max-width: none; }

.docs-body h2 {
  margin: var(--s9) 0 var(--s4);
  padding-top: var(--s5);
  border-top: 1px solid var(--border);
  font-size: var(--t-h3);
}
.docs-body h2:first-of-type { margin-top: var(--s7); }
.docs-body h3 { margin: var(--s6) 0 var(--s3); font-size: var(--t-lg); }
.docs-body p { color: var(--text-2); line-height: var(--lh-loose); }
.docs-body ul, .docs-body ol { margin: 0 0 var(--s4); padding-left: var(--s5); color: var(--text-2); }
.docs-body li { margin-bottom: var(--s2); line-height: var(--lh-snug); }
.docs-body a { text-decoration: underline; text-underline-offset: 2px; }

/* Inline code, and it is deliberately quiet: these are file paths and key
   names, read once, not syntax to be studied. */
.docs-body code {
  padding: 2px 6px;
  border: 1px solid var(--border);
  border-radius: var(--r-xs);
  background: var(--surface-2);
  color: var(--text);
  font-family: var(--mono); font-size: .92em;
  letter-spacing: 0;
  word-break: break-word;
}

/* Numbered steps that look like steps rather than like a list that happens to
   have numbers. Reuses the counter idiom from the closing band. */
.doc-steps { counter-reset: d; list-style: none; padding-left: 0; }
.doc-steps > li {
  position: relative;
  margin-bottom: var(--s4);
  padding-left: var(--s7);
  line-height: var(--lh-snug);
}
.doc-steps > li::before {
  counter-increment: d;
  content: counter(d);
  position: absolute; left: 0; top: -1px;
  width: 26px; height: 26px;
  display: grid; place-items: center;
  border-radius: var(--r-full);
  background: var(--accent-soft); color: var(--accent-ink);
  font-family: var(--font-display);
  font-size: var(--t-micro); font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* Term and definition, for "the four pieces" and the refusals list. */
.doc-dl { margin: 0 0 var(--s5); }
.doc-dl dt {
  margin-top: var(--s5);
  color: var(--text); font-weight: var(--w-semi);
}
.doc-dl dt:first-child { margin-top: 0; }
.doc-dl dd {
  margin: var(--s2) 0 0;
  padding-left: var(--s4);
  border-left: 2px solid var(--border);
  color: var(--text-2);
  line-height: var(--lh-snug);
}

/* An instruction the reader would actually type to their agent. Set as speech,
   because that is what it is, and the whole point of the page is that this
   replaces a form and six clicks. */
.doc-say {
  margin: var(--s5) 0;
  padding: var(--s4) var(--s5);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--r) var(--r) 0;
  background: var(--accent-wash);
  color: var(--text);
  font-size: var(--t-lg);
  line-height: var(--lh-snug);
}

/*
 * The before and after table. It scrolls sideways on its own below about 560px
 * rather than squeezing two columns of prose into 160px each, which is the one
 * place the page is allowed to scroll horizontally.
 */
/* The same spoken instruction, centred, when it is carrying a section rather
   than sitting inside a docs paragraph. */
.say--center {
  max-width: 62ch;
  margin-inline: auto;
  margin-bottom: var(--s7);
  border-left: 0;
  border-radius: var(--r-lg);
  border: 1px solid color-mix(in oklab, var(--accent) 20%, var(--border));
  text-align: center;
}

.scale-note {
  max-width: 62ch;
  margin: var(--s7) auto 0;
  color: var(--muted);
  font-size: var(--t-sm);
  text-align: center;
}

.doc-table { margin: var(--s5) 0; overflow-x: auto; }
.doc-table table {
  width: 100%; min-width: 440px;
  border-collapse: collapse;
  font-size: var(--t-md);
}
.doc-table th {
  padding: var(--s3) var(--s4);
  border-bottom: 2px solid var(--border-strong);
  color: var(--text); text-align: left;
  font-family: var(--font-display);
  font-size: var(--t-sm); font-weight: 700;
  letter-spacing: var(--tr-caps); text-transform: uppercase;
}
.doc-table th:last-child { color: var(--accent-ink); }
.doc-table td {
  padding: var(--s3) var(--s4);
  border-bottom: 1px solid var(--border);
  color: var(--text-2);
  line-height: var(--lh-snug);
  vertical-align: top;
}
.doc-table td:last-child { color: var(--text); }
.doc-table tr:last-child td { border-bottom: 0; }
.doc-table tbody tr:hover td { background: var(--surface-2); }

/* The one thing on a page that a reader must not skim past. */
.callout {
  margin: var(--s6) 0;
  padding: var(--s5);
  border: 1px solid color-mix(in oklab, var(--accent) 22%, var(--border));
  border-left-width: 3px;
  border-radius: var(--r);
  background: var(--accent-wash);
  color: var(--text-2);
  font-size: var(--t-md);
  line-height: var(--lh-snug);
}
.callout b { color: var(--text); }

/* ------------------------------------------------------------ prev / next */

.docs-more {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--s4);
  margin-top: var(--s9);
  padding-top: var(--s6);
  border-top: 1px solid var(--border);
}
.docs-more a {
  display: block;
  padding: var(--s4) var(--s5);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  text-decoration: none;
  transition: border-color var(--motion) var(--ease), box-shadow var(--motion) var(--ease);
}
.docs-more a:hover { border-color: var(--border-strong); box-shadow: var(--shadow); }
.docs-more span {
  display: block;
  color: var(--muted);
  font-size: var(--t-micro); letter-spacing: var(--tr-micro);
}
.docs-more b {
  display: block; margin-top: 2px;
  color: var(--text); font-size: var(--t-md); font-weight: var(--w-semi);
}
.docs-more-next { text-align: right; }

/* ================================================================== scroll */

/*
 * WHAT CSS CAN AND CANNOT DO ABOUT HOW SCROLLING FEELS.
 *
 * It cannot change the wheel. The momentum, the easing and the rubber-banding
 * of a scroll gesture belong to the browser and the OS, and the libraries that
 * override them — Lenis, Locomotive — work by cancelling the native scroll and
 * re-implementing it in JavaScript. This site cannot do that: the docroot's
 * .htaccess grants html, css, images and fonts, and NOT js, so a script file is
 * served a 403. That is a deliberate decision, because this document root also
 * holds verify.php, the licence endpoint every install heartbeats against.
 *
 * What it can do — and what actually accounts for most of the difference
 * between a page that feels soft and one that feels hard — is make the content
 * arrive rather than appear. Scroll-driven animations do that natively, on the
 * compositor, with no script at all:
 *
 *   - every block rises a little and fades in as it enters the viewport,
 *     tied to scroll POSITION rather than to a timer, so it tracks the gesture
 *     exactly and reverses when the reader scrolls back up
 *   - the product shot lifts and settles as it comes up
 *   - a progress line fills across the bottom edge of the nav
 *
 * Because the timeline is per-element, a grid staggers itself: each cell
 * animates as that cell crosses the threshold. No index arithmetic, and it
 * looks right at every width.
 *
 * TWO GATES, BOTH LOAD-BEARING:
 *
 *   @supports  — where scroll timelines are unsupported, none of this is
 *                declared at all, so the content is simply visible. The failure
 *                mode to avoid is content stuck at opacity 0 because a reveal
 *                never fired, and an @supports block makes that impossible
 *                rather than unlikely.
 *   prefers-reduced-motion — off entirely. Not slowed: off.
 */

/* The nav's read-progress line. Zero-width by default, so a browser without
   scroll timelines shows nothing rather than a permanently full bar. */
.nav-progress {
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 2px;
  background: linear-gradient(90deg,
    var(--accent),
    color-mix(in oklab, var(--accent) 55%, #fff));
  transform: scaleX(0);
  transform-origin: 0 50%;
  z-index: var(--z-raised);
  pointer-events: none;
}

@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .nav-progress {
      animation: magy-progress linear;
      animation-timeline: scroll(root block);
    }
    @keyframes magy-progress {
      from { transform: scaleX(0); }
      to { transform: scaleX(1); }
    }
  }
}

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {

    /*
     * ELEVEN ELEMENTS, AND THE COUNT IS THE WHOLE POINT.
     *
     * This list used to name nineteen selectors, which matched FIFTY-FIVE
     * elements on the homepage — four diagram layers, eight bento cells, seven
     * FAQ rows, three plans, three stat cells, three tiles, and so on. Each one
     * animating transform and opacity gets promoted to its own composited layer,
     * and fifty-five of those on a page that also holds two 1350x700 PNGs is
     * enough GPU memory pressure to drop frames on integrated graphics. Together
     * with the blurred sticky nav above, that is why the page stuttered.
     *
     * So the reveal is now on the eight section heads and the three screenshots:
     * the points where a reader arrives somewhere new. Cards, rows and diagram
     * layers simply appear, which is what cursor.com does with its own — nothing
     * on that page animates per-card either.
     *
     * The rule to keep: a reveal is worth a composited layer at the top of a
     * section. It is not worth one per card.
     */
    .section-head {
      animation: magy-rise linear both;
      animation-timeline: view();
      animation-range: entry 2% cover 18%;
    }

    @keyframes magy-rise {
      from { opacity: 0; transform: translateY(18px); }
      to { opacity: 1; transform: none; }
    }

    /*
     * The product shot gets its own, longer, because it is the largest object
     * on the page and the one the eye lands on: it comes up from slightly
     * further and settles a fraction later than the copy above it.
     */
    .shot-stage .shot {
      animation: magy-settle linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 26%;
    }
    @keyframes magy-settle {
      from { opacity: 0; transform: translateY(30px) scale(.985); }
      to { opacity: 1; transform: none; }
    }

    /*
     * The in-section screenshots are already in view when their section is, so
     * they take the plain rise on a shorter range rather than the settle.
     */
    .shot--plain {
      animation: magy-rise linear both;
      animation-timeline: view();
      animation-range: entry 4% cover 22%;
    }
  }
}

/* ------------------------------------------------------------ hover polish */

/*
 * Everything that is a card now lifts by one pixel and warms its border. One
 * pixel because these are surfaces on paper, not buttons: the cue should be
 * that the card is live, not that it is about to leave the page.
 */
.tile, .plan, .faq details, .abil article, .grid > article {
  transition: border-color var(--motion) var(--ease),
              box-shadow var(--motion) var(--ease),
              transform var(--motion) var(--ease);
}
.tile:hover, .plan:hover, .abil article:hover, .grid > article:hover {
  border-color: var(--border-strong);
  box-shadow: var(--shadow);
  transform: translateY(-1px);
}
.faq details:hover { border-color: var(--border-strong); }
.bento-cell:hover { transform: translateY(-1px); }

/* The plan panel is a single card the reader is not choosing between, so it does
   not lift on hover. Only its call to action responds. */

/* A gradient hairline along the top of the widest bento cell — the only piece
   of pure decoration on the page, and it is one pseudo-element. */
.bento-cell--wide { position: relative; overflow: hidden; }
.bento-cell--wide::before {
  content: "";
  position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg,
    transparent,
    color-mix(in oklab, var(--accent) 60%, transparent) 30%,
    color-mix(in oklab, var(--accent) 60%, transparent) 70%,
    transparent);
}

/* ============================================================ breakpoints */

/*
 * ALL OF THEM, IN ONE PLACE, WIDEST FIRST.
 *
 * They used to be in six blocks scattered through the file in source order
 * 980 -> 760 -> 900 -> 900 -> reduced-motion -> reduced-motion. Two things were
 * wrong with that beyond the untidiness:
 *
 *   1. At a 700px viewport BOTH the 760 and the 900 block apply, and the later
 *      one in source order wins. Nothing conflicted, so nothing was broken —
 *      but any future rule declared in both would have taken the wide value on
 *      a narrow screen, which is the hardest kind of bug to see.
 *   2. The two 900px blocks were six hundred lines apart, so a change to the
 *      diagram's behaviour and a change to the same-width behaviour of the
 *      before/after block looked unrelated.
 *
 * Ordered narrow-last now, so narrower always wins. Still max-width rather than
 * min-width: this file has ~550 lines of illustration blocks with
 * breakpoint-specific overrides — a tooltip that goes position: static, a
 * comparison that collapses to one column, an SVG fan that shortens — and
 * inverting the polarity of all of that by hand, with no build step and no
 * tests, would buy a reader nothing.
 */

/* The bento only. Nothing else needs a step here, and the fluid --gutter is
   what keeps the page off the viewport edges between 980 and 1188. */
@media (max-width: 1200px) {
  .bento { grid-template-columns: repeat(4, 1fr); }
  .b4, .b6, .bento-cell--wide { grid-column: span 4; }
  .b3, .b2 { grid-column: span 2; }
}

@media (max-width: 980px) {
  /*
   * THE PHONE NAV. This used to be `.nav-links { display: none }` and nothing
   * else, which meant a phone had no navigation at all above the footer — every
   * link on the site was unreachable from the header.
   *
   * The links become a panel under the bar rather than a full-screen overlay.
   * The bar stays visible and so does the logo, so it is obvious what closed and
   * how to close it, and there is no scroll-locking to get wrong.
   */
  .nav-burger { display: flex; }
  .nav-cta { margin-left: auto; }

  .nav-links {
    position: absolute; left: 0; right: 0; top: 100%;
    flex-direction: column; gap: 0;
    padding: var(--s2) var(--gutter) var(--s4);
    border-bottom: 1px solid var(--border);
    background: var(--surface);
    box-shadow: var(--shadow-md);
    /* Closed by default, and closed by the same property that opens it, so a
       browser that never runs the script shows nothing rather than a panel
       stuck open across the page. */
    display: none;
  }
  .nav-open .nav-links { display: flex; }

  .nav-links > a,
  .nav-menu a {
    padding: 13px 0;              /* 44px+ rows, per WCAG 2.2 */
    border-bottom: 1px solid var(--border);
    color: var(--text); font-size: var(--t-base);
  }
  .nav-links > a:last-child { border-bottom: 0; }

  /*
   * NO NESTED DROPDOWN ON A PHONE. The panel has the room, and a menu inside a
   * menu is two taps and a guess to reach a page. The group's button becomes a
   * heading for its children and the children are always shown, so both tours
   * are one tap from opening the burger.
   */
  .nav-group { position: static; }
  .nav-group-btn {
    width: 100%;
    padding: 16px 0 6px;
    color: var(--muted);
    font-size: var(--t-micro); font-weight: 700;
    letter-spacing: var(--tr-caps); text-transform: uppercase;
    cursor: default;
  }
  .nav-group-btn svg { display: none; }

  .nav-menu,
  .nav-group.open .nav-menu {
    display: block;
    position: static;
    min-width: 0; padding: 0;
    border: 0; border-radius: 0;
    background: none; box-shadow: none;
  }
  .nav-menu a { padding-left: var(--s4); }

  /* The bar has to be the positioning context for the panel, and it must sit
     above the page while open. */
  .nav { position: sticky; }
  .nav-inner { position: relative; gap: var(--s3); }

  .plan-one {
    grid-template-columns: 1fr;
    grid-template-areas:
      "rail"
      "feats"
      "foot";
  }
  .plan-rail {
    border-right: 0;
    border-bottom: 1px solid var(--border);
    padding: var(--s6) var(--s5);
  }
  .plan-feats {
    grid-template-columns: 1fr;
    gap: var(--s6);
    padding: var(--s6) var(--s5);
  }
  .plan-foot { padding: 16px var(--s5) 20px; }
  .price-ctas--row .btn { flex: 1 1 100%; }
  .duo, .trio { grid-template-columns: 1fr; }
  .feature { grid-template-columns: 1fr; gap: var(--s7); }
  .feature--rev .feature-text { order: 0; }
  .foot-top { grid-template-columns: 1fr; gap: var(--s7); }
  .foot-cols { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s6) var(--s5); }
}

@media (max-width: 900px) {
  /* ---- the diagram */
  .cells--4 { grid-template-columns: repeat(2, 1fr); }
  .sitegrid { grid-template-columns: repeat(5, 1fr); }
  .abil { grid-template-columns: 1fr; }
  .lyr { padding: var(--s5); }

  /* A 250px tooltip does not fit beside a half-width cell. It becomes a plain
     block under the summary, always visible — the information matters more than
     the interaction. */
  .cell .tip {
    position: static; width: auto; transform: none;
    opacity: 1; margin-top: var(--s3);
    background: var(--surface-3); color: var(--text-2);
    box-shadow: none;
  }
  .cell .tip::after { display: none; }

  /* ---- the time contrast */
  .vs { grid-template-columns: 1fr; }
  .vs-panel--before { border-radius: var(--r-xl) var(--r-xl) 0 0; }
  .vs-panel--after { border-radius: 0 0 var(--r-xl) var(--r-xl); }
  .vs-mid { padding: var(--s3) 0; }
  .vs-arrow { transform: rotate(90deg); }
  .silos { grid-template-columns: repeat(5, 1fr); gap: var(--s2); }
  .fan-sites { grid-template-columns: repeat(5, 1fr); }
  .fanlines { height: 44px; }

  /* ---- the docs sidebar becomes a real disclosure */
  /*
   * minmax(0, 1fr) and not 1fr. A bare 1fr is minmax(AUTO, 1fr), and auto as a
   * minimum means min-content: the scrollable table inside the page carries
   * min-width: 440px, and that floor propagated up through the grid item and
   * made the whole column 416px wide inside a 320px viewport. The list items
   * beside it were then hanging 115px off the screen while the table itself,
   * being in its own scroll box, looked innocent.
   */
  .docs { grid-template-columns: minmax(0, 1fr); gap: var(--s6); padding-top: var(--s7); }
  .docs-nav {
    position: static;
    max-height: none;
    overflow: visible;
    padding-right: 0;
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    background: var(--surface);
  }
  .docs-nav > summary {
    display: block;
    padding: var(--s4) var(--s5);
    cursor: pointer;
    font-family: var(--font-display);
    font-size: var(--t-md); font-weight: var(--w-semi);
  }
  .docs-nav[open] > summary { border-bottom: 1px solid var(--border); }
  .docs-nav nav {
    position: static; max-height: none; overflow: visible;
    padding: var(--s4) var(--s5) var(--s5);
  }
  .docs-more { grid-template-columns: 1fr; }

  /* ---- the bento */
  .bento { grid-template-columns: 1fr; }
  .b2, .b3, .b4, .b6 { grid-column: span 1; }
  .bento-cell--wide { grid-template-columns: 1fr; gap: var(--s5); }
  .bento-cell--wide .bento-visual { padding-top: var(--s5); }
  .figma-duo { grid-template-columns: 1fr; }
  .fig-arrow { transform: rotate(90deg); margin-inline: auto; }
}

/*
 * THE NAV DID NOT FIT ON A PHONE, AND CLIPPING WOULD HAVE HIDDEN THAT RATHER
 * THAN FIXED IT.
 *
 * At 360px the row came to 20 + 134 (wordmark) + 32 (gap) + 80 (Sign in) + 8 +
 * 134 (Get Multiagentry) + 20 = 428px, and .btn is white-space: nowrap, so
 * nothing gave: the primary button hung 55px off the right edge. Measured, not
 * guessed — website/test/overflow.test.js named the element and the number.
 *
 * Sign in goes first: it is the owner's dashboard link, it is in the footer
 * already, and of the two buttons it is the one a visitor on a phone has no use
 * for. Then the gap tightens and the wordmark comes down to 22px, which leaves
 * about 60px of slack at 360 instead of none.
 */
@media (max-width: 560px) {
  .nav-inner { gap: var(--s3); }
  .brand img { height: 22px; }
}

@media (max-width: 760px) {
  .foot-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .announce { font-size: var(--t-micro); padding: var(--s2) var(--s4); }
  .grid--2 { grid-template-columns: 1fr; }
  .strip-board { grid-template-columns: 1fr; }
  .strip-hook {
    gap: 20px;
    padding: 26px 22px;
  }
  .strip-hook-title { max-width: 16ch; }
  .strip-grid { grid-template-columns: 1fr; }
  .strip-cell {
    border-right: 0;
    border-bottom: 1px solid var(--border);
  }
  .strip-cell:nth-child(2n) { border-right: 0; }
  .strip-cell:nth-child(n + 3) { border-bottom: 1px solid var(--border); }
  .strip-cell:last-child { border-bottom: 0; }
  .shot-body { grid-template-columns: 1fr; }
  .shot-side { display: none; }
  .shot-stage { padding-bottom: var(--s8); }
  .tile-text { padding: var(--s5) var(--s5) var(--s1); }
  .tile-visual { padding: var(--s5); }
  .bento-cell { padding: var(--s5); }
  .figma-duo, .findings, .conf { font-size: var(--t-micro); }
}

/*
 * ONE reduced-motion block, not two.
 *
 * The old pair overlapped and it was tempting to delete the second as
 * redundant: the first already had * { transition: none !important }. It was
 * not redundant. A transition of none stops the ANIMATION while the hover
 * transform still applies instantly, so the lift on a diagram cell survived.
 * That rule is kept below and the genuinely duplicated half is gone.
 *
 * Durations go to 1ms rather than 0 because a zero-duration transition does not
 * fire transitionend, and to zero on the tokens so anything reading them gets a
 * consistent answer.
 */
@media (prefers-reduced-motion: reduce) {
  :root { --motion-fast: 0ms; --motion: 0ms; --motion-slow: 0ms; }
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    transition-duration: 1ms !important;
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
  }
  .cell:hover, .cell:focus-visible,
  .tile:hover, .plan:hover, .abil article:hover,
  .grid > article:hover, .bento-cell:hover { transform: none; }
}

/* --------------------------------------------------------------- ask form */

.ask {
  position: relative;
  padding: clamp(48px, 8vw, 96px) var(--gutter) clamp(72px, 10vw, 120px);
  overflow: hidden;
}
.ask-inner {
  max-width: var(--wrap-wide);
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(32px, 5vw, 72px);
  align-items: start;
}
.ask-copy { padding-top: var(--s3); }
.ask-copy h1 {
  margin: 0 0 var(--s4);
  font-size: clamp(2rem, 1.4rem + 2.2vw, 3.1rem);
  letter-spacing: -0.035em;
  line-height: 1.08;
}
.ask-lede {
  margin: 0 0 var(--s6);
  max-width: 36ch;
  color: var(--text-2);
  font-size: var(--t-lg);
}
.ask-points {
  list-style: none;
  margin: 0 0 var(--s6);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.ask-points li {
  position: relative;
  padding-left: 1.35em;
  color: var(--text-2);
  font-size: var(--t-sm);
}
.ask-points li::before {
  content: "";
  position: absolute; left: 0; top: .55em;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent);
}
.ask-alt {
  margin: 0;
  color: var(--muted);
  font-size: var(--t-sm);
}
.ask-alt a { font-weight: 600; }

.ask-panel {
  position: relative;
  padding: clamp(22px, 3vw, 32px);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-xl);
  background: var(--surface);
  box-shadow: var(--shadow-md), var(--edge);
  overflow: hidden;
}
.ask-panel::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 2px;
  background: linear-gradient(90deg,
    transparent 0%,
    color-mix(in oklab, var(--accent) 55%, transparent) 25%,
    var(--accent) 50%,
    color-mix(in oklab, var(--accent) 55%, transparent) 75%,
    transparent 100%);
  z-index: 1;
}
.ask-form, .ask-done { position: relative; z-index: 1; }

.ask-done h2 {
  margin: 0 0 var(--s3);
  font-size: clamp(1.6rem, 1.2rem + 1.2vw, 2rem);
  letter-spacing: -0.03em;
}
.ask-done-kicker {
  margin: 0 0 6px;
  color: var(--accent);
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
}
.ask-done p { color: var(--text-2); margin: 0 0 var(--s6); max-width: 38ch; }

.ask-err {
  margin: 0 0 var(--s4);
  padding: 10px 12px;
  border-radius: var(--r-sm);
  background: color-mix(in oklab, #b01c1c 10%, var(--surface));
  border: 1px solid color-mix(in oklab, #b01c1c 28%, var(--border));
  color: #8f1818;
  font-size: var(--t-sm);
}

.ask-hp {
  position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden;
}

.ask-want {
  margin: 0 0 var(--s5);
  padding: 0;
  border: 0;
}
.ask-want legend {
  margin: 0 0 10px;
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--muted);
}
.ask-want-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
.ask-chip {
  position: relative;
  cursor: pointer;
}
.ask-chip input {
  position: absolute; inset: 0; opacity: 0; cursor: pointer;
}
.ask-chip span {
  display: flex; align-items: center; justify-content: center;
  min-height: 44px;
  padding: 10px 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--text-2);
  font-size: var(--t-sm);
  font-weight: 600;
  text-align: center;
  transition: border-color 140ms, background 140ms, color 140ms, box-shadow 140ms;
}
.ask-chip input:checked + span {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent-ink);
  box-shadow: var(--ring);
}
.ask-chip input:focus-visible + span { box-shadow: var(--ring); }

.ask-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s4);
  margin-bottom: var(--s4);
}
.ask-field {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin-bottom: var(--s4);
}
.ask-row .ask-field { margin-bottom: 0; }
.ask-field > span {
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--text-2);
}
.ask-field > span i {
  font-style: normal;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--muted);
  opacity: .85;
}
.ask-field input,
.ask-field select,
.ask-field textarea {
  width: 100%;
  padding: 13px 14px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  color: var(--text);
  font: inherit;
  font-size: var(--t-sm);
  transition: border-color 140ms, box-shadow 140ms, background 140ms;
}
.ask-field input:hover,
.ask-field select:hover,
.ask-field textarea:hover {
  border-color: color-mix(in oklab, var(--accent) 28%, var(--border-strong));
}
.ask-field input:focus,
.ask-field select:focus,
.ask-field textarea:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--surface);
  box-shadow: var(--ring);
}
.ask-field textarea { min-height: 96px; resize: vertical; }
.ask-submit { width: 100%; justify-content: center; margin-top: var(--s2); }
.ask-fine {
  margin: var(--s4) 0 0;
  text-align: center;
  color: var(--muted);
  font-size: var(--t-micro);
}

@media (max-width: 900px) {
  .ask-inner { grid-template-columns: 1fr; gap: var(--s7); }
  .ask-lede { max-width: none; }
}
@media (max-width: 560px) {
  .ask-row, .ask-want-grid { grid-template-columns: 1fr; }
  .ask-want-grid--3 { grid-template-columns: 1fr; }
}

/* ------------------------------------------------------- Meta funnel */

.hero-badges {
  margin-top: var(--s4);
  font-size: var(--t-sm);
  color: var(--muted);
  letter-spacing: 0.01em;
}

.demo-poster {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: #0b0b12;
  cursor: pointer;
  aspect-ratio: 16 / 9;
  overflow: hidden;
}
.demo-poster img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.demo-poster__play {
  position: absolute;
  inset: 50% auto auto 50%;
  width: 68px;
  height: 68px;
  margin: -34px 0 0 -34px;
  border-radius: 50%;
  background: color-mix(in oklab, var(--accent) 92%, #000);
  box-shadow: 0 10px 28px rgb(0 0 0 / .35);
  pointer-events: none;
}
.demo-poster__play::before {
  content: "";
  position: absolute;
  left: 26px; top: 22px;
  border-style: solid;
  border-width: 12px 0 12px 20px;
  border-color: transparent transparent transparent #fff;
}
.demo-poster:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
.shot-video[data-loaded] .demo-poster { display: none; }
.shot-video iframe {
  width: 100%;
  aspect-ratio: 16 / 9;
  border: 0;
  display: block;
}

.ask-band {
  padding: clamp(48px, 7vw, 88px) max(var(--gutter), (100% - var(--wrap)) / 2);
  background: var(--bg);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.alt + .ask-band,
.g-deep + .ask-band,
.g-warm + .ask-band,
.ask-band + .ask-band {
  border-top: 0;
}
.ask-band--bottom {
  background: var(--bg);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.ask-band-inner {
  max-width: 980px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 0.88fr) minmax(0, 1.12fr);
  gap: clamp(32px, 5vw, 56px);
  align-items: start;
}
.ask-band-copy {
  padding-top: clamp(8px, 1.2vw, 18px);
}
.ask-band-copy .kicker {
  margin-bottom: .7em;
  color: var(--accent);
}
.ask-band-copy h2 {
  margin: 0 0 var(--s4);
  font-size: clamp(1.65rem, 1.2rem + 1.6vw, 2.35rem);
  letter-spacing: -0.04em;
  line-height: var(--lh-head);
}
.ask-band-copy > p {
  margin: 0;
  color: var(--text-2);
  max-width: 36ch;
  font-size: var(--t-lg);
  line-height: var(--lh-body);
}
.ask-band-points {
  list-style: none;
  margin: var(--s6) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.ask-band-points li {
  position: relative;
  padding-left: 28px;
  color: var(--text);
  font-size: var(--t-sm);
  font-weight: 550;
  line-height: var(--lh-snug);
}
.ask-band-points li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .15em;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--accent-soft);
  border: 1px solid color-mix(in oklab, var(--accent) 22%, var(--border));
}
.ask-band-points li::after {
  content: "";
  position: absolute;
  left: 5px;
  top: .5em;
  width: 8px;
  height: 4px;
  border-left: 1.75px solid var(--accent-ink);
  border-bottom: 1.75px solid var(--accent-ink);
  transform: rotate(-45deg);
}
.ask-panel--compact {
  padding: clamp(22px, 2.8vw, 30px);
}
.ask-want-grid--3 {
  grid-template-columns: repeat(3, 1fr);
}
.ask-band .ask-chip span {
  border-radius: var(--r);
  background: var(--surface-2);
}
.ask-band .ask-submit {
  margin-top: var(--s3);
  min-height: 48px;
  box-shadow: 0 8px 20px -8px color-mix(in oklab, var(--accent) 55%, transparent);
}
.ask-band .ask-fine {
  margin-top: var(--s4);
  line-height: 1.5;
}

@media (max-width: 720px) {
  .ask-band-inner { grid-template-columns: 1fr; gap: var(--s6); }
  .ask-band-copy { padding-top: 0; text-align: center; }
  .ask-band-copy > p { max-width: none; margin-inline: auto; }
  .ask-band-points {
    align-items: flex-start;
    max-width: 32ch;
    margin-inline: auto;
    text-align: left;
  }
}

.who-for {
  padding-block: clamp(56px, 7vw, 88px);
  background: var(--bg);
}
.who-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s5);
  max-width: 1080px;
  margin: 0 auto;
}
.who-card {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: clamp(22px, 2.5vw, 28px);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
  transition:
    border-color var(--motion) var(--ease),
    box-shadow var(--motion) var(--ease),
    transform var(--motion) var(--ease),
    background var(--motion) var(--ease);
}
.who-card::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 2px;
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  opacity: 0;
  transition: opacity var(--motion) var(--ease);
}
.who-icon {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-bottom: var(--s4);
  border-radius: 12px;
  background: var(--accent-soft);
  border: 1px solid color-mix(in oklab, var(--accent) 18%, var(--border));
  color: var(--accent-ink);
  transition:
    background var(--motion) var(--ease),
    border-color var(--motion) var(--ease),
    color var(--motion) var(--ease),
    transform var(--motion) var(--ease),
    box-shadow var(--motion) var(--ease);
}
.who-icon svg {
  width: 22px;
  height: 22px;
}
.who-card h3 {
  margin: 0 0 var(--s3);
  font-size: var(--t-lg);
  letter-spacing: -0.02em;
}
.who-card p {
  margin: 0;
  color: var(--text-2);
  font-size: var(--t-sm);
  line-height: var(--lh-body);
}
@media (hover: hover) and (pointer: fine) {
  .who-card:hover {
    border-color: color-mix(in oklab, var(--accent) 28%, var(--border));
    box-shadow: var(--shadow-md);
    transform: translateY(-3px);
    background: color-mix(in oklab, var(--accent-wash) 55%, var(--surface));
  }
  .who-card:hover::before { opacity: 1; }
  .who-card:hover .who-icon {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
    transform: scale(1.06);
    box-shadow: 0 8px 18px -8px color-mix(in oklab, var(--accent) 65%, transparent);
  }
}
.who-card:focus-within {
  border-color: color-mix(in oklab, var(--accent) 28%, var(--border));
  box-shadow: var(--ring);
}
@media (prefers-reduced-motion: reduce) {
  .who-card,
  .who-icon { transition: none; }
  .who-card:hover { transform: none; }
  .who-card:hover .who-icon { transform: none; }
}

.lahore-band {
  padding: clamp(28px, 4vw, 40px) max(var(--gutter), (100% - var(--wrap)) / 2);
  background: #f5f4fc;
  border-top: 1px solid color-mix(in oklab, var(--accent) 14%, var(--border));
  border-bottom: 1px solid color-mix(in oklab, var(--accent) 14%, var(--border));
}
.lahore-inner {
  max-width: 1080px;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s5);
}
.lahore-inner h2 {
  margin: 0 0 8px;
  font-size: clamp(1.35rem, 1.1rem + 1vw, 1.75rem);
  letter-spacing: -0.03em;
}
.lahore-inner p { margin: 0; color: var(--text-2); max-width: 48ch; }

.tech-acc {
  padding-block: clamp(48px, 6vw, 80px);
}
.tech-acc-list {
  max-width: 1080px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.tech-acc-item {
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface);
  padding: 0;
  box-shadow: var(--shadow-xs);
  overflow: hidden;
  transition: border-color var(--motion) var(--ease), box-shadow var(--motion) var(--ease);
}
.tech-acc-item[open] {
  border-color: color-mix(in oklab, var(--accent) 22%, var(--border));
  box-shadow: var(--shadow-sm);
}
.tech-acc-item > summary {
  cursor: pointer;
  list-style: none;
  padding: 16px 18px;
  font-weight: 650;
  letter-spacing: -0.015em;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.tech-acc-item > summary::-webkit-details-marker { display: none; }
.tech-acc-item > summary::after {
  content: "+";
  flex: none;
  color: var(--accent);
  font-size: 1.25rem;
  font-weight: 500;
  line-height: 1;
}
.tech-acc-item[open] > summary::after { content: "–"; }
.tech-acc-body {
  overflow: hidden;
  height: 0;
  transition: height 0.32s var(--ease);
}
.tech-acc-item[open] > .tech-acc-body {
  /* height driven by JS; border lives on the inner pad */
}
.tech-acc-body-inner {
  padding: 4px 18px 20px;
  border-top: 1px solid var(--border);
}
.tech-acc-body-inner > p {
  color: var(--text-2);
  max-width: 62ch;
  margin: 16px 0 0;
}
.tech-acc-body-inner > p:first-child { margin-top: 16px; }
@media (prefers-reduced-motion: reduce) {
  .tech-acc-body { transition: none; }
}
.pipeline-bare .stack { margin-top: var(--s5); }

.thanks {
  padding: clamp(64px, 12vw, 120px) var(--pad);
  text-align: center;
}
.thanks-inner { max-width: 640px; margin: 0 auto; }
.thanks h1 {
  margin: 0 0 var(--s4);
  font-size: clamp(1.6rem, 1.2rem + 2vw, 2.4rem);
  letter-spacing: -0.035em;
}
.thanks-lede { color: var(--text-2); margin: 0 0 var(--s6); }
.thanks .cta { justify-content: center; }

.sticky-cta {
  display: none;
}
@media (max-width: 720px) {
  .sticky-cta:not([hidden]) {
    display: flex;
    position: fixed;
    left: 12px;
    right: 12px;
    bottom: calc(12px + env(safe-area-inset-bottom, 0px));
    z-index: 40;
    gap: 8px;
    padding: 8px;
    border-radius: 999px;
    background: color-mix(in oklab, var(--surface) 92%, transparent);
    border: 1px solid var(--border-strong);
    box-shadow: var(--shadow-lg);
    backdrop-filter: blur(10px);
  }
  .sticky-cta__trial {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    border-radius: 999px;
    background: var(--accent);
    color: #fff;
    font-weight: 650;
    font-size: var(--t-sm);
    text-decoration: none;
  }
  .sticky-cta__wa {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: #0e7a6e;
    color: #fff;
    flex-shrink: 0;
  }
  body { padding-bottom: 72px; }
  .ask-band-inner { grid-template-columns: 1fr; }
  .who-grid { grid-template-columns: 1fr; }
  .lahore-inner { flex-direction: column; align-items: flex-start; }
}

/* -------------------------------------------------------------- site chat */

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0);
  white-space: nowrap; border: 0;
}

.magy-chat {
  position: fixed;
  z-index: 55;
  right: max(16px, env(safe-area-inset-right));
  left: auto;
  bottom: max(16px, env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 12px;
  font-family: var(--font-body);
  max-width: calc(100vw - 32px);
}
@media (max-width: 720px) {
  .magy-chat { bottom: max(84px, calc(72px + env(safe-area-inset-bottom))); }
}
.magy-chat-launch {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 11px 16px 11px 11px;
  border: 0;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font: inherit;
  font-weight: 650;
  font-size: var(--t-sm);
  cursor: pointer;
  box-shadow: 0 14px 30px -12px color-mix(in oklab, var(--accent) 70%, transparent);
  transition: transform var(--motion) var(--ease), box-shadow var(--motion) var(--ease);
}
.magy-chat.is-open .magy-chat-launch { display: none; }
.magy-chat-launch:hover { transform: translateY(-1px); }
.magy-chat-launch-ic {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: rgb(255 255 255 / .18);
}
.magy-chat-launch-ic svg { width: 18px; height: 18px; }

.magy-chat-panel {
  width: min(420px, calc(100vw - 24px));
  height: min(640px, calc(100vh - 100px));
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: 22px;
  background: #fff;
  box-shadow:
    0 1px 0 rgb(255 255 255 / .7) inset,
    0 28px 60px -28px rgb(18 18 24 / .45);
  overflow: hidden;
}
.magy-chat-panel[hidden] { display: none !important; }

.magy-chat-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  background: #fff;
}
.magy-chat-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.magy-chat-mark {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 8px;
  background: linear-gradient(145deg, color-mix(in oklab, var(--accent) 75%, #fff), var(--accent-ink));
  color: #fff;
  flex: none;
}
.magy-chat-mark svg { width: 16px; height: 16px; }
.magy-chat-brand strong {
  display: block;
  font-family: var(--font-display);
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
  text-transform: none;
}
.magy-chat-brand span {
  display: block;
  color: var(--muted);
  font-size: 0.72rem;
  line-height: 1.2;
}
.magy-chat-head-actions {
  display: flex;
  align-items: center;
  gap: 4px;
}
.magy-chat-iconbtn {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--text-2);
  cursor: pointer;
}
.magy-chat-iconbtn:hover {
  background: var(--bg-2);
  color: var(--text);
}
.magy-chat-iconbtn svg { width: 16px; height: 16px; }

.magy-chat-tip {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 0;
  padding: 10px 14px;
  background: color-mix(in oklab, var(--accent-wash) 80%, #fff);
  color: var(--text-2);
  font-size: var(--t-micro);
  line-height: 1.45;
  border-bottom: 1px solid color-mix(in oklab, var(--accent) 10%, var(--border));
}
.magy-chat-tip a {
  color: var(--accent-ink);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.magy-chat-tip b { color: var(--accent-ink); font-weight: 650; }
.magy-chat-tip-ic {
  flex: none;
  margin-top: 1px;
  color: var(--accent);
}
.magy-chat-tip-ic svg { width: 14px; height: 14px; display: block; }

.magy-chat-log {
  flex: 1;
  overflow: auto;
  padding: 18px 18px 10px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  background: #fff;
}
.magy-chat-msg {
  max-width: 100%;
  font-size: 0.92rem;
  line-height: 1.55;
  color: var(--text);
  white-space: pre-wrap;
}
.magy-chat-msg--bot {
  align-self: stretch;
}
.magy-chat-msg--user {
  align-self: flex-end;
  max-width: 88%;
  padding: 10px 14px;
  border-radius: 16px 16px 4px 16px;
  background: var(--bg-2);
  border: 1px solid var(--border);
  color: var(--text);
}
.magy-chat-msg--thinking {
  color: var(--muted);
  font-style: italic;
}
.magy-chat-msg-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 8px;
  color: var(--muted);
  font-size: 0.7rem;
}
.magy-chat-msg-meta button {
  border: 0;
  background: transparent;
  color: inherit;
  padding: 2px;
  cursor: pointer;
  display: grid;
  place-items: center;
  border-radius: 6px;
}
.magy-chat-msg-meta button:hover {
  color: var(--text);
  background: var(--bg-2);
}
.magy-chat-msg-meta svg { width: 14px; height: 14px; }

.magy-chat-composer-wrap {
  padding: 10px 12px 6px;
  background: #fff;
}
.magy-chat-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px 12px 10px;
  border: 1px solid var(--border-strong);
  border-radius: 18px;
  background: #fafafa;
  box-shadow: var(--shadow-xs);
  transition: border-color var(--motion) var(--ease), box-shadow var(--motion) var(--ease);
}
.magy-chat-form:focus-within {
  border-color: color-mix(in oklab, var(--accent) 35%, var(--border));
  box-shadow: var(--ring);
  background: #fff;
}
.magy-chat-form textarea {
  width: 100%;
  min-height: 52px;
  max-height: 120px;
  resize: none;
  border: 0;
  outline: none;
  background: transparent;
  font: inherit;
  font-size: 0.95rem;
  line-height: 1.45;
  color: var(--text);
  padding: 2px 4px;
}
.magy-chat-form-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.magy-chat-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  min-width: 0;
}
.magy-chat-chip {
  border: 1px solid var(--border);
  border-radius: 999px;
  background: #fff;
  color: var(--text-2);
  font: inherit;
  font-size: 0.72rem;
  font-weight: 600;
  padding: 5px 10px;
  cursor: pointer;
  white-space: nowrap;
}
.magy-chat-chip:hover {
  border-color: color-mix(in oklab, var(--accent) 30%, var(--border));
  color: var(--accent-ink);
  background: var(--accent-wash);
}
.magy-chat-send {
  flex: none;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: 50%;
  background:
    linear-gradient(#fff, #fff) padding-box,
    linear-gradient(135deg, var(--accent), #7a8cff) border-box;
  border: 2px solid transparent;
  color: var(--accent-ink);
  cursor: pointer;
  box-shadow: 0 8px 18px -12px color-mix(in oklab, var(--accent) 55%, transparent);
}
.magy-chat-send:hover { color: var(--accent); }
.magy-chat-send:disabled { opacity: 0.45; cursor: default; }
.magy-chat-send svg { width: 18px; height: 18px; }

.magy-chat-foot {
  margin: 0;
  padding: 4px 16px 12px;
  text-align: center;
  color: var(--muted);
  font-size: 0.68rem;
  line-height: 1.35;
}
.magy-chat-meta {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .magy-chat-launch { transition: none; }
  .magy-chat-launch:hover { transform: none; }
}
