/* Flai: the site's stylesheet. Lifted whole out of index.html so the demo
 page can share it not carry a second copy of the nav, the footer
 and every token. */

/* IvyPresto Headline, subset to Latin (261 of 764 glyphs, 90 KB -> 25 KB).
 The full weight ships alongside as a file; swap the src if the copy ever
 needs glyphs outside Latin. */
@font-face{
  font-family:"IvyPresto Headline";
  src:url("assets/img/ivypresto-headline.woff2") format("woff2");
  font-weight:400;
  font-style:normal;
  font-display:swap;
}

/* =========================================================================
 FLAI: landing Figma: Website Playground / UI Design (node 107:7) ASSETS
 Every asset lives in the --a-* block below. */

:root{
  /* --- assets: nav + hero --- */
  --a-logo:url("assets/img/logo.svg");
  --a-cta-arrow:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTEiIGhlaWdodD0iMTgiIHZpZXdCb3g9IjAgMCAxMSAxOCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNS4wMDUyIDE0Ljg0NzJWMThIMFYxNS4zODQ4QzEuNjc3MDQgMTUuMjQ4MyAzLjM0NTYgMTUuMDY5OSA1LjAwNTIgMTQuODQ3N1YxNC44NDcyWk0wLjAwMDk5NzQzIDYuNzM5MDRWMTAuMDQzM0MzLjUxMDAyIDguNjg5MTEgNi45MDU5NCA3LjE1MjU3IDEwLjE0NzkgNS40MDU3OFYwQzYuOTgzMTcgMi40OTMxNCAzLjU2NjMyIDQuNzI3MTkgMC4wMDA5OTc0MyA2LjczOTU0VjYuNzM5MDRaTTAuMDAwOTk3NDMgMTEuMjAzN1YxNC4wOTE5QzMuNDUwNzMgMTMuNTU2MyA2Ljg0NjY1IDEyLjg0NzggMTAuMTQ3OSAxMS45NDhWNy42NjQ3NUM2LjczNjA1IDguODg2NCAzLjM3MTUxIDEwLjE0MDkgMC4wMDA5OTc0MyAxMS4yMDM3WiIgZmlsbD0iI0ZBMDc0MSIvPjwvc3ZnPg==");
  /* generated: the dot frit off a car window. Replaces the raster overlay so
 the colour is ours, it scales cleanly, and it dissolves instead of cutting */


  /* --- assets: brand marks --- */

  /* --- assets: statement band --- */

  /* --- assets: feature --- */

  /* TODO: 8 of the tokens below point at figma.com asset URLs, which
     expire. Export each one and move it into assets/img/. */
  --a-feature-photo:url("https://www.figma.com/api/mcp/asset/9186b2f2-f5e3-4993-8780-51b294f159dd.png");
  --a-send:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHJ4PSIxNiIgZmlsbD0iI0NFRThFQiIvPjxyZWN0IHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgcng9IjE2IiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfMTA3XzIxNikiLz48cmVjdCB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHJ4PSIxNiIgZmlsbD0idXJsKCNwYWludDFfbGluZWFyXzEwN18yMTYpIi8+PHBhdGggZD0iTTE1LjczOTMgMjEuNDM2NlYyNC43OTk2SDEwLjQwMDRWMjIuMDEwMUMxMi4xODkyIDIxLjg2NDQgMTMuOTY5IDIxLjY3NDIgMTUuNzM5MyAyMS40MzcyVjIxLjQzNjZaTTEwLjQwMTUgMTIuNzg3OVYxNi4zMTI1QzE0LjE0NDQgMTQuODY4IDE3Ljc2NjcgMTMuMjI5IDIxLjIyNDggMTEuMzY1OFY1LjU5OTYxQzE3Ljg0OTEgOC4yNTg5NSAxNC4yMDQ1IDEwLjY0MTkgMTAuNDAxNSAxMi43ODg0VjEyLjc4NzlaTTEwLjQwMTUgMTcuNTUwMlYyMC42MzFDMTQuMDgxMiAyMC4wNTk3IDE3LjcwMzUgMTkuMzA0IDIxLjIyNDggMTguMzQ0MlYxMy43NzUzQzE3LjU4NTUgMTUuMDc4NCAxMy45OTY3IDE2LjQxNjYgMTAuNDAxNSAxNy41NTAyWiIgZmlsbD0iIzFBMEQwRCIvPjxkZWZzPjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl8xMDdfMjE2IiB4MT0iMC43NDI2MTciIHkxPSItMi4wMDA3MWUtMDYiIHgyPSI0MS4wNTIzIiB5Mj0iMTUuMzM3MyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPjxzdG9wIHN0b3AtY29sb3I9IiNGQTA3NDEiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMxQTBEMEQiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQxX2xpbmVhcl8xMDdfMjE2IiB4MT0iMTYiIHkxPSIyOC4zMjU5IiB4Mj0iMTYiIHkyPSItMC4xMTg1MTgiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj48c3RvcCBzdG9wLWNvbG9yPSJ3aGl0ZSIvPjxzdG9wIG9mZnNldD0iMC4zOCIgc3RvcC1jb2xvcj0iI0RERUNFRiIvPjxzdG9wIG9mZnNldD0iMC43NyIgc3RvcC1jb2xvcj0iI0MyRENFMiIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0I4RDdERSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjwvc3ZnPg==");
  /* The bullet for the three checked lists: the service panels, the sales
 modules and the FAQ. Embedded byte for byte as supplied. */
  --a-check:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTcuMzk4NDcgMEwzLjA5Mzk0IDE2SDJMNi4zMDQ1MyAwSDcuMzk4NDdaIiBmaWxsPSIjRkEwNzQxIi8+CjxwYXRoIGQ9Ik0xNC4xNTYzIDBMOS44NTE3NSAxNkg4Ljc1NzgxTDEzLjA2MjMgMEgxNC4xNTYzWiIgZmlsbD0iI0ZBMDc0MSIvPgo8L3N2Zz4K");

  /* --- assets: marquee --- */

  /* --- assets: case studies --- */
  --a-eyebrow-icon:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTciIGhlaWdodD0iMTciIHZpZXdCb3g9IjAgMCAxNyAxNyIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNOC44NTkyIDAuMTI4OTA2TDcuMzk4NDQgMy42MTIwNCIgc3Ryb2tlPSIjMUEwRDBEIiBzdHJva2Utd2lkdGg9IjAuNjY2NjY3IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz48cGF0aCBkPSJNOC44NTkyIDEyLjY0NThMNy4zOTg0NCAxNi4xMjg5IiBzdHJva2U9IiMxQTBEMEQiIHN0cm9rZS13aWR0aD0iMC42NjY2NjciIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPjxwYXRoIGQ9Ik0xNi4xMjkgOC44NTkxOUwxMi42NDQ1IDcuMzk4NDQiIHN0cm9rZT0iIzFBMEQwRCIgc3Ryb2tlLXdpZHRoPSIwLjY2NjY2NyIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+PHBhdGggZD0iTTMuNjEyMDQgOC44NTkxOUwwLjEyODkwNiA3LjM5ODQ0IiBzdHJva2U9IiMxQTBEMEQiIHN0cm9rZS13aWR0aD0iMC42NjY2NjciIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPjxwYXRoIGQ9Ik0xMy4yNjg2IDE0LjMwMjFMMTEuODM3OSAxMC44MDY2IiBzdHJva2U9IiMxQTBEMEQiIHN0cm9rZS13aWR0aD0iMC42NjY2NjciIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPjxwYXRoIGQ9Ik00LjQxODk5IDUuNDUxMjRMMi45ODgyOCAxLjk1NTgxIiBzdHJva2U9IiMxQTBEMEQiIHN0cm9rZS13aWR0aD0iMC42NjY2NjciIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPjxwYXRoIGQ9Ik0xLjk1NTA4IDEzLjI2ODhMNS40NTE4NyAxMS44MzgxIiBzdHJva2U9IiMxQTBEMEQiIHN0cm9rZS13aWR0aD0iMC42NjY2NjciIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPjxwYXRoIGQ9Ik0xMC44MDQ3IDQuNDE4MzRMMTQuMzAxNSAyLjk4OTAxIiBzdHJva2U9IiMxQTBEMEQiIHN0cm9rZS13aWR0aD0iMC42NjY2NjciIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPjwvc3ZnPg==");
  --a-case-1:url("https://www.figma.com/api/mcp/asset/745f3905-356a-4ab4-821e-646af9944aa9.png");
  --a-case-2:url("https://www.figma.com/api/mcp/asset/d9b6e751-87b9-4a08-bf98-87727aad8daa.png");
  /* card 3 was the hover mock-up in Figma (red wash + cursor); it is a
 photograph like the other three, cropped to 564:491 and encoded at 2x */
  --a-case-3:url("assets/img/case-3.webp");
  --a-case-4a:url("https://www.figma.com/api/mcp/asset/88f0a74a-f77d-4aff-b8a3-3c04378e7c79.png");
  --a-case-4b:url("https://www.figma.com/api/mcp/asset/e52d6cb4-582a-485a-9e41-37ad22f51fc3.png");

  --a-ps-bg:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTQ0MCIgaGVpZ2h0PSI4OTQiIHZpZXdCb3g9IjAgMCAxNDQwIDg5NCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBjbGlwLXBhdGg9InVybCgjY2xpcDBfMzE2XzgzKSI+PHJlY3Qgd2lkdGg9IjE0NDAiIGhlaWdodD0iODk0IiBmaWxsPSIjQ0VFOEVCIi8+PHBhdGggZD0iTTE0NDAgLTI1NVYtMTI1LjdDOTkxLjkgMTU0LjMgNTA3LjMgMzg5LjkgMSA1ODkuMlYyNjYuNEMzMjMuNiA4Mi45IDYzNSAtMTE3LjkgOTI3LjEgLTMzOUgxMzU2QzE0MDIuNCAtMzM5IDE0NDAgLTMwMS40IDE0NDAgLTI1NVpNMTQ0MCAxNjkuNUM5ODYuMyA0MDguMiA1MDAuMSA1OTguMyAxIDc1MS41VjEwMzQuMUM0OTUuMiA5NTIuOSA5NzguMSA4MzguNCAxNDQwIDY4Mi4zVjE2OS41VjE2OS41Wk0xIDExODUuMlYxNDYwSDU4OS45VjExMTQuNkMzOTQuOSAxMTQ0LjIgMTk4LjIgMTE2Ny40IDEgMTE4NS4yWiIgZmlsbD0idXJsKCNwYWludDBfbGluZWFyXzMxNl84MykiLz48L2c+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzMxNl84MyIgeDE9IjEiIHkxPSI1NjAuNSIgeDI9IjE0NDAiIHkyPSI1NjAuNSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPjxzdG9wIHN0b3AtY29sb3I9IndoaXRlIiBzdG9wLW9wYWNpdHk9IjAiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IndoaXRlIiBzdG9wLW9wYWNpdHk9IjAuNCIvPjwvbGluZWFyR3JhZGllbnQ+PGNsaXBQYXRoIGlkPSJjbGlwMF8zMTZfODMiPjxyZWN0IHdpZHRoPSIxNDQwIiBoZWlnaHQ9Ijg5NCIgZmlsbD0id2hpdGUiLz48L2NsaXBQYXRoPjwvZGVmcz48L3N2Zz4=");
  --a-bl-solera:url("assets/img/bl-solera.png");
  --a-bl-autolive:url("assets/img/bl-autolive.png");
  --a-bl-updatepromise:url("assets/img/bl-updatepromise.png");
  --a-bl-vinsolutions:url("assets/img/bl-vinsolutions.png");
  /* --- assets: hero --- */
  --a-sales-1:url("assets/sales-1.webp");
  --a-sales-2:url("assets/sales-2.webp");
  --a-sales-3:url("assets/sales-3.webp");
  --a-sales-4:url("assets/sales-4.webp");
  --a-sales-av:url("https://www.figma.com/api/mcp/asset/72ded769-a571-43cd-acff-215a9c676810/8f21c.png");
  --a-panel-calls:url("assets/img/panel-calls.webp");
  --a-panel-retention:url("https://www.figma.com/api/mcp/asset/1892fd37-54d8-4e60-811c-215519b692eb/57bd7.png");
  --a-panel-intel:url("https://www.figma.com/api/mcp/asset/58afd6d8-8ec3-49ee-a985-cf70474c5881/01237.png");
  --a-sales-fx-1:url("assets/img/sales-fx-1.svg");
  --a-linkedin:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI2ZmZiI+PHBhdGggZD0iTTIwLjQ1IDIwLjQ1aC0zLjU2di01LjU3YzAtMS4zMy0uMDMtMy4wNC0xLjg1LTMuMDQtMS44NiAwLTIuMTQgMS40NS0yLjE0IDIuOTR2NS42N0g5LjM1VjloMy40MXYxLjU2aC4wNWEzLjc0IDMuNzQgMCAwIDEgMy4zNy0xLjg1YzMuNiAwIDQuMjcgMi4zNyA0LjI3IDUuNDZ2Ni4yOFpNNS4zNCA3LjQzYTIuMDYgMi4wNiAwIDEgMSAwLTQuMTMgMi4wNiAyLjA2IDAgMCAxIDAgNC4xM1pNNy4xMiAyMC40NUgzLjU2VjloMy41NnYxMS40NVpNMjIuMjIgMEgxLjc3Qy43OSAwIDAgLjc3IDAgMS43MnYyMC41NkMwIDIzLjIzLjc5IDI0IDEuNzcgMjRoMjAuNDVjLjk4IDAgMS43OC0uNzcgMS43OC0xLjcyVjEuNzJDMjQgLjc3IDIzLjIgMCAyMi4yMiAwWiIvPjwvc3ZnPg==");
  /* the diagonal mark, used on the demo page and behind the blog's lead */
  --a-bd-pattern:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTEzMCIgaGVpZ2h0PSIxNDEyIiB2aWV3Qm94PSIwIDAgMTEzMCAxNDEyIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8cGF0aCBkPSJNMTEzMCA2NS45MDc1VjE2Ny4zODVDNzc4LjEzOSAzODcuMjAyIDM5Ny42MDYgNTcyLjEzMyAwIDcyOC41MzlWNDc1LjIwNEMyNTMuMzI0IDMzMS4xNzkgNDk3Ljg1NCAxNzMuNTQyIDcyNy4yNjIgMEgxMDY0LjA3QzExMDAuNDcgMCAxMTMwIDI5LjUxNjUgMTEzMCA2NS45MDc1Wk0xMTMwIDM5OS4xMDRDNzczLjc1OSA1ODYuNDk4IDM5MS44OTIgNzM1LjY1MyAwIDg1NS45NDJWMTA3Ny43NEMzODguMDYgMTAxMy45OSA3NjcuMjU5IDkyNC4xMDcgMTEzMCA4MDEuNTk1VjM5OS4xMzlWMzk5LjEwNFpNMCAxMTk2LjI5VjE0MTJINDYyLjQ0MlYxMTQwLjg4QzMwOS4yOTkgMTE2NC4xIDE1NC44NTQgMTE4Mi4zNyAwIDExOTYuMjlaIiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfNDk4Xzk4KSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzQ5OF85OCIgeDE9IjE3MSIgeTE9IjkwMC41IiB4Mj0iODIxIiB5Mj0iNDcyLjUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzJBMTExMSIgc3RvcC1vcGFjaXR5PSIwIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzJBMTExMSIgc3RvcC1vcGFjaXR5PSIwLjgiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4=");
  --a-hero-photo:url("assets/hero-poster.jpg");   /* a frame of the hero film */
  /* The caller's face, in the hero and in every Service composition. Both of
 these pointed at figma.com remote links that nothing on this page can reach. */
  --a-hero-av-1:url("assets/img/av-caller.webp");
  --a-hero-av-2:url("assets/img/av-caller.webp");
  /* The dealer wall: eighteen marks, each drawn into the same 240x112 canvas
 by the studio, so one common box here reproduces the sizing they were
 given not flattening them all to one height. */
  --a-dl-alpine:url("assets/img/dl-alpine.webp");
  --a-dl-cardinale:url("assets/img/dl-cardinale.webp");
  --a-dl-carter:url("assets/img/dl-carter.webp");
  --a-dl-fifth-wave:url("assets/img/dl-fifth-wave.webp");
  --a-dl-findlay:url("assets/img/dl-findlay.webp");
  --a-dl-freeman:url("assets/img/dl-freeman.webp");
  /* Inline: it is read as a CSS mask, and a mask obeys same-origin, which a
 page opened straight off disk cannot satisfy. 230 bytes. */
  --a-arrow:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTkgMTNMMTQgOEw5IDNNMTQgOEgyIiBzdHJva2U9ImJsYWNrIiBzdHJva2Utd2lkdGg9IjEuNiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cjwvc3ZnPg==");
  --a-dl-gomez:url("assets/img/dl-gomez.webp");
  --a-dl-hiley:url("assets/img/dl-hiley.webp");
  --a-dl-hudson:url("assets/img/dl-hudson.webp");
  --a-dl-indigo:url("assets/img/dl-indigo.webp");
  --a-dl-jn:url("assets/img/dl-jn.webp");
  --a-dl-kahlig:url("assets/img/dl-kahlig.webp");
  --a-dl-mountainwest:url("assets/img/dl-mountainwest.webp");
  --a-dl-premier:url("assets/img/dl-premier.webp");
  --a-dl-price:url("assets/img/dl-price.webp");
  --a-dl-servco:url("assets/img/dl-servco.webp");

  /* --- assets: the Listen window chrome --- */
  --a-w-bell:url("data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiB3aWR0aD0iMTQiIGhlaWdodD0iMTQiIHZpZXdCb3g9IjAgMCAxNCAxNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNS4zMyA5Ljk2QzYuNDQgMTAuMSA3LjU2IDEwLjEgOC42NyA5Ljk2QzkuNzUgOS44NCAxMC44MiA5LjU4IDExLjg1IDkuMkMxMC45OCA4LjI0IDEwLjUgNi45OSAxMC41IDUuNjlWNS4yNUMxMC41IDQuMzIgMTAuMTMgMy40MyA5LjQ3IDIuNzhDOC44MiAyLjEyIDcuOTMgMS43NSA3IDEuNzVDNi4wNyAxLjc1IDUuMTggMi4xMiA0LjUyIDIuNzhDMy44NyAzLjQzIDMuNSA0LjMyIDMuNSA1LjI1VjUuNjlDMy41IDYuOTkgMy4wMiA4LjI0IDIuMTUgOS4yQzMuMTYgOS41NyA0LjIzIDkuODMgNS4zMyA5Ljk2Wk04LjY3IDkuOTZDOC43NSAxMC4yMyA4Ljc3IDEwLjUxIDguNzMgMTAuNzhDOC42OCAxMS4wNSA4LjU4IDExLjMxIDguNDEgMTEuNTNDOC4yNSAxMS43NSA4LjA0IDExLjkzIDcuNzkgMTIuMDZDNy41NSAxMi4xOCA3LjI3IDEyLjI1IDcgMTIuMjVDNi43MiAxMi4yNSA2LjQ1IDEyLjE4IDYuMjEgMTIuMDZDNS45NiAxMS45MyA1Ljc1IDExLjc1IDUuNTkgMTEuNTNDNS40MiAxMS4zMSA1LjMyIDExLjA1IDUuMjcgMTAuNzhDNS4yMyAxMC41MSA1LjI1IDEwLjIzIDUuMzMgOS45NiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+PC9zdmc+");
  --a-w-gear:url("assets/img/w-gear.svg");
  --a-w-mark:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTEiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAxMSAyMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNS4zNCAxNS44NFYxOS4ySDBWMTYuNDFDMS43OSAxNi4yNiAzLjU3IDE2LjA3IDUuMzQgMTUuODRWMTUuODRaTTAgNy4xOVYxMC43MUMzLjc0IDkuMjcgNy4zNyA3LjYzIDEwLjgyIDUuNzdWMEM3LjQ1IDIuNjYgMy44IDUuMDQgMCA3LjE5VjcuMTlaTTAgMTEuOTVWMTUuMDNDMy42OCAxNC40NiA3LjMgMTMuNyAxMC44MiAxMi43NFY4LjE4QzcuMTkgOS40OCAzLjYgMTAuODIgMCAxMS45NVoiIGZpbGw9IndoaXRlIi8+PC9zdmc+");
  --a-w-r1:url("data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiB3aWR0aD0iMTUiIGhlaWdodD0iMTUiIHZpZXdCb3g9IjAgMCAxNSAxNSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNC41IDguNTVWOS45TTYuMyA3LjJWOS45TTguMSA1Ljg1VjkuOU05LjkgNC41VjkuOU0zLjYgMTIuMTVIMTAuOEMxMS4xNiAxMi4xNSAxMS41IDEyLjAxIDExLjc1IDExLjc1QzEyLjAxIDExLjUgMTIuMTUgMTEuMTYgMTIuMTUgMTAuOFYzLjZDMTIuMTUgMy4yNCAxMi4wMSAyLjkgMTEuNzUgMi42NUMxMS41IDIuMzkgMTEuMTYgMi4yNSAxMC44IDIuMjVIMy42QzMuMjQgMi4yNSAyLjkgMi4zOSAyLjY1IDIuNjVDMi4zOSAyLjkgMi4yNSAzLjI0IDIuMjUgMy42VjEwLjhDMi4yNSAxMS4xNiAyLjM5IDExLjUgMi42NSAxMS43NUMyLjkgMTIuMDEgMy4yNCAxMi4xNSAzLjYgMTIuMTVaIiBzdHJva2U9IndoaXRlIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz48L3N2Zz4=");
  --a-w-r2:url("data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiB3aWR0aD0iMTQiIGhlaWdodD0iMTQiIHZpZXdCb3g9IjAgMCAxNCAxNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMS4zMSA3Ljg4SDMuNTZDMy44MSA3Ljg4IDQuMDUgNy45NCA0LjI1IDguMDdDNC40NiA4LjIgNC42MyA4LjM4IDQuNzQgOC42TDQuODkgOC45QzUgOS4xMiA1LjE2IDkuMyA1LjM3IDkuNDNDNS41OCA5LjU2IDUuODIgOS42MyA2LjA2IDkuNjNINy45NEM4LjE4IDkuNjMgOC40MiA5LjU2IDguNjMgOS40M0M4Ljg0IDkuMyA5IDkuMTIgOS4xMSA4LjlMOS4yNiA4LjZDOS4zNyA4LjM4IDkuNTQgOC4yIDkuNzUgOC4wN0M5Ljk1IDcuOTQgMTAuMTkgNy44NyAxMC40NCA3Ljg4SDEyLjY5TTEuMzEgOC4wN1YxMC41QzEuMzEgMTAuODUgMS40NSAxMS4xOCAxLjcgMTEuNDNDMS45NCAxMS42NyAyLjI4IDExLjgxIDIuNjMgMTEuODFIMTEuMzhDMTEuNzIgMTEuODEgMTIuMDYgMTEuNjcgMTIuMyAxMS40M0MxMi41NSAxMS4xOCAxMi42OSAxMC44NSAxMi42OSAxMC41VjguMDdDMTIuNjkgNy45NCAxMi42NyA3LjgxIDEyLjYzIDcuNjlMMTEuMjIgMy4xMUMxMS4xNCAyLjg1IDEwLjk3IDIuNjEgMTAuNzUgMi40NEMxMC41MiAyLjI4IDEwLjI1IDIuMTkgOS45NyAyLjE5SDQuMDNDMy43NSAyLjE5IDMuNDggMi4yOCAzLjI1IDIuNDRDMy4wMyAyLjYxIDIuODYgMi44NSAyLjc4IDMuMTFMMS4zNyA3LjY5QzEuMzMgNy44MSAxLjMxIDcuOTQgMS4zMSA4LjA3WiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+PC9zdmc+");
  --a-w-r3:url("data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiB3aWR0aD0iMTQiIGhlaWdodD0iMTQiIHZpZXdCb3g9IjAgMCAxNCAxNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMS4zMSAzLjk0QzEuMzEgOC43NyA1LjIzIDEyLjY5IDEwLjA2IDEyLjY5SDExLjM4QzExLjcyIDEyLjY5IDEyLjA2IDEyLjU1IDEyLjMgMTIuM0MxMi41NSAxMi4wNiAxMi42OSAxMS43MiAxMi42OSAxMS4zOFYxMC41N0MxMi42OSAxMC4yNyAxMi40OCAxMC4wMSAxMi4xOSA5Ljk0TDkuNjEgOS4yOUM5LjM1IDkuMjMgOS4wOCA5LjMzIDguOTMgOS41NEw4LjM2IDEwLjI5QzguMiAxMC41MSA3LjkxIDEwLjYxIDcuNjUgMTAuNTFDNi43IDEwLjE2IDUuODMgOS42MSA1LjExIDguODlDNC4zOSA4LjE3IDMuODQgNy4zIDMuNDkgNi4zNUMzLjM5IDYuMDkgMy40OSA1LjggMy43MSA1LjY0TDQuNDYgNS4wN0M0LjY4IDQuOTIgNC43NyA0LjY1IDQuNzEgNC4zOUw0LjA2IDEuODFDNC4wMyAxLjY3IDMuOTQgMS41NCAzLjgzIDEuNDVDMy43MSAxLjM2IDMuNTcgMS4zMSAzLjQzIDEuMzFIMi42M0MyLjI4IDEuMzEgMS45NCAxLjQ1IDEuNyAxLjdDMS40NSAxLjk0IDEuMzEgMi4yOCAxLjMxIDIuNjNWMy45NFoiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPjwvc3ZnPg==");
  --a-w-r4:url("data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiB3aWR0aD0iMTQiIGhlaWdodD0iMTQiIHZpZXdCb3g9IjAgMCAxNCAxNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMy45NCAxLjc1VjMuMDZNMTAuMDYgMS43NVYzLjA2TTEuNzUgMTAuOTRWNC4zOEMxLjc1IDQuMDMgMS44OSAzLjY5IDIuMTMgMy40NUMyLjM4IDMuMiAyLjcxIDMuMDYgMy4wNiAzLjA2SDEwLjk0QzExLjI5IDMuMDYgMTEuNjIgMy4yIDExLjg3IDMuNDVDMTIuMTEgMy42OSAxMi4yNSA0LjAzIDEyLjI1IDQuMzhWMTAuOTRNMTIuMjUgMTAuOTRWNi41NkMxMi4yNSA2LjIxIDEyLjExIDUuODggMTEuODcgNS42M0MxMS42MiA1LjM5IDExLjI5IDUuMjUgMTAuOTQgNS4yNUgzLjA2QzIuNzEgNS4yNSAyLjM4IDUuMzkgMi4xMyA1LjYzQzEuODkgNS44OCAxLjc1IDYuMjEgMS43NSA2LjU2VjEwLjk0QzEuNzUgMTEuMjkgMS44OSAxMS42MiAyLjEzIDExLjg3QzIuMzggMTIuMTEgMi43MSAxMi4yNSAzLjA2IDEyLjI1SDEwLjk0QzExLjI5IDEyLjI1IDExLjYyIDEyLjExIDExLjg3IDExLjg3QzEyLjExIDExLjYyIDEyLjI1IDExLjI5IDEyLjI1IDEwLjk0WiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+PC9zdmc+");
  --a-w-r5:url("data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiB3aWR0aD0iMTQiIGhlaWdodD0iMTQiIHZpZXdCb3g9IjAgMCAxNCAxNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTEuMzggOC4zMVY2Ljc4QzExLjM4IDYuMjYgMTEuMTcgNS43NiAxMC44IDUuMzlDMTAuNDMgNS4wMiA5LjkzIDQuODEgOS40MSA0LjgxSDguNTNDOC4zNiA0LjgxIDguMTkgNC43NCA4LjA3IDQuNjJDNy45NCA0LjUgNy44OCA0LjMzIDcuODggNC4xNlYzLjI4QzcuODggMi43NiA3LjY3IDIuMjYgNy4zIDEuODlDNi45MyAxLjUyIDYuNDMgMS4zMSA1LjkxIDEuMzFINC44MU00LjgxIDguNzVIOS4xOU00LjgxIDEwLjVIN002LjEzIDEuMzFIMy4yOEMyLjkyIDEuMzEgMi42MyAxLjYxIDIuNjMgMS45N1YxMi4wM0MyLjYzIDEyLjM5IDIuOTIgMTIuNjkgMy4yOCAxMi42OUgxMC43MkMxMS4wOCAxMi42OSAxMS4zOCAxMi4zOSAxMS4zOCAxMi4wM1Y2LjU2QzExLjM4IDUuMTcgMTAuODIgMy44MyA5Ljg0IDIuODVDOC44NSAxLjg3IDcuNTIgMS4zMSA2LjEzIDEuMzFaIiBzdHJva2U9IndoaXRlIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz48L3N2Zz4=");

  --a-w-chev:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTQiIGhlaWdodD0iMTQiIHZpZXdCb3g9IjAgMCAxNCAxNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNC42IDUuNiA3IDMuMmwyLjQgMi40TTkuNCA4LjQgNyAxMC44IDQuNiA4LjQiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMS4xIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz48L3N2Zz4=");
  --a-w-find:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTQiIGhlaWdodD0iMTQiIHZpZXdCb3g9IjAgMCAxNCAxNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48Y2lyY2xlIGN4PSI2LjQiIGN5PSI2LjQiIHI9IjQuMSIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIxLjEiLz48cGF0aCBkPSJNOS41IDkuNSAxMiAxMiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIxLjEiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPjwvc3ZnPg==");
  --a-w-spark:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTIiIHZpZXdCb3g9IjAgMCAxMiAxMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNiAuOGMuMzYgMS44Ni44NiAzLjEgMS42IDMuODVDOC4zNCA1LjQgOS41IDUuODYgMTEuMiA2Yy0xLjcuMTQtMi44Ni42LTMuNiAxLjM1QzYuODYgOC4xIDYuMzYgOS4zNCA2IDExLjJjLS4zNi0xLjg2LS44Ni0zLjEtMS42LTMuODVDMy42NiA2LjYgMi41IDYuMTQuOCA2YzEuNy0uMTQgMi44Ni0uNiAzLjYtMS4zNUM1LjE0IDMuOSA1LjY0IDIuNjYgNiAuOFoiIGZpbGw9IndoaXRlIi8+PHBhdGggZD0iTTEwLjYgMS4xYy4xNi42Mi4zMyAxIC42MiAxLjItLjM0LjE0LS41Mi41LS42MiAxLjEtLjEtLjYtLjI4LS45Ni0uNjItMS4xLjI5LS4yLjQ2LS41OC42Mi0xLjJaIiBmaWxsPSJ3aGl0ZSIvPjwvc3ZnPg==");
  /* --- assets: built to connect --- */
  --a-orbits:url("assets/img/orbits.svg");
  --a-bl-cdk:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTgiIGhlaWdodD0iNTgiIHZpZXdCb3g9IjM1IDAgNTggNTgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTYzLjYgMjUuMUg2MS41VjMxLjJINjMuNkM2NC43IDMxLjIgNjUuMyAzMSA2NS44IDMwLjVDNjYuMyAyOS45IDY2LjcgMjkuMiA2Ni43IDI4LjJDNjYuNyAyNy4zIDY2LjQgMjYuNiA2NS44IDI2QzY1LjQgMjUuNSA2NC44IDI1LjEgNjMuNiAyNS4xWiIgZmlsbD0iIzFBMEQwRCIvPjxwYXRoIGQ9Ik02NCAwQzQ4LjQgMCAzNS44IDEyLjcgMzUuOCAyOC4yQzM1LjggNDMuNyA0OC40IDU2LjQgNjQgNTYuNEM3OS41IDU2LjQgOTIuMiA0My43IDkyLjIgMjguMkM5Mi4yIDEyLjcgNzkuNSAwIDY0IDBaTTUwLjkgMzQuMUM0Ny4xIDM0LjEgNDQuNyAzMS40IDQ0LjcgMjguMkM0NC43IDI1IDQ3LjIgMjIuMyA1MC44IDIyLjNDNTIuOCAyMi4zIDU0LjkgMjMuMSA1Ni4zIDI0LjNMNTQuNSAyNi4yQzUzLjUgMjUuMyA1Mi4xIDI0LjggNTEuMSAyNC44QzQ5LjEgMjQuOCA0Ny44IDI2LjQgNDcuOCAyOC4yQzQ3LjggMzAuMSA0OS4xIDMxLjYgNTEuMiAzMS42QzUyLjUgMzEuNiA1My45IDMwLjggNTQuOCAyOS45TDU2LjYgMzEuOEM1NS4zIDMzIDUzLjMgMzQuMSA1MC45IDM0LjFaTTY4LjIgMzIuMUM2Ny4yIDMzLjEgNjUuOCAzMy43IDYzLjYgMzMuN0g1OC41VjIyLjdINjMuNkM2NS43IDIyLjcgNjcuMiAyMy4yIDY4LjMgMjQuM0M2OS4yIDI1LjMgNjkuNyAyNi43IDY5LjcgMjguMkM2OS43IDI5LjcgNjkuMiAzMS4yIDY4LjIgMzIuMVpNODAuMiAzMy43TDc2LjUgMjlMNzUuMSAzMC4yVjMzLjdINzIuMVYyMi43SDc1LjFWMjYuOEw3OS41IDIyLjdIODMuMkw3OC41IDI3LjFMODMuOSAzMy43SDgwLjJaIiBmaWxsPSIjMUEwRDBEIi8+PC9zdmc+");
  --a-bl-dealerfx:url("assets/img/bl-dealerfx.svg");
  --a-bl-dr:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjEiIGhlaWdodD0iNjEiIHZpZXdCb3g9IjAgMCA2MSA2MSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMzAuMSA1OUM0NiA1OSA1OSA0Ni4xIDU5IDMwLjFDNTkgMTQuMSA0NiAxLjEgMzAuMSAxLjFDMTQuMSAxLjEgMS4yIDE0LjEgMS4yIDMwLjFDMS4yIDQ2LjEgMTQuMSA1OSAzMC4xIDU5WiIgZmlsbD0id2hpdGUiLz48cGF0aCBkPSJNMzAuMSAwQzEzLjUgMCAwIDEzLjUgMCAzMC4xQzAgNDYuNyAxMy41IDYwLjEgMzAuMSA2MC4xQzQ2LjcgNjAuMSA2MC4xIDQ2LjcgNjAuMSAzMC4xQzYwLjEgMTMuNSA0Ni43IDAgMzAuMSAwWk0yNC43IDQyLjRIOS4yTDEzLjIgMjguM0MxNCAyNS4yIDE2LjkgMjMgMjAuNSAyMi41SDI4TDI2LjQgMjguMUgyMEMxOS40IDI4LjEgMTguNyAyOC41IDE4LjUgMjkuMkwxNi4yIDM2LjlIMjQuOUMyNS44IDM2LjkgMjYuMiAzNi41IDI2LjQgMzUuOEwzMS43IDE2LjNIMzcuM0wzMS43IDM2LjlDMzAuOCA0MC43IDI3LjUgNDIuNCAyNC43IDQyLjRaTTMyLjggNDIuNEwzOS45IDE2LjZINDUuN0wzOS45IDM2LjlDMzkgNDAuNyAzNS43IDQyLjQgMzIuOCA0Mi40Wk01MC4zIDI4LjVINDQuOEw0Ni4zIDIzSDUxLjlMNTAuMyAyOC41WiIgZmlsbD0iIzFBMEQwRCIvPjwvc3ZnPg==");
  --a-bl-mykaarma:url("assets/img/bl-mykaarma.svg");
  --a-bl-reynolds:url("assets/img/bl-reynolds.svg");
  --a-bl-tekion:url("assets/img/bl-tekion.svg");
  --a-bl-vauto:url("assets/img/bl-vauto.svg");
  --a-bl-xtime:url("assets/img/bl-xtime.svg");

  /* The caller in the Listen conversation. It com
 asset URL those links are remote,
 they expire, and nothing on this page can reach them. */
  --a-caller:url("assets/img/av-caller.webp");
  /* The play mark from the button artwork, framed to the disc it sits in.
 Supplied as part of listen-to-flai.svg; the path is carried over
 unchanged and only the viewBox crops to it. */
  /* The two faces of the Listen control, as supplied: 20x20, drawn in ink,
 used as images on the white disc not as masks: nothing is
 recoloured, so they stay exactly what was handed over. */
  --a-listen-play:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuMzc1IDQuNzEwNDFDNC4zNzUgMy45OTcwOCA1LjEzOTE3IDMuNTQ1NDEgNS43NjQxNyAzLjg4ODc1TDE1LjM4MDggOS4xNzc5MUMxNS41MjggOS4yNTg3OCAxNS42NTA4IDkuMzc3NjkgMTUuNzM2MyA5LjUyMjI0QzE1LjgyMTggOS42NjY3OCAxNS44NjY5IDkuODMxNjQgMTUuODY2OSA5Ljk5OTU4QzE1Ljg2NjkgMTAuMTY3NSAxNS44MjE4IDEwLjMzMjQgMTUuNzM2MyAxMC40NzY5QzE1LjY1MDggMTAuNjIxNSAxNS41MjggMTAuNzQwNCAxNS4zODA4IDEwLjgyMTJMNS43NjQxNyAxNi4xMTA0QzUuNjIxNCAxNi4xODg5IDUuNDYwNjUgMTYuMjI4OCA1LjI5Nzc2IDE2LjIyNjNDNS4xMzQ4NiAxNi4yMjM3IDQuOTc1NDUgMTYuMTc4NyA0LjgzNTIyIDE2LjA5NThDNC42OTUgMTYuMDEyOSA0LjU3ODgxIDE1Ljg5NDggNC40OTgxMSAxNS43NTMzQzQuNDE3NDEgMTUuNjExOCA0LjM3NDk4IDE1LjQ1MTcgNC4zNzUgMTUuMjg4N1Y0LjcxMDQxWiIgZmlsbD0iIzFBMEQwRCIvPgo8L3N2Zz4=");
  --a-listen-pause:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEzLjEyNSA0LjM3NVYxNS42MjVNNi44NzUgNC4zNzVWMTUuNjI1IiBzdHJva2U9IiMxQTBEMEQiIHN0cm9rZS13aWR0aD0iMi41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPC9zdmc+");
  --a-play:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMiAxNCI+PHBhdGggZD0iTTExLjUgNi4xM2ExIDEgMCAwIDEgMCAxLjc0bC05Ljk4IDUuNzlBMSAxIDAgMCAxIDAgMTIuNzlWMS4yMUExIDEgMCAwIDEgMS41Mi4zNGw5Ljk4IDUuNzlaIiBmaWxsPSIjZmZmIi8+PC9zdmc+");

  /* --- assets: press marks in the footer --- */
  --a-press-tc:url("assets/img/press-tc.svg");
  --a-press-cdg:url("assets/img/press-cdg.svg");
  --a-press-an:url("assets/img/press-an.svg");

  /* --- assets: faq + footer (the eyebrow sparkle and red checker are reused) --- */
  --a-faq-minus:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTgiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxOCAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTYuMDAxNiA4LjhIMS42MDE1NiIgc3Ryb2tlPSIjMUEwRDBEIiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+PC9zdmc+");
  --a-faq-plus:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTgiIGhlaWdodD0iMTciIHZpZXdCb3g9IjAgMCAxOCAxNyIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNOC44IDEuNTk5NjFWMTUuOTk5NiIgc3Ryb2tlPSIjMUEwRDBEIiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+PHBhdGggZD0iTTE2LjAwMTYgOC44SDEuNjAxNTYiIHN0cm9rZT0iIzFBMEQwRCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPjwvc3ZnPg==");
  /* alpha mask of the wordmark: the letterforms are cut out of the light
 layers underneath, so a single moving element lights the whole logo */
  /* This one stays inline. It is consumed as a CSS mask, and a mask reads its
 source under same-origin rules: which a page opened straight off disk
 cannot satisfy, so as a file it silently stopped masking in local preview. */
  --a-footer-mask:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMzc2IDU3NiI+PHBhdGggZD0iTTE4NC41NjQgNTc0LjdDMTIzLjM0OSA1NzUuNjg3IDYxLjc4NTQgNTc0Ljc5OCAwIDU3Mi4xNzJWNDg4LjczOUM2MS44MTMyIDQ4My4zMzUgMTIzLjQzMiA0NzYuMTk0IDE4NC41NjQgNDY3LjA2NVY1NzQuN1pNMTA0Ny41MSAyMzkuNTU3QzExMTkuOSAyMzkuNTU3IDExNjAuODggMjg1LjMyMyAxMTYwLjg4IDM1OS43NjZWNDgzLjExNEMxMTYwLjg4IDUwNS42NSAxMTYwLjg5IDUyNi4xNDIgMTE4MC43IDUyNi4xNDNDMTE5MC4yNiA1MjYuMTQzIDExOTguNDUgNTIxLjM2MyAxMjAzLjkxIDUxNS44ODlMMTIxMy40NyA1MjQuNzY4TDEyMTMuNDYgNTI0Ljc4MUMxMjAyLjU0IDU0MS4xNzYgMTE3NC41MyA1NzMuOTUxIDExMjguNzggNTczLjk1MUMxMDg3LjExIDU3My45NTEgMTA3NS41MSA1NDYuNjM2IDEwNzIuMDkgNTIzLjQyQzEwNDcuNSA1NTQuMTUzIDEwMDUuODUgNTczLjk1MSA5NjYuOTE1IDU3My45NTFDOTE5Ljc4OCA1NzMuOTUxIDg4Ny4wMTIgNTQ1LjI3NSA4ODcuMDEyIDQ5OC44MjhDODg3LjAxMiA0NDYuMjQgOTI0LjU4IDQwNi42MjggMTAwNS4xNiAzODQuMDkzTDEwNjcuMzEgMzY2LjMzN0MxMDY3LjMxIDM0Ni45MTggMTA2Ny4wMiAyODUuMzIyIDEwMDMuOCAyODUuMzIyQzk2MS40NTUgMjg1LjMyMiA5MjkuMzYgMzEzLjMxOSA5MTAuOTIzIDM0Ny40N0w4OTcuMjY2IDM0Mi4wMDlDOTE1LjAyMiAyODYuNjk4IDk2OS42NTIgMjM5LjU1NyAxMDQ3LjUxIDIzOS41NTdaTTEzNDUuOTUgNDkwLjYzQzEzNDUuOTUgNTM0LjMzOSAxMzQ3Ljk5IDU1Ny41NTYgMTM3NiA1NTcuNTU3VjU2NS43NTRIMTIyMC4yOFY1NTcuNTU3QzEyNDguMjcgNTU3LjU1NyAxMjUwLjMzIDUzNC4zNCAxMjUwLjMzIDQ5MC42M1YzNDAuNjM0QzEyNTAuMzMgMjk2LjkyNCAxMjM4LjcxIDI4NC42MjggMTIxNS41IDI3Ni40MzFWMjY4LjIzM0wxMzQwLjQ5IDI0MC45MThIMTM0NS45NVY0OTAuNjNaTTY5Ny44NzYgMTEwLjA0OUM3MjcuMjQ3IDExMC4wNDkgNzU1LjI0MyAxMTYuMTkgNzc3Ljc3OCAxMjYuNDQzTDgzNS4xNDYgMTExLjQyNEg4NDAuNjA2VjQ5MC42MjZIODQwLjYyQzg0MC42MiA1MzQuMzM2IDg0Mi42NjIgNTU3LjU1MiA4NzAuNjcyIDU1Ny41NTJWNTY1Ljc0OUg3MTQuOTUxVjU1Ny41NTJDNzQyLjk0NyA1NTcuNTUyIDc0NS4wMDMgNTM0LjMzNiA3NDUuMDAzIDQ5MC42MjZWMTkyLjY4OEM3MjMuODI5IDE1Ni40OTYgNjk0LjQ3MiAxMzYuNjg0IDY2OC41MTkgMTM2LjY4NEM2MzcuNzg2IDEzNi42ODQgNjI5LjU4OCAxNjEuMjc1IDYyOS41ODggMjE4LjY0M1YyODcuNjI1SDcwNi4wNzNMNjk0LjQ3MiAzMjEuMDgxSDYyOS41ODhWNDkwLjYyNkM2MjkuNTg4IDUzNC4zMzYgNjMxLjY0NSA1NTcuNTUyIDY1OS42NDEgNTU3LjU1MlY1NjUuNzQ5SDUwMy45MTlWNTU3LjU1MkM1MzEuOTE1IDU1Ny41NTIgNTMzLjk3MiA1MzQuMzM2IDUzMy45NzIgNDkwLjYyNlYzMjEuMDgxSDQ5OC40NTlWMzAxLjk2M0w1MzMuOTcyIDI4Ny42MjVDNTMzLjk3MiAxODMuMTMgNjA3LjA1MyAxMTAuMDQ5IDY5Ny44NzYgMTEwLjA0OVpNMTAzOS4zMSAzOTUuMDI3QzEwMDUuMTggNDA4LjAwNCA5NzYuNDg3IDQyMy43MDQgOTc2LjQ4NyA0NzIuMTkzQzk3Ni40ODcgNTEwLjQ0MyA5OTYuMyA1MjguMTk5IDEwMjAuMiA1MjguMTk5QzEwMzcuMjcgNTI4LjE5OSAxMDU0LjM1IDUyMC4wMDIgMTA2Ny4zMiA1MDguMzg3SDEwNjcuMzFWMzg0Ljc3NEwxMDM5LjMxIDM5NS4wMjdaTTM0NS40OTUgMzc0LjA1QzIzMy4yNDggNDA2LjM1MyAxMTcuNjEgNDMxLjM5IDAgNDUwLjQ3OVYzNjMuOTkxQzExOC4yOTEgMzI3Ljk2NSAyMzQuMzg3IDI4NS4zMjUgMzQ1LjQ5NSAyMzQuNDZWMzc0LjA1Wk0zNDUuNDk1IDE2OS4yNTNDMjM1LjQ5OCAyMzAuMTA3IDExOS42ODEgMjgzLjM3NiAwIDMzMC4xMjlWMjMxLjQ3QzEyMS42NTMgMTYyLjcxIDIzOC4zMDUgODYuMDI5OSAzNDUuNDk1IDBWMTY5LjI1M1pNMTM0MC45NiAxODguMzlMMTI1NS40OSAyMTAuMTA1VjEyNC42MzFMMTM0MC45NiAxMDIuOTE1VjE4OC4zOVoiIGZpbGw9IiNmZmYiLz48L3N2Zz4=");

  /* --- color --- */
  --white:#ffffff;
  --ink:#1a0d0d;
  --cyan:#cee8eb;
  --red:#fa0741;

  /* --- type --- */
  --display:"IvyPresto Headline","Playfair Display",Georgia,"Times New Roman",serif;
  --sans:"DM Sans",system-ui,-apple-system,"Segoe UI",sans-serif;

  /* --- layout --- */
  --max:1440px;
  --gutter:32px;
  /* The air between sections. 104 was the same figure at every width, which
 read tight once the page got long; this grows with the viewport and is
 floored at the old value, so nothing anywhere ends up closer than */
  --gap-section:clamp(104px, 10vw, 152px);
  /* The band Figma lays across every data card: one vector, three ribbons,
 filled left to right from nothing to full. Read straight out of the file
 not eyeballed, so the edges fall where the design puts them. */
  --a-sheen-red:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 420 525' preserveAspectRatio='none'%3E%3Cdefs%3E%3ClinearGradient id='r' x1='0' y1='0' x2='420' y2='0' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%231A0D0D' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='%23FA0741' stop-opacity='1'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath fill='url(%23r)' fill-rule='nonzero' d='M 420 24.505 L 420 62.235 C 289.219 143.966 147.782 212.726 0 270.880 L 0 176.687 C 94.155 123.136 185.043 64.524 270.309 0 L 395.494 0 C 409.025 0 420 10.974 420 24.505 Z M 420 148.392 C 287.591 218.067 145.658 273.525 0 318.250 L 0 400.718 C 144.234 377.014 285.175 343.594 420 298.043 L 420 148.404 L 420 148.392 Z M 0 444.795 L 0 525 L 171.881 525 L 171.881 424.193 C 114.960 432.828 57.556 439.619 0 444.795 Z'/%3E%3C/svg%3E");
  --a-sheen-white:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 420 525' preserveAspectRatio='none'%3E%3Cdefs%3E%3ClinearGradient id='r' x1='0' y1='0' x2='420' y2='0' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%23FFFFFF' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='%23FFFFFF' stop-opacity='1'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath fill='url(%23r)' fill-rule='nonzero' d='M 420 24.505 L 420 62.235 C 289.219 143.966 147.782 212.726 0 270.880 L 0 176.687 C 94.155 123.136 185.043 64.524 270.309 0 L 395.494 0 C 409.025 0 420 10.974 420 24.505 Z M 420 148.392 C 287.591 218.067 145.658 273.525 0 318.250 L 0 400.718 C 144.234 377.014 285.175 343.594 420 298.043 L 420 148.404 L 420 148.392 Z M 0 444.795 L 0 525 L 171.881 525 L 171.881 424.193 C 114.960 432.828 57.556 439.619 0 444.795 Z'/%3E%3C/svg%3E");
  --r-lg:32px;
  --r-md:24px;
  --r-sm:16px;
}

@media (max-width:900px){
  :root{ --gutter:20px; --r-lg:24px; --r-md:20px; }
  /* 104 was the desktop floor carried down unchanged, and on a phone it read
 as a hole between every pair of sections. */
  :root{ --gap-section:72px; }
}
@media (max-width:640px){
  :root{ --gap-section:64px; }
}

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

html{ -webkit-text-size-adjust:100%; }

body{
  margin:0;
  overflow-x:hidden;
  font-family:var(--sans);
  font-variation-settings:"opsz" 14;
  color:var(--ink);
  /* Figma runs one #CEE8EB -> #FFFFFF gradient down the whole page frame, so
 the correct anchor is the document, not a fixed pixel height. It */
  background:linear-gradient(180deg,var(--cyan) 0%,var(--white) 100%) no-repeat var(--white);
  background-size:100% 100%;
  -webkit-font-smoothing:antialiased;
}

img{ display:block; max-width:100%; }
a{ color:inherit; text-decoration:none; }
button{ font:inherit; color:inherit; background:none; border:0; cursor:pointer; }
p{ margin:0; }
h1,h2,h3{ margin:0; font-weight:400; font-family:var(--display); }
ul{ margin:0; padding:0; list-style:none; }

:focus-visible{
  outline:2px solid var(--red);
  outline-offset:3px;
  border-radius:4px;
}

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

.shell{
  width:100%;
  max-width:var(--max);
  margin-inline:auto;
  padding-inline:var(--gutter);
}

/* ---------- shared: pill button -----------------------------------
   The hover is a red flood that opens from behind the mark. It is painted
   in the button's own background, not in a layer on top of it. --------
   -------------------------------------------------------------------- */
@property --btn-fill{
  syntax:'<percentage>';
  inherits:false;
  initial-value:0%;
}

.btn{
  position:relative;
  display:inline-flex;
  align-items:center;
  height:48px;
  border-radius:var(--r-sm);
  background-color:var(--white);
  /* An ellipse, not a circle, and a tall one. A circle springing from a point
 24px above the floor of a 48px pill reaches the top and the bottom almost
 at once, so most of what you see is a fat arc bulging vertically. */
  background-image:radial-gradient(ellipse 100% 320% at 26px 50%,
    var(--btn-flood) calc(var(--btn-fill) - 5%),
    var(--btn-flood-0) var(--btn-fill));
  --btn-flood:var(--red);
  --btn-flood-0:rgba(250,7,65,0);
  color:var(--ink);
  font-size:16px;
  font-weight:500;
  white-space:nowrap;
  --btn-fill:0%;
  transition:--btn-fill .62s cubic-bezier(.22,1,.36,1),
             box-shadow .55s cubic-bezier(.22,1,.36,1);
}
.btn:hover,
.btn:focus-visible{
  --btn-fill:108%;               /* past the farthest corner */
  box-shadow:0 8px 22px rgba(250,7,65,.22);
}
/* Coming back is quicker and on a different curve, so it */
.btn:not(:hover):not(:focus-visible){
  transition:--btn-fill .44s cubic-bezier(.4,0,.2,1),
             box-shadow .45s cubic-bezier(.4,0,.2,1);
}
.btn:active{ --btn-fill:100%; }

.btn__face{
  display:flex;
  align-items:center;
  gap:8px;
  padding:8px 20px;
}

/* The mark is a mask over a colour, not a picture, so it can be
 recoloured with a plain transition: no second copy to cross-fade. It sits
 at the origin of the flood */
.btn__arrow{
  width:10.148px;
  height:18px;
  flex:none;
  background-color:var(--red);
  -webkit-mask:var(--a-cta-arrow) no-repeat center/contain;
  mask:var(--a-cta-arrow) no-repeat center/contain;
  transition:background-color .2s linear;
}
.btn:hover .btn__arrow,
.btn:focus-visible .btn__arrow{ background-color:var(--white); }
/* on a white flood the mark keeps the red it has at rest on any white pill */
.btn--ghost:hover .btn__arrow,
.btn--ghost:focus-visible .btn__arrow{ background-color:var(--red); }
.btn:not(:hover):not(:focus-visible) .btn__arrow{ transition:background-color .2s linear .3s; }

/* The outlined secondary floods white, not red: the same sweep, the other
 colour, so the pair Only
 the flood colour and the two parts that travel with it are restated; */
.btn--ghost{
  --btn-flood:var(--white);
  --btn-flood-0:rgba(255,255,255,0);
  background-color:transparent;
  box-shadow:inset 0 0 0 1px var(--white);
  color:var(--white);
  transition:--btn-fill .62s cubic-bezier(.22,1,.36,1),
             box-shadow .55s cubic-bezier(.22,1,.36,1),
             color .42s ease;
}
.btn--ghost:hover,
.btn--ghost:focus-visible{
  color:var(--ink);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,0), 0 8px 22px rgba(0,0,0,.28);
}
.btn--ghost:not(:hover):not(:focus-visible){
  transition:--btn-fill .44s cubic-bezier(.4,0,.2,1),
             box-shadow .45s cubic-bezier(.4,0,.2,1),
             color .3s ease;
}

@media (prefers-reduced-motion:reduce){
  .btn, .btn--ghost, .btn__arrow{ transition:none; }
}

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

.nav{
  position:fixed;
  inset:0 0 auto 0;
  z-index:60;
  padding-block:24px;
  transition:background-color .4s ease, box-shadow .4s ease;
}
/* Nothing spans the viewport. At the top the bar is invisible; once you
 scroll it draws itself in, shedding the menu and pulling the logo and the
 two actions together into a single glass pill. */
.nav__inner{ position:relative; }
.nav__shell{
  position:relative;
  max-width:100%;
  margin-inline:auto;
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:16px;
  padding:0;
  /* the CTA inside is 16px with 8px of padding around it, so the shell reads
 as concentric with it at 24. A pill would not: the eye would see two
 unrelated curvatures nested in each other. */
  border-radius:24px;
  transition:max-width .7s cubic-bezier(.22,1,.36,1),
             padding .55s cubic-bezier(.22,1,.36,1),
             background-color .45s ease,
             box-shadow .45s ease;
}
.nav.is-stuck .nav__shell{
  max-width:min(100%,460px);
  padding:8px 8px 8px 24px;
  background:rgba(236,245,246,.66);
  backdrop-filter:blur(20px) saturate(140%);
  -webkit-backdrop-filter:blur(20px) saturate(140%);
  box-shadow:0 12px 34px rgba(26,13,13,.12), inset 0 0 0 1px rgba(255,255,255,.55);
}
.nav__logo{ flex:none; }
/* centred on the bar and out of the flex flow, so collapsing the shell cannot
 drag it around and the intro can still transform the pill itself */
.nav__menu-wrap{
  position:absolute;
  left:50%; top:50%;
  transform:translate(-50%,-50%);
  transition:opacity .3s ease, transform .5s cubic-bezier(.22,1,.36,1);
}
.nav.is-stuck .nav__menu-wrap{
  opacity:0;
  transform:translate(-50%,-50%) scale(.94);
  pointer-events:none;
}
.nav__actions{
  flex:none;
  display:flex;
  align-items:center;
  gap:24px;
}
.nav.is-stuck .nav__actions{ gap:18px; }
.nav__login{ font-size:16px; font-weight:500; white-space:nowrap; }
/* on desktop the drawer is, not a box at all, its children join the nav row */
.nav__drawer{ display:contents; }
.nav__toggle{ display:none; }
.nav__logo{
  width:96px;
  height:40px;
  flex:none;
  background:var(--a-logo) no-repeat left center/contain;
}
.nav__menu{
  display:flex;
  align-items:center;
  gap:32px;
  height:48px;
  padding:8px 24px;
  border-radius:var(--r-sm);
  background:rgba(255,255,255,.4);
  backdrop-filter:blur(12px);
  -webkit-backdrop-filter:blur(12px);
  font-size:16px;
}
/* The label sits in a one-line window with a second copy stacked underneath.
 On hover the pair slides up by exactly one line, so the word is replaced by
 its red twin not underlined. One transform, nothing else moves. */
.nav__menu a,
.nav__login{
  display:block;
  overflow:hidden;
  height:1.5em;
  line-height:1.5;
}
.roll{
  display:block;
  will-change:transform;
  transition:transform .5s cubic-bezier(.22,1,.36,1);
}
.roll > span{ display:block; height:1.5em; }
.roll > span + span{ color:var(--red); }
.nav__menu a:hover .roll,
.nav__menu a:focus-visible .roll,
.nav__login:hover .roll,
.nav__login:focus-visible .roll{ transform:translateY(-1.5em); }

@media (max-width:1100px){
  .nav__menu-wrap{ position:static; transform:none; opacity:1; }
  /* And it stays visible once the bar sticks. `.nav.is-stuck.nav__menu-wrap`
 fades this block out: which is right on a desktop, where the pill lives
 in the bar and the bar collapses on scroll. */
  .nav.is-stuck .nav__menu-wrap{
    opacity:1;
    transform:none;
    pointer-events:auto;
  }
  .nav.is-stuck .nav__shell{ max-width:100%; padding:8px 8px 8px 20px; }
  .nav__toggle{
    display:flex;
    flex-direction:column;
    justify-content:center;
    gap:5px;
    width:48px; height:48px;
    padding:0 13px;
    flex:none;
    border-radius:var(--r-sm);
    background:rgba(255,255,255,.55);
    backdrop-filter:blur(12px);
    -webkit-backdrop-filter:blur(12px);
  }
  .nav__toggle i{
    display:block;
    width:100%; height:1.5px;
    background:var(--ink);
    border-radius:2px;
    transition:transform .4s cubic-bezier(.22,1,.36,1);
  }
  .nav.is-open .nav__toggle i:first-of-type{ transform:translateY(3.25px) rotate(45deg); }
  .nav.is-open .nav__toggle i:last-of-type{ transform:translateY(-3.25px) rotate(-45deg); }

  /* The menu takes the whole screen in the brand cyan. A card floating under
 the bar had to guess how much room its own contents needed and clip
 anything that did not fit; */
  .nav__drawer{
    display:flex;
    position:fixed;
    inset:0;
    flex-direction:column;
    justify-content:center;
    align-items:stretch;
    gap:24px;
    padding:calc(96px + env(safe-area-inset-top, 0px)) var(--gutter)
            calc(40px + env(safe-area-inset-bottom, 0px));
    border-radius:0;
    background:var(--cyan);
    backdrop-filter:none;
    -webkit-backdrop-filter:none;
    box-shadow:none;
    overflow-y:auto;
    opacity:0;
    visibility:hidden;
    transform:translateY(-8px);
    transition:opacity .35s ease, transform .4s cubic-bezier(.22,1,.36,1), visibility .35s;
  }
  .nav.is-open .nav__drawer{ opacity:1; visibility:visible; transform:none; }

  /* The panel is position:fixed and it lives inside .nav__shell: and the
     shell picks up a backdrop-filter once the page is scrolled. A filter
     makes an element a containing block for fixed descendants, exactly as a
     transform does, so past 60px of scroll the full-screen panel stopped
     being full-screen and collapsed into the bar: */
  .nav.is-open .nav__shell{
    backdrop-filter:none;
    -webkit-backdrop-filter:none;
  }

  /* and the page holds still underneath it */
  html.is-nav-open,
  html.is-nav-open body{
    overflow:hidden;
    touch-action:none;
  }
  /* the toggle has to stay reachable above a full-screen panel */
  .nav__toggle{ position:relative; z-index:2; }

  .nav__menu{
    flex-direction:column;
    align-items:stretch;
    gap:0;
    height:auto;
    padding:0;
    background:none;
    backdrop-filter:none;
    -webkit-backdrop-filter:none;
  }
  .nav__menu{ gap:8px; }
  .nav__menu a{
    margin:0;
    padding-block:10px;
    font-family:var(--display);
    font-size:40px;
    line-height:1.15;
  }
  /* The roll is a hover effect, and there is no hover here. It is also what
 clips descenders once the type is set at 24: the window is one line tall
 by design and a 'g' grazes its edge. */
  .nav__drawer .nav__menu a,
  .nav__drawer .nav__login{ overflow:visible; height:auto; }
  .nav__drawer .roll{ transform:none; }
  .nav__drawer .roll > span{ height:auto; }
  .nav__drawer .roll > span[aria-hidden="true"]{ display:none; }

  /* The panel covers the whole screen, so the two things that have to stay on
 top of it are the way out and the way home. The mark is inverted to white
 for the dark bar; over the cyan it goes back to the ink */
  .nav__logo{ position:relative; z-index:2; }
  .nav.is-open .nav__logo{ filter:none; }
  /* and the bars of the toggle keep their own contrast on the light pill */
  .nav.is-open .nav__toggle{ background:rgba(255,255,255,.72); }
  /* column-reverse not moving the markup: the button comes first in
 the panel and the login sits under it, centred on it. In the bar the two
 keep the order they are written in. */
  .nav__actions{
    flex-direction:column-reverse;
    align-items:stretch;
    gap:16px;
    margin-top:40px;
  }
  .nav__login{
    margin:0;
    padding-block:10px;
    font-size:18px;
    text-align:center;
  }
  .nav__cta{ width:100%; }
  .nav__cta .btn__face{ flex:1; justify-content:center; }
}

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

/* ---------- hero --------------------------------------------------
   Figma 260:10880, a 1440x812 frame. The photograph runs to 724 with the
   bottom corners rounded, the copy sits on its left half, the conversation
   floats over its right, and a blurred bar across the foot carries the
   dealer marks. --------
   -------------------------------------------------------------------- */

.hero{
  position:relative;
  isolation:isolate;
  min-height:812px;
  min-height:100svh;
}
.hero__shot{
  position:absolute;
  left:0; right:0; top:0;
  /* Full screen. Figma stopped the film at 724 of 812 and rounded the two
 bottom corners, which left a band of page ground under it; the film now
 runs the whole height and meets the next section on a straight edge. */
  height:100%;
  overflow:hidden;
  /* the still stays underneath as the ground: it is what shows before the
 video has a frame, and what remains if the file never loads at all */
  background:var(--a-hero-photo) no-repeat center/cover var(--ink);
  z-index:-2;
}
.hero__video{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  object-fit:cover;
  display:block;
}
/* A black wash that runs across, heaviest on the left where the claim sits
 and nearly clear on the right so the picture reads there. */
.hero__shot::after{
  content:"";
  position:absolute;
  inset:0;
  background:linear-gradient(90deg,
    rgba(0,0,0,.5) 0%, rgba(0,0,0,.1) 100%);
}
/* A dusting of film grain over the picture. The noise is one 110px tile
   built by feTurbulence: nothing to ship, no bitmap, repeated across the
   frame, and it jumps to a fresh offset ten times a second not sliding: */
.hero__shot::before{
  content:"";
  position:absolute;
  inset:-6%;
  z-index:1;                       /* over the film, the wash and the glow */
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='g' x='0' y='0' width='100%' height='100%' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.1' numOctaves='3' stitchTiles='stitch' result='t'/%3E%3CfeColorMatrix in='t' values='1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0'/%3E%3CfeComponentTransfer%3E%3CfeFuncR type='discrete' tableValues='.2 .8'/%3E%3CfeFuncG type='discrete' tableValues='.2 .8'/%3E%3CfeFuncB type='discrete' tableValues='.2 .8'/%3E%3CfeFuncA type='table' tableValues='.8 0 .8'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23g)'/%3E%3C/svg%3E");
  background-size:110px 110px;
  opacity:.16;                     /* the one number to turn for more or less */
  pointer-events:none;
  will-change:transform;
  animation:hero-grain .8s steps(1,end) infinite;
}
@keyframes hero-grain{
  0%    { transform:translate3d(0,0,0); }
  12.5% { transform:translate3d(-2%,-1%,0); }
  25%   { transform:translate3d(1%,-2%,0); }
  37.5% { transform:translate3d(-1%,2%,0); }
  50%   { transform:translate3d(2%,1%,0); }
  62.5% { transform:translate3d(-2%,2%,0); }
  75%   { transform:translate3d(1%,-1%,0); }
  87.5% { transform:translate3d(-1%,-2%,0); }
}
/* Still grain not none: the texture belongs to the picture, the flicker is
   the part that has to stop. Same on a phone, and for the same reason it
   is worth having at all: measured on a 4x-throttled handset the hero ran
   27.8fps with the grain jumping, 34.6 with it held still and 39.7 with no
   grain at all. */
@media (prefers-reduced-motion:reduce), (max-width:900px){
  .hero__shot::before{ animation:none; }
}

/* and a soft light through the upper right, which the design draws as a vector */
.hero__glow{
  position:absolute;
  left:36.6%; top:-18%;
  width:80%; height:150%;
  background:radial-gradient(52% 38% at 42% 30%,
    rgba(255,255,255,.16) 0%, rgba(255,255,255,.05) 45%, rgba(255,255,255,0) 78%);
  pointer-events:none;
}

.hero__inner{
  position:relative;
  max-width:var(--max);
  margin-inline:auto;
  min-height:812px;
  min-height:100svh;
  padding:0 var(--gutter);
}

/* the copy is centred on the frame, as Figma has it */
.hero__copy{
  position:absolute;
  left:var(--gutter);
  top:50%;
  transform:translateY(-50%);
  width:min(691px, calc(52% - 32px));   /* Figma 723, pulled in 32 */
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:24px;
  z-index:2;
}
.hero__title{
  /* 72. Written as a clamp with 72 at the top, not a flat 72: the same
 figure on a 375px screen is a headline in a column half the width, and it
 wants to come down with it. Above ~1440 it is exactly 72. */
  font-size:clamp(2.25rem,5vw,4.5rem);
  line-height:1.15;
  color:var(--white);
  text-wrap:pretty;
}
/* Kept for any em inside the claim, though nothing uses it now: the cyan
 marked one clause of a long heading, and that clause is the whole heading. */
.hero__title em,
.hero__title .hero__cyan{ font-style:normal; color:var(--cyan); }   /* #CEE8EB */

/* the conversation over the right of the photograph ---- Six turns run as
   a thread: the newest sits at the foot and the ones before it ride up,
   softening a step at a time until they are gone. The band is centred on
   the viewport with a negative margin, not a transform: a transform here
   would make it a backdrop root and the bubbles could no longer blur the
   photograph behind them. */
.hero__chat{
  position:absolute;
  left:58%; right:2.2%;
  top:50%;
  /* one value, used twice: min() picks the most negative operand, so writing
 the offset by hand drifted off centre as soon as the two disagreed */
  --band-h:min(560px, 68vh);
  height:var(--band-h);
  margin-top:calc(var(--band-h) / -2);
  z-index:2;
  pointer-events:none;
  overflow:hidden;
}
.hero__thread{
  position:absolute;
  left:0; right:0; bottom:0;
  display:flex;
  flex-direction:column;
  /* without this the customer's turns stretch to the full column while Flai's
 shrink to their text, and the two sides end up different widths */
  align-items:flex-start;
  gap:16px;
}
/* the card: mark on top, the line under it, the time under that */
.hero__msg{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:20px;
  /* Narrower, and held within a band so the six cards read as a set rather
 than as one long line and one short one. The longer turns wrap. */
  max-width:66%;
  min-width:46%;
  padding:22px 24px;
  border:1px solid transparent;
  border-radius:24px;
  background:
    linear-gradient(rgba(26,13,13,.05), rgba(26,13,13,.05)) padding-box,
    linear-gradient(175deg, rgba(255,255,255,.2) 0%, rgba(255,255,255,0) 100%) border-box;
  backdrop-filter:blur(8px);
  -webkit-backdrop-filter:blur(8px);
  color:var(--white);
}
.hero__msg--out{ align-self:flex-end; }
.hero__msg p{ margin:0; font-size:17px; line-height:26px; }
.hero__time{ font-size:13px; line-height:1; opacity:.55; }
.hero__msg p + .hero__time{ margin-top:-8px; }

.hero__av{
  flex:none;
  width:44px; height:44px;
  border-radius:50%;
  background-repeat:no-repeat;
  background-position:center;
  background-size:cover;
}
.hero__av--caller{  background-image:var(--a-hero-av-1); }
.hero__av--caller2{ background-image:var(--a-hero-av-2); }
.hero__av--flai{ background:var(--a-send) no-repeat center/contain; }

/* the dealer marks, in a grid of their own under the case studies ----
   Twelve cells, seven marks: the empty ones are what the marks move into,
   so the wall keeps rearranging itself without ever repeating a layout
   twice in a row. */
/* The wall belongs to the case studies above it, so it keeps its own tight
 tuck, not the full section gap. Nothing below it: the next section
 brings its own --gap-section. */
.dealers{ margin-top:80px !important; margin-bottom:0 !important; }
/* The wall's tuck has to stay tighter than the gap between sections or the
 hierarchy inverts: and on a phone the section gap came down to 64/72,
 which the desktop's 80 had overtaken. */
@media (max-width:900px){
  .dealers{ margin-top:64px !important; }   /* 56 before: the one gap on the page that was not 64 */
}
.dealers__grid{
  display:grid;
  grid-template-columns:repeat(4, 1fr);
  grid-template-rows:repeat(3, 1fr);
}
.dealers__cell{
  position:relative;
  display:flex;
  align-items:center;
  justify-content:center;
  min-height:132px;
  /* one hairline between neighbours not two stacked on each other */
  box-shadow:inset 0 0 0 .5px #493B3B;
  border-radius:0;
}
/* Every mark was drawn into the same 240x112 canvas, so they all get the same
 box and the relative sizes the studio gave them survive: a stacked lockup
 stays taller than a wordmark instead of being squashed to a common height. */
.dealers__mark{
  position:absolute;
  width:120px;
  aspect-ratio:240/112;
  background-repeat:no-repeat;
  background-position:center;
  background-size:contain;
  /* the marks as supplied, in their own greys: no filter over them */
  opacity:1;
  transition:opacity .5s ease;
}
.dealers__mark--b{ opacity:0; }
.dealers__cell.is-flipped .dealers__mark--a{ opacity:0; }
.dealers__cell.is-flipped .dealers__mark--b{ opacity:1; }
@media (prefers-reduced-motion:reduce){
  .dealers__mark{ transition:none; }
}

@media (max-width:900px){
  /* three across not two: twelve tiles stacked two-wide made the wall
 six rows deep, which is a lot of scrolling for a logo strip */
  .dealers__grid{ grid-template-columns:repeat(3, 1fr); grid-template-rows:repeat(4, 1fr); }
  .dealers__cell{ min-height:104px; }
  .dealers__mark{ width:84px; }
}

@media (max-width:900px){
  .hero{ min-height:0; }
  /* the last turn was landing flush on the foot of the section */
  .hero__inner{ min-height:0; padding-block:120px 56px; }
  .hero__copy{
    position:relative;
    top:auto;
    left:auto;
    transform:none;
    width:100%;
  }
  /* On a phone the thread came out of its band and all six turns stacked in
 the flow, which ran the hero to 1598px: near two screens before you had
 scrolled once, and it is what was cropping the film so tightly. */
  /* A 1920x1080 film cover-cropped into a phone shows about a quarter of its
 width, and centred that quarter fell between the two people. Checked at
 three points of the clip: */
  .hero__video{ object-position:60% 50%; }
  .hero__chat{ position:relative; inset:auto; margin-top:24px; height:auto; overflow:visible; }
  .hero__thread{ position:relative; bottom:auto !important; gap:10px; }
  .hero__msg{
    max-width:88%;
    min-width:0;
    gap:8px;
    padding:14px 16px;
    border-radius:18px;
  }
  .hero__msg p{ font-size:15px; line-height:22px; }
  .hero__msg p + .hero__time{ margin-top:-4px; }
  .hero__av{ width:32px; height:32px; }
  .hero__msg:nth-of-type(n+4){ display:none; }
}

/* ---------- the problem, and how Flai solves it -------------------
   A full screen of cyan that holds still while the statement writes
   itself, then lets the page carry on. Everything is set in the dark
   bordeaux. --------
   -------------------------------------------------------------------- */

/* A card on the page, not a screen of its own, sized like the FAQ. */
.ps{
  max-width:calc(var(--max) - var(--gutter) * 2);
  margin:var(--gap-section) auto 0 !important;
  border-radius:var(--r-lg);
  overflow:hidden;
  /* Figma bg-statement: the cyan with its own pale bands running across it.
 The flat cyan stays underneath as the ground the artwork sits on. */
  background:var(--a-ps-bg) no-repeat center/cover var(--cyan);
  color:var(--ink);
}
.ps__stage{
  position:relative;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  padding:120px var(--gutter);
}
@media (max-width:1440px){ .ps{ margin-inline:var(--gutter) !important; } }
.ps__stack{
  position:relative;
  display:grid;
  width:100%;
  max-width:calc(var(--max) - var(--gutter) * 2);
}
.ps__say{
  grid-area:1/1;
  align-self:center;
  text-align:center;
  font-family:var(--display);
  font-size:clamp(1.75rem,2.9vw,2.625rem);   /* smaller now that it is a card */
  line-height:1.3;
}
/* the break between the two halves of the statement */
.ps__gap{ display:block; height:.85em; }
/* One span per character, written by the script as the statement fills. A
 static sweep for unused selectors cannot see it: the class is never in
 the markup, */
.ps__c{ opacity:.16; }
html:not(.js) .ps__c{ opacity:1; }

@media (max-width:900px){
  .ps__stage{ padding:72px var(--gutter); }
}

/* ---------- for sales: cards that stack as you scroll -------------
   Figma 301:58. Each card is 1376x620 with a 32 radius, cyan with a
   diagonal sheen, the copy on its left half and a 680-wide photograph
   flush to its right edge. They stick one over the other as the page
   scrolls, and the ones underneath shrink, dim and soften. --------
   -------------------------------------------------------------------- */

.sales{ margin-top:var(--gap-section); }
.sales__title{
  margin:0;
  text-align:center;
  font-family:var(--display);
  font-size:clamp(2.25rem,4.44vw,4rem);   /* Figma 64 */
  line-height:1.2;
  color:var(--white);
}
/* The line under the claim, held to the same 640 and left the same distance
 from the row that the service heading keeps from its own panel, so the two
 sections open the same way. */
.sales__lede{
  max-width:640px;
  margin:16px auto 104px;
  text-align:center;
  font-size:16px;
  line-height:1.55;
  color:var(--muted);
}
@media (max-width:900px){
  .sales__lede{ margin-bottom:64px; }
}

/* Four modules flush against each other, each one a photograph with its own
 conversation over it and the claim inside the frame. At rest you get the
 picture, the chat and the claim; */
.sales__grid{
  display:grid;
  grid-template-columns:repeat(4, minmax(0,1fr));
  gap:12px;                               /* the modules stand apart, and the
 row runs square into its edges */
}
.scol{ display:flex; }
.scol__panel{
  position:relative;
  width:100%;
  /* Taller than the row it replaces: open, a module carries the claim, the
 copy and three items over the conversation, and at 4:5 the last turn and
 the first item landed on each other. */
  /* 335x541: the 3:5 Written as the ratio, not a
 subtraction because the column's width moves with the container and a flat
 32 would only be 32 at one of those widths. */
  aspect-ratio:335/556;
  overflow:hidden;
  /* The conversation and the copy share the height as a column, not the chat
     reserving a percentage for the copy. The copy's height depends on how
     its own sentences wrap, which no percentage here can know: the first
     attempt guessed 34% and the tallest module overran it by 32px. */
  display:flex;
  flex-direction:column;
  background-repeat:no-repeat;
  background-position:center;
  background-size:cover;
}
/* Four photographs, four modules, shipped as local files not pulled from
   Figma: they are 971x1619, which is 3:5 to four decimal places, so the
   panel takes them whole at the widest layout and only crops top and
   bottom once the row folds to two across. */
.scol__panel--1{ background-image:var(--a-sales-1); }
.scol__panel--2{ background-image:var(--a-sales-2); }
.scol__panel--3{ background-image:var(--a-sales-3); }
.scol__panel--4{ background-image:var(--a-sales-4); }
/* The wash that carries the type: black at the foot, nothing by the time it
 reaches the conversation. */
.scol__shade{
  position:absolute;
  inset:0;
  background:linear-gradient(to top, rgba(0,0,0,.6) 0%, rgba(0,0,0,0) 100%);
  pointer-events:none;
}
/* The photograph is sharp until you point at it. The blur is on the veil
 not on the image itself, so it softens the picture without touching
 the bubbles or the type sitting on top. */
.scol__veil{
  position:absolute;
  inset:0;
  backdrop-filter:blur(0px);
  -webkit-backdrop-filter:blur(0px);
  /* A flat 20% sits over every photograph at rest, on top of the gradient at
 the foot: it settles the four pictures to a common weight so the row
 */
  background:rgba(0,0,0,.2);
  transition:backdrop-filter .45s ease, -webkit-backdrop-filter .45s ease, background-color .45s ease;
  pointer-events:none;
}
/* 60% black over a 12px blur: the image mask the design specifies for these
 cards. the red of the showroom read as streaks across what should be a
 flat, quiet ground. */
.scol:hover .scol__veil{
  backdrop-filter:blur(12px);
  -webkit-backdrop-filter:blur(12px);
  background:rgba(0,0,0,.6);
}

.scol__chat{
  position:relative;
  z-index:2;
  flex:1;
  min-height:0;
  display:flex;
  flex-direction:column;
  justify-content:center;
  /* Tight by design now: the claim went up 16 and the module came down 32,
     which between them took about 70 off what the turns had. Measured with
     the real DM Sans loaded, not the fallback: the three-turn panel was
     still two pixels short, so the turns themselves give a little back
     below. */
  gap:5px;
  padding:16px 20px 12px;
  /* At rest a module is the photograph, the claim and the description; the
 conversation belongs to the hover. It keeps its place in the column while
 hidden, so nothing shifts when it arrives. */
  opacity:0;
  transition:opacity .4s ease;
}
.scol:hover .scol__chat{ opacity:1; }
.scol__msg{
  position:relative;
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:6px;
  max-width:94%;
  padding:8px 10px;
  border-radius:14px;
  color:var(--white);
  backdrop-filter:blur(10px);
  -webkit-backdrop-filter:blur(10px);
}
.scol__msg--flai{   background:rgba(26,13,13,.55); }
.scol__msg--caller{ background:rgba(255,255,255,.12); }
.scol__msg--out{ align-self:flex-end; }
.scol__msg--in { align-self:flex-start; }
.scol__msg--mid{ align-self:center; max-width:100%; width:100%; }
.scol__msg p{ margin:0; font-size:12px; line-height:17px; font-variation-settings:'opsz' 14; }
.scol__time{ font-size:10px; font-weight:500; opacity:.5; }
.scol__mbody{ display:flex; flex-direction:column; gap:3px; }
.scol__av{
  flex:none;                       /* same trap as the service avatar above */
  width:22px; height:22px;
  border-radius:50%;
  background-repeat:no-repeat;
  background-position:center;
  background-size:cover;
}
.scol__av--flai{ background-image:var(--a-send); background-size:contain; }
.scol__av--caller{ background-image:var(--a-sales-av); }
/* the three dots that stand in for a turn while it is being typed */
.scol__typing{
  position:absolute;
  left:10px; top:40px;
  display:flex;
  align-items:center;
  gap:4px;
  height:14px;
  opacity:0;
}
.scol__typing i{
  width:5px; height:5px;
  border-radius:50%;
  background:currentColor;
  animation:mset-type 1.05s ease-in-out infinite;
}
.scol__typing i:nth-child(2){ animation-delay:.14s; }
.scol__typing i:nth-child(3){ animation-delay:.28s; }

.scol__foot{
  position:relative;
  z-index:3;
  padding:0 20px 20px;
}
.scol__title{
  margin:0;
  font-family:var(--display);
  /* 32 flat, at every width. both ends are gone, so the modules read the same
 on a phone and on a wide screen and there is no band where the size
 drifts. Two or three lines and welcome to them. */
  font-size:2rem;
  line-height:1.15;
  color:var(--white);
}
/* 0fr to 1fr, not a height: the row measures its own content, so the
 copy can be any length and nothing has to be guessed here. */
.scol__more{
  display:grid;
  grid-template-rows:0fr;
  opacity:0;
  transition:grid-template-rows .45s ease, opacity .35s ease;
}
.scol__more > div{ overflow:hidden; }
.scol:hover .scol__more{ grid-template-rows:1fr; opacity:1; }
.scol__lede{
  margin:14px 0 0;
  font-size:13px;
  line-height:1.5;
  color:rgba(255,255,255,.78);
}
.scol__list{ margin:14px 0 0; padding:0; list-style:none; }
.scol__list li{
  position:relative;
  padding-left:20px;
  font-size:12px;
  line-height:1.4;
  color:rgba(255,255,255,.72);
}
.scol__list li + li{ margin-top:8px; }
.scol__list li::before{
  content:"";
  position:absolute;
  left:0; top:.15em;
  width:13px; height:13px;
  background:var(--a-check) no-repeat center/contain;
}

.sales__cta{ display:flex; justify-content:center; margin-top:56px; }

/* Nothing to hover with a finger: the copy is there, and the blur with
 it, not hidden behind a gesture the device cannot make. */
@media (hover:none){
  .scol__more{ grid-template-rows:1fr; opacity:1; }
  .scol__chat{ opacity:1; }
  .scol__veil{ backdrop-filter:blur(12px); -webkit-backdrop-filter:blur(12px); background:rgba(0,0,0,.6); }
  /* With the copy permanently open there is nothing to reserve room for, so
 the two blocks go back into the flow and the module takes the height its
 own content asks for, not a ratio guessing at it. */
  .scol__panel{ aspect-ratio:auto; min-height:440px; }
}
@media (prefers-reduced-motion:reduce){
  .scol__more, .scol__veil, .scol__chat{ transition:none; }
  .scol__typing i{ animation:none; }
}

/* Four abreast stops working well before 1100. The column narrows as the
   window does, so the claims start wrapping to three lines exactly as the
   panel: whose height is a ratio of that same shrinking width, has least
   to give. */
@media (max-width:1380px){
  .sales__grid{ grid-template-columns:repeat(2, minmax(0,1fr)); gap:20px; }
  /* Taller than square. The panel's height is a ratio of a width that keeps
 shrinking while the copy inside it keeps growing, so a square ran out of
 room at the narrow end of this range: */
  .scol__panel{ aspect-ratio:1/1.18; }
}
/* One column from 960 not 640. Two abreast below that gives each
 module under 400px, and the same squeeze returns: measured an overlap of
 26px at 700 and 60 at 641. */
@media (max-width:960px){
  .sales__grid{ grid-template-columns:minmax(0,1fr); gap:24px; }
  .scol__panel{ aspect-ratio:3/4; }
  .sales__cta{ margin-top:40px; }
}

/* ---------- the service section: a column of names ----------------
   Each name has a hairline over it. The live one opens to show its copy,
   and that hairline fills as its time runs out; clicking any name jumps to
   it. --------
   -------------------------------------------------------------------- */
.feature{
  display:grid;
  /* the media panel keeps the larger share; the reading column is narrower
 and sits 80 clear of it */
  grid-template-columns:minmax(0,1.25fr) minmax(0,1fr);
  gap:0 80px;
  align-items:start;
}
.feature__panel{ min-width:0; }
.feature__list{ display:flex; flex-direction:column; }

/* The rule belongs under the name it times, not over it: which also means
 the top of the list opens with the first name not with a line. */
.ftab{ position:relative; padding-bottom:24px; }
.ftab + .ftab{ padding-top:24px; }
.ftab__rule{
  position:absolute;
  left:0; right:0; bottom:0;
  height:1px;
  background:rgba(255,255,255,.16);
  overflow:hidden;
}
.ftab__rule i{
  display:block;
  height:100%;
  width:100%;
  background:var(--red);
  transform:scaleX(0);
  transform-origin:0 50%;
}
.ftab__name{
  display:block;
  width:100%;
  padding:0;
  text-align:left;
  font-family:var(--display);
  /* the full claim is the name now */
  font-size:clamp(1.375rem,2.2vw,1.875rem);
  line-height:1.2;
  /* 42% measures 4.07:1 against the page ground. That clears the 3:1 this type
 needs while it is still large text, which it is down to a 1091 viewport: below that the clamp floors it at 22px, it counts as normal text, and
 4.5:1 is the bar it misses. */
  color:rgba(255,255,255,.42);
  cursor:pointer;
  transition:color .35s ease;
}
.ftab:hover .ftab__name{ color:rgba(255,255,255,.72); }
.ftab.is-on .ftab__name{ color:var(--white); }
.ftab.is-on .ftab__rule{ background:rgba(255,255,255,.3); }

/* the panel opens by animating its own row height, so nothing jumps */
.ftab__panel{
  display:grid;
  grid-template-rows:0fr;
  opacity:0;
  transition:grid-template-rows .45s ease, opacity .3s ease;
}
.ftab.is-on .ftab__panel{ grid-template-rows:1fr; opacity:1; }
.ftab__panel > div{ min-height:0; overflow:hidden; }
.ftab__lede{
  margin-top:16px;
  font-size:16px;
  line-height:1.6;
  color:var(--muted);
  padding-bottom:20px;
}
.ftab__list{ margin:0; padding:0; list-style:none; }
.ftab__list li{
  position:relative;
  padding-left:28px;
  font-size:15px;
  line-height:1.5;
  color:rgba(255,255,255,.86);
}
.ftab__list li + li{ margin-top:12px; }
.ftab__list li::before{
  content:"";
  position:absolute;
  left:0; top:.25em;
  width:16px; height:16px;
  background:var(--a-check) no-repeat center/contain;
}

@media (max-width:900px){
  .feature{ grid-template-columns:minmax(0,1fr); gap:32px; }
}

/* ---------- the service panel: tabs, stat cards, charts -----------
   The right-hand panel is authored at 680x670 in Figma and everything
   inside it is placed as a share of that box, so the composition holds at
   any width. --------
   -------------------------------------------------------------------- */

.feature__media{
  display:grid;
  overflow:hidden;
  /* The veil inside carries a blur, and a filtered child is composited on its
 own layer: which Safari then declines to clip to this box's radius, so
 the panel came out with square corners there while Chromium rounded them. */
  clip-path:inset(0 round var(--r-lg));
  background:#130707;
}
.mset{
  grid-area:1/1;
  position:relative;
  opacity:0;
  visibility:hidden;
}
.mset.is-on{ opacity:1; visibility:visible; }
/* The photograph is blurred directly and a flat dark veil laid over it.
 Figma does this with a backdrop-filter, but a backdrop-filter here blurs the
 cards that sit on top of it too */
.mset--photo .mset__veil{
  position:absolute;
  inset:-40px;                     /* the blur must not pull in the panel edge */
  background-repeat:no-repeat;
  background-position:center;
  background-size:cover;
  filter:blur(20px);
}
.mset--photo::after{
  content:"";
  position:absolute;
  inset:0;
  background:rgba(0,0,0,.6);
  pointer-events:none;
}
.mset--calls .mset__veil{ background-image:var(--a-panel-calls); }
.mset--retention .mset__veil{ background-image:var(--a-panel-retention); }
.mset--intel .mset__veil{ background-image:var(--a-panel-intel); }
.mset--csi .mset__veil{ background-image:var(--a-panel-intel); }

/* ---------- the product window (first panel) ----------------------
   Figma drops a 1209x599 dashboard into the 680x670 panel at (120,96), so
   only its top-left corner is ever on screen: --------
   -------------------------------------------------------------------- */
.dash{
  position:absolute;
  left:17.647%;                    /* 120 of 680 */
  top:14.328%;                     /* 96 of 670 */
  width:177.794%;                  /* 1209 */
  aspect-ratio:1209/599;
  z-index:2;
  border-radius:24px;
  background:rgba(26,13,13,.8);
  backdrop-filter:blur(12px);          /* Figma: background blur 24 */
  -webkit-backdrop-filter:blur(12px);
  overflow:hidden;
  color:var(--white);
}
/* The rail and the bar are the window's chrome: the rule down the left and
 the one under the top strip are the two lines Figma draws as one vector. */
.dash__rail{
  position:absolute;
  left:0; top:0; bottom:0;
  width:3.722%;                    /* 45 */
  border-right:1px solid rgba(255,255,255,.08);
}
.dash__bar{
  position:absolute;
  left:3.722%; right:0; top:0;
  height:12.12%;                   /* the rule sits at 72.58 */
  border-bottom:1px solid rgba(255,255,255,.08);
}
.dash__mark,
.dash__ricon,
.dash__pill,
.dash__search,
.dash__wbtn{
  /* All of these are laid out against the window. They */
  position:absolute;
}
.dash__mark{
  left:1.314%; top:3.033%;
  width:1.017%;                    /* 12.29 of 1209 */
  aspect-ratio:12.29/21.8;
  background:var(--a-w-mark) no-repeat center/contain;
  opacity:.9;
}
.dash__ricon{
  left:.751%;                      /* 9.08, which centres 27.25 in the 45 rail */
  width:2.254%;
  aspect-ratio:1;
  border-radius:5px;
  background-repeat:no-repeat;
  background-position:center;
  background-size:58.3% 58.3%;     /* 15.9 of 27.25 */
  backdrop-filter:blur(6.8px);
  -webkit-backdrop-filter:blur(6.8px);
  opacity:.55;
}
.dash__ricon--1{ top:17.249%; background-image:var(--a-w-r1); background-color:rgba(255,255,255,.05); }
.dash__ricon--2{ top:24.832%; background-image:var(--a-w-r2); background-color:rgba(255,255,255,.05); opacity:1; }
.dash__ricon--3{ top:32.414%; background-image:var(--a-w-r3); }
.dash__ricon--4{ top:39.997%; background-image:var(--a-w-r4); }
.dash__ricon--5{ top:47.578%; background-image:var(--a-w-r5); }
.dash__pill,
.dash__search,
.dash__wbtn{
  top:4.549%;
  border-radius:9px;
  background-color:rgba(255,255,255,.1);
  background-repeat:no-repeat;
  /* Figma blurs behind each of these too, on top of the window's own blur */
  backdrop-filter:blur(6.8px);
  -webkit-backdrop-filter:blur(6.8px);
}
.dash__pill{
  left:5.259%; width:9.016%;
  aspect-ratio:109/27.25;
  background-image:var(--a-w-chev);
  background-position:right 5.2% center;
  background-size:14.6% auto;
}
.dash__search{
  left:42.167%; width:18.784%;
  aspect-ratio:227.09/27.25;
  background-image:var(--a-w-find);
  background-position:right 4% center;
  background-size:7% auto;
}
.dash__wbtn{
  width:2.254%;
  aspect-ratio:1;
  background-color:rgba(255,255,255,.05);
  background-position:center;
  background-size:58.3% 58.3%;
}
.dash__wbtn--min{ left:92.694%; background-image:var(--a-w-gear); }
/* a bell, despite what the Figma export called it */
.dash__wbtn--bell{ left:95.512%; background-image:var(--a-w-bell); }
.dash__head{
  position:absolute;
  left:6.451%; top:18.531%;
  font-family:var(--display);
  font-size:32px;
  line-height:1.3;
}
.dash__stat{ position:absolute; height:28.548%; width:27.461%; }
.dash__stat--a{ left:6.451%;  top:29.549%; }
.dash__stat--b{ left:35.897%; top:29.549%; }
/* 72 here, not the panel cards' clamp: these sit inside a window at
 the design's own scale, not across the full width of the composition. */
.dash__stat .stat__value{ margin-top:14px; font-size:72px; line-height:1.05; }
.dash__stat .stat__value em{ font-size:56px; }
.dash__chart{
  position:absolute;
  left:6.451%; top:62.104%;
  width:42.845%; height:36.895%;
  padding:24px;
}
.chartcard--deep{ background:#36000c; color:var(--white); }

/* Calls over time. Figma hands this over as a flat vector; it is redrawn as
 a path here because a flat vector cannot be made to draw itself, and
 drawing itself is the whole point of it. */
.wave{
  position:absolute;
  left:0; top:16.29%;              /* 36 of 221 */
  width:93.05%;                    /* 482 of 518 */
  height:133.48%;                  /* 295 of 221 */
  display:block;
}
.wave__line{ fill:none; stroke:#FF5F84; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
.wave__grid line{ stroke:rgba(255,255,255,.13); stroke-width:1; stroke-dasharray:2 7; }

/* The call button Figma parks on the panel itself, clear of the window. */

/* --- the data cards --- */
.stat{
  position:absolute;
  z-index:2;
  padding:24px 24px 0;
  border-radius:24px;
  overflow:hidden;
}
.stat--red{ background:linear-gradient(122deg,#FA0741 1.7%,#1A0D0D 106%); color:var(--white); }
.stat--cyan{ background:var(--cyan); color:#130707; }
/* the diagonal sheen Figma lays across each card */
/* Figma hangs a 420x525 vector off each card and lets the card clip it, so
 which ribbons show depends on how tall the card is. The box is given here
 in the card's own terms and the top is set per card height below. */
.stat__sheen,
.chartcard__sheen{
  position:absolute;
  left:-10.542%;                   /* -35 of 332 */
  width:126.506%;                  /* 420 of 332 */
  aspect-ratio:420/525;
  background-repeat:no-repeat;
  background-size:100% 100%;
  pointer-events:none;
}
.stat--red  .stat__sheen{ background-image:var(--a-sheen-red); }
.stat--cyan .stat__sheen{ background-image:var(--a-sheen-white); }
.dash__stat .stat__sheen{ top:-50.877%; }        /* -87 of 171 */
.mset--retention .stat__sheen{ top:-43.500%; }   /* -87 of 200 */
/* The light chart card carries the same vector at a different size and half
 strength: 478x597 hung 4 down from its own top edge. */
.chartcard--light .chartcard__sheen{
  left:0; top:1.170%;
  width:140.588%;                  /* 478 of 340 */
  aspect-ratio:478/597;
  opacity:.5;
  background-image:var(--a-sheen-white);
}
.stat__label{
  position:relative;
  font-size:12px;
  font-weight:600;
  letter-spacing:.08em;
  text-transform:uppercase;
}
.stat__value{
  position:relative;
  margin-top:18px;
  font-family:var(--display);
  font-size:clamp(2.5rem,6.1vw,5.5rem);
  line-height:1.05;
  font-variant-numeric:tabular-nums;
}
.stat__value em{ font-style:normal; font-size:.64em; }

/* --- the conversation --- */
.mset__msg{
  position:absolute;
  z-index:2;
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:8px;
  padding:16px;
  border-radius:16px;
  /* No edge on these. The blur and the fill are what hold the shape; a
 hairline around both of them was the thing making the two speakers read as
 one component. */
  backdrop-filter:blur(20px);
  -webkit-backdrop-filter:blur(20px);
  color:var(--white);
}
.mset__msg--flai{   background:rgba(26,13,13,.6); }
.mset__msg--caller{ background:rgba(255,255,255,.1); }
/* Figma sets DM Sans at optical size 14, which renders a shade narrower: without it the shortest turn wrapped to two lines and the card grew. */
.mset__msg p{ margin:0; font-size:16px; line-height:24px; font-variation-settings:'opsz' 14; }
.mset__time{ font-size:12px; font-weight:500; opacity:.5; }
/* Figma gaps the avatar from the message by 8 and the line from its stamp by
 4; one gap of 8 for all three was holding the stamp too far off. */
.mset__body{ display:flex; flex-direction:column; gap:4px; }
/* The three dots that stand in for the message while it is being typed. They
 are hidden until the panel's timeline raises them, so nothing shows them
 to anyone without scripting. */
.mset__typing{
  position:absolute;
  left:16px; top:56px;
  display:flex;
  align-items:center;
  gap:5px;
  height:20px;
  opacity:0;
}
.mset__typing i{
  width:6px; height:6px;
  border-radius:50%;
  background:currentColor;
  animation:mset-type 1.05s ease-in-out infinite;
}
.mset__typing i:nth-child(2){ animation-delay:.14s; }
.mset__typing i:nth-child(3){ animation-delay:.28s; }
@keyframes mset-type{
  0%,60%,100%{ transform:translateY(0);    opacity:.34; }
  30%        { transform:translateY(-3px); opacity:.85; }
}
@media (prefers-reduced-motion:reduce){
  .mset__typing i{ animation:none; }
}
.mset__av{
  /* flex:none, or it is, not a circle for the length of the animation. The
     bubble is a flex column whose height is animated from the typing height
     up to the full one, and a flex item shrinks along the main axis when its
     container is shorter than its contents: so the avatar was squashed into
     an oval every time a turn came in, and sprang back at the end. */
  flex:none;
  width:32px; height:32px;
  border-radius:50%;
  background-repeat:no-repeat;
  background-position:center;
  background-size:cover;
}
.mset__av--caller{  background-image:var(--a-hero-av-1); }
.mset__av--flai{ background:var(--a-send) no-repeat center/contain; }

/* --- the two chart cards --- */
.chartcard{
  position:absolute;
  z-index:2;
  display:flex;
  flex-direction:column;
  padding:40px;
  border-radius:24px;
  overflow:hidden;
}
.chartcard--light{ background:var(--cyan); color:#1A0D0D; }
.chartcard--red{ background:linear-gradient(122deg,#FA0741 1.7%,#1A0D0D 106%); color:var(--white); }
.chartcard__legend{
  position:relative;
  display:flex;
  gap:20px;
  margin-top:25px;
  font-size:15px;
  line-height:24px;
  white-space:nowrap;
}
.chartcard__legend span{ display:flex; align-items:center; gap:8px; }
.dot{ width:5px; height:5px; border-radius:50%; background:#1A0D0D; }
.dot--b{ background:#AABCBF; }

/* six bars, 12 wide on a 36 pitch, the tallest 165: Figma's own numbers */
.bars{
  position:relative;
  margin-top:32px;
  height:165px;
  display:flex;
  align-items:flex-end;
  gap:24px;
}
.bars i{
  position:relative;
  display:block;
  width:12px;
  height:var(--h);
  border-radius:16px;
  background:#AABCBF;          /* unassigned shop */
  transform-origin:50% 100%;
  overflow:hidden;
}
.bars i b{
  position:absolute;
  left:0; right:0; bottom:0;
  height:var(--d);
  border-radius:16px;
  background:#1A0D0D;          /* main shop */
}

/* Figma draws the trend 360 wide inside a 340 card, sitting on its floor: so it runs past the right edge not being squashed to fit. */
.spark{
  position:absolute;
  left:0; bottom:0;
  width:105.88%;     /* 360 of 340 */
  height:40.64%;     /* 139 of 342 */
  display:block;
}
/* the stroke and the wash both come straight from the Figma export */
.spark__line{ fill:none; stroke:#70001A; stroke-width:4; stroke-linecap:round; stroke-linejoin:round; }

/* Below this the 680x670 composition has nowhere to go, so the pieces leave
 their Figma coordinates and stack in reading order. */
@media (max-width:1100px){

  .mset{
    display:flex;
    flex-direction:column;
    gap:16px;
    padding:24px;
  }
  .mset .stat,
  .mset .mset__msg,
  .mset .chartcard{
    position:relative;
    left:auto !important;
    top:auto !important;
    width:auto !important;
    height:auto !important;
  }
  /* The stack ran 721 tall, which is most of a screen for one panel of four.
 The cards keep their proportions and give back the padding and the figure
 size they were carrying from the desktop composition. */
  .mset .stat{ padding:20px 20px 18px; }
  .mset .chartcard{ padding:20px; }
  .mset .stat__value{ font-size:clamp(2rem,7.5vw,2.75rem); }
  .mset .bars{ height:96px; }
  /* the intel panel is the tallest of the four and it is what the shared grid
 area is sized to, so this is where the height actually comes from */
  .mset .chartcard__legend{ font-size:13px; gap:14px; }
  .mset__msg{ padding:14px; gap:6px; }
  .mset__msg p{ font-size:15px; line-height:21px; }
  .mset__av{ width:28px; height:28px; }
  .mset__typing{ left:14px; top:48px; }
  .mset__msg{ align-self:flex-start; max-width:100%; }
  .stat__value{ font-size:clamp(2.25rem,9vw,3.5rem); }
  .bars{ height:120px; }
  .spark{ position:relative; width:100%; height:120px; margin-top:20px; }
  .chartcard__legend{ white-space:normal; flex-wrap:wrap; gap:12px; font-size:14px; }

  /* The product window is a crop: it only says anything where there is width
 to crop away. Down here the chrome goes and the two figures and the chart
 it holds join the stack with everything else. */
  .dash{
    position:static;
    width:auto;
    aspect-ratio:auto;
    display:flex;
    flex-direction:column;
    gap:12px;
    background:none;
    border-radius:0;
    overflow:visible;
  }
  .dash__rail,
  .dash__bar,
  .dash__head{ display:none; }
  .mset .dash__stat .stat__value{ font-size:clamp(2rem,7.5vw,2.75rem); margin-top:10px; }
  .mset .dash__stat .stat__value em{ font-size:.75em; }
  .wave{ position:relative; top:auto; width:100%; height:120px; margin-top:12px; }
}

/* ---------- feature ---------- */

/* The page gradient is nearly white by this depth, so the white panel had
 nothing to sit against. This carries the hero's cyan down behind the
 section, fading in and out so there is no band edge. */
.feature::before{
  content:"";
  position:absolute;
  z-index:-1;
  inset:-140px calc(50% - 50vw) -160px;
  pointer-events:none;
  background:linear-gradient(180deg,
    rgba(206,232,235,0)   0%,
    rgba(206,232,235,.75) 26%,
    rgba(206,232,235,.75) 74%,
    rgba(206,232,235,0)   100%);
}

.feature{ position:relative; }
/* the section's own heading, outside both cards */
.feature__title{
  grid-column:1/-1;
  margin:0;
  text-align:center;
  font-size:clamp(2.25rem,4.44vw,4rem);
  line-height:1.1;
}
/* The line under the claim. Held to 640 and centred with it: full width the
 sentence would run the whole 1376 and stop reading as a subtitle. */
.feature__lede{
  grid-column:1/-1;
  max-width:640px;
  /* 104 down to the panel: the grid's own row gap is 0 here, so this margin
 is the whole distance and the figure reads straight. */
  margin:16px auto 104px;
  text-align:center;
  font-size:16px;
  line-height:1.55;
  color:var(--muted);
}
@media (max-width:900px){
  .feature__lede{ margin-bottom:32px; }
}
.feature__media{
  position:relative;
  overflow:hidden;
  border-radius:var(--r-lg);
  min-height:670px;
  background:var(--a-feature-photo) no-repeat center/cover var(--ink);
}

@media (max-width:900px){
  .feature__media{ min-height:520px; }
}

/* ---------- marquee ---------- */

/* ---------- case studies ---------- */

.cases{
  margin-top:121px;
  padding-bottom:0;
  /* the white runs the width of the screen: no card, no rounded corners. The
 shell class */
  width:100vw;
  margin-inline:calc(50% - 50vw);
  background:var(--white);
}
.cases__panel{
  max-width:var(--max);
  margin-inline:auto;
  /* the 120 that */
  padding:104px var(--gutter) 0;
}
.eyebrow{
  display:flex;
  align-items:center;
  justify-content:center;
  gap:8px;
  font-size:12px;
  font-weight:600;
  letter-spacing:.08em;
}
/* masked not painted, so the mark inherits currentColor and a red
 eyebrow comes out red all the way through */
.eyebrow::before{
  content:"";
  width:16px; height:16px;
  background:currentColor;
  -webkit-mask:var(--a-eyebrow-icon) no-repeat center/contain;
  mask:var(--a-eyebrow-icon) no-repeat center/contain;
}
.cases__title{
  margin-top:16px;
  text-align:center;
  font-size:clamp(2.25rem,4.44vw,4rem);
  line-height:1;
}
/* An endless rail, not a 2x2 grid. The row is advanced on the ticker
 with the same wrap the marquee uses, so it costs one transform, and it
 stops while you are hovering it so the cards stay clickable. */
/* Breaks out of the panel and the shell to run the full width of the
 viewport. body already hides horizontal overflow, so the vw maths cannot
 introduce a scrollbar. */
.cases__carousel{
  margin:80px calc(50% - 50vw) 0;
  width:100vw;
  overflow:hidden;
}
.cases__row{
  display:flex;
  width:max-content;
  will-change:transform;
}
.cases__unit{
  display:flex;
  gap:16px;
  padding-right:16px;
  flex:none;
}
.cases__unit .case{
  flex:none;
  width:564px;
}

.case{
  position:relative;
  overflow:hidden;
  border-radius:var(--r-lg);
  aspect-ratio:564/491;
  color:var(--white);
  background-color:var(--ink);
  isolation:isolate;
  display:block;
}
/* a 20% wash on hover, under the labels and over the photograph */
.case::before{
  content:"";
  position:absolute;
  inset:0;
  z-index:1;
  background:rgba(0,0,0,.2);
  opacity:0;
  pointer-events:none;
  transition:opacity .45s ease;
}
.case:hover::before,
.case:focus-visible::before{ opacity:1; }

.case__img{
  position:absolute;
  left:0; top:0;
  width:100%; height:100%;
  background-repeat:no-repeat;
  background-position:center;
  background-size:cover;
  transform:scale(var(--s,1.02));
  transition:transform .9s cubic-bezier(.22,1,.36,1);
}
.case:hover .case__img{ --s:1.07; }

.case::after{
  content:"";
  position:absolute;
  inset:0;
  /* Figma only scrims the foot of the card, which works while every photo
 happens to be dark up top. The new portrait is shot against pale glass, so
 a light touch at the head keeps the dealership name legible on all four. */
  background:
    linear-gradient(180deg,rgba(0,0,0,.46) 0%,rgba(0,0,0,.4) 18%,rgba(0,0,0,0) 36%),
    linear-gradient(180deg,rgba(0,0,0,0) 50%,rgba(0,0,0,.6) 100%);
  pointer-events:none;
}
/* 107:9 frame 63 -> h 143.56%, top -15.49%, w 100% */
/* One photograph per dealership, cropped to the card's own shape not
 squashed into it. */
.case--1 .case__img{ background-image:url("assets/img/case-southpoint.webp"); }
.case--4 .case__img{ background-image:url("assets/img/case-freeman.webp"); }
.case--5 .case__img{ background-image:url("assets/img/case-audimarin.webp"); }
/* 107:22 frame 92 -> h 191.39%, top -16.11%, left -8.24%, w 110.99% */
.case--2 .case__img{
  left:-8.24%; top:-16.11%; width:110.99%; height:191.39%;
  background-image:var(--a-case-2); background-size:100% 100%;
}
.case--3 .case__img{ background-image:var(--a-case-3); }
/* 107:27 two stacked cover fills */
/* slots 5 and 6 borrow photographs from 4a and 2 at different crops; swap in
 the real dealership shots when they exist */
.case--6 .case__img{
  left:-14%; top:-20%; width:120%; height:200%;
  background-image:var(--a-case-2); background-size:100% 100%;
}

.case__name,
.case__stat,
.case__cta{ position:absolute; z-index:2; }
.case__name{
  left:24px; top:33px;
  font-size:clamp(1rem,1.39vw,1.25rem);
  line-height:1.3;
  font-weight:500;
  letter-spacing:-.02em;
}
/* The stat keeps its exact Figma box; the blurb hangs above it, out of the
 flow, so revealing it cannot move the number. */
.case__foot{
  position:absolute;
  left:24px; right:24px; bottom:24px;
  z-index:2;
}
/* The quotation runs to three or four lines, so the veil under it starts
   higher up the picture than a single line would need. */
.case__foot::before{
  content:"";
  position:absolute;
  z-index:-1;
  left:-24px; right:-24px; bottom:-24px; top:-96px;
  background:linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,.55) 42%, rgba(0,0,0,.82) 100%);
  pointer-events:none;
}
/* these are films, so each card says so quietly */
.case__play{
  position:absolute;
  z-index:2;
  left:50%; top:50%;
  width:56px; height:56px;
  display:grid;
  place-items:center;
  border-radius:50%;
  background:rgba(255,255,255,.13);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.34);
  opacity:.72;
  transform:translate(-50%,-50%) scale(1);
  transition:opacity .4s ease, transform .55s cubic-bezier(.22,1,.36,1),
             background-color .4s ease;
}
.case__play::before{
  content:"";
  width:12px; height:14px;
  margin-left:3px;                 /* optical centring of the triangle */
  background:var(--a-play) no-repeat center/contain;
}
.case:hover .case__play,
.case:focus-visible .case__play{
  opacity:1;
  transform:translate(-50%,-50%) scale(1.07);
  background:rgba(255,255,255,.2);
}

.case__stat{
  position:static;
  display:block;
  font-family:var(--display);
  font-size:24px;
  line-height:1.2;
  text-wrap:pretty;
}
/* The plate and the arrow They
 are two things now: */
.case__cta{
  right:25px; top:24px;
  width:42.73px; height:42.57px;
  border-radius:16px;
  background:var(--cyan);
  display:grid;
  place-items:center;
}
.case__cta::before{
  content:"";
  width:16px; height:16px;
  background:var(--ink);
  -webkit-mask:var(--a-arrow) no-repeat center/contain;
  mask:var(--a-arrow) no-repeat center/contain;
  transition:transform .5s cubic-bezier(.22,1,.36,1);
}
/* Cards two and four used a second plate asset that differed from the first
 only in how its corners were drawn. One CSS plate covers all of them. */
/* Up and to the right. Negative because CSS turns clockwise. */
.case:hover .case__cta::before,
.case:focus-visible .case__cta::before{ transform:rotate(-45deg); }

@media (max-width:900px){
  /* Taller than the 564:491 the desktop card keeps: at 78vw that ratio left
 them 265 high, which is a strip, not a card. */
  .cases__unit .case{ width:min(78vw,480px); aspect-ratio:auto; height:470px; }
  /* and the rail answers to a finger */
  .cases__carousel{ touch-action:pan-y; cursor:grab; }
  .cases__carousel.is-dragging{ cursor:grabbing; }
  .cases__carousel.is-dragging .case{ pointer-events:none; }
}
@media (max-width:760px){
  .cases{ margin-top:80px; padding-bottom:64px; }
  .cases__panel{ padding:64px var(--gutter) 64px; }
  .cases__carousel{ margin-top:64px; }
}
/* the rail runs past the panel's rounded corners, so it must not be clipped */
.cases__panel{ overflow:visible; }

/* ---------- loader ---------- */

/* Only shown when scripting is on, so a no-JS visitor never meets a curtain
 that cannot lift. The panel colour is the same #1A0D0D the Lottie artwork
 is drawn on, so the two read as one surface. */
.loader{ display:none; }
.js .loader{
  position:fixed;
  inset:0;
  z-index:200;
  display:grid;
  place-items:center;
  background:var(--ink);
  /* the canvas runs wider than the screen on a phone so the gauge can be
 read; the ink either side of it is what gets clipped here */
  overflow:hidden;
  will-change:transform;
}
.loader__art{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
}
/* The loader on a phone. Two things were wrong and only one of them was
   the fit. The container was the whole viewport with the art set to cover
   it, so on a 390x844 screen a 16:9 composition was scaled up by the
   height and lost most of its width off both sides. */
@media (max-width:900px){
  .loader__art{
    /* Centred with a transform not left to the grid. A grid item wider than
       its track does not overflow evenly: it gets clipped from the start edge,
       which left a 20px slice of the gauge against the left of the screen
       instead of the gauge in the middle. */
    position:absolute;
    inset:auto;                 /* first: it is a shorthand and resets the two below */
    left:50%; top:50%;
    transform:translate(-50%, -50%);
    width:min(calc(100vw * 2.4), calc((100vh - 8px) * 16 / 9));
    height:auto;
    aspect-ratio:640/360;
  }
}
@supports (height: 1dvh){
  @media (max-width:900px){
    .loader__art{ width:min(calc(100vw * 2.4), calc((100dvh - 8px) * 16 / 9)); }
  }
}
html.is-loading,
html.is-loading body{ overflow:hidden; }

/* used only when GSAP is unavailable */
.loader.is-done{
  opacity:0;
  visibility:hidden;
  transition:opacity .7s ease, visibility .7s;
}

@media (prefers-reduced-motion:reduce){
  .js .loader{ display:none; }
}

/* ---------- built to connect ---------- */

.bl{
  margin-top:120px;
  /* Figma: the frame is the full 1440 with clipsContent off, so this runs the
 width of the viewport instead of sitting inside the shell. That is also
 what gives the outer orbit room to carry its logos without clipping. */
  width:100vw;
  margin-inline:calc(50% - 50vw);
}
.bl__stage{
  position:relative;
  /* Figma's frame clips the rings where they run past it, and so must this:
 left unclipped they push the document wider than the viewport */
  overflow:hidden;
  /* no min-height alongside this: a minimum height with an aspect ratio makes
 the box grow sideways to satisfy the ratio, which pushed the document
 wider than the viewport on every phone size */
  aspect-ratio:1440/1017;
}
/* the four rings, drawn once. Figma hangs them off the frame by 131/126. */
/* Uniform scale, deliberately. The artwork was being stretched 18% wider than
 tall, which threw the third ring off both sides of the frame; at 1:1 that
 ring sits fully on screen and clears the headline */
.bl__orbits{
  position:absolute;
  left:0; top:-12.4%;
  width:100%; height:124.8%;
  background:var(--a-orbits) no-repeat center/100% 100%;
  pointer-events:none;
}
.bl__text{
  position:absolute;
  left:50%; top:42.1%;
  transform:translateX(-50%);
  width:min(747px,86%);
  text-align:center;
}
.bl__eyebrow{ color:var(--red); }
.bl__title{
  margin-top:14px;
  font-size:clamp(2.25rem,4.44vw,4rem);
  line-height:1.1;
}
.bl__lede{ margin-top:14px; font-size:16px; line-height:24px; }

/* Two boxes on purpose: the outer one is driven along its ellipse by the
 ticker, the inner one carries the entrance (opacity, scale, blur). Sharing
 one element would mean GSAP and the orbit fighting over transform. */
.bl__logo{
  position:absolute;
  left:0; top:0;
  display:block;
  will-change:transform;
}
.bl__logo i{
  position:absolute;
  inset:0;
  display:block;
  border-radius:16px;
  /* Figma frosts these with a background blur, but they travel their orbit
 every frame and a moving backdrop-filter has to resample the page behind
 it each time: */
  background:var(--white);
  box-shadow:0 2px 18px rgba(26,13,13,.06), 0 1px 3px rgba(26,13,13,.04);
}
/* The logo is sized as a fraction of its own card not inset by a
 flat number: Figma pads each card differently, and a single 32px inset
 left the 184x70 ones with six pixels of height to draw into. */
.bl__logo i::before{
  content:"";
  position:absolute;
  inset:0;
  background-repeat:no-repeat;
  background-position:center;
}
.bl__logo--tekion i::before{ background-image:var(--a-bl-tekion); background-size:68.0% auto; }
.bl__logo--mykaarma i::before{ background-image:var(--a-bl-mykaarma); background-size:69.4% auto; }
.bl__logo--vauto i::before{ background-image:var(--a-bl-vauto); background-size:73.9% auto; }
.bl__logo--reynolds i::before{ background-image:var(--a-bl-reynolds); background-size:68.0% auto; }
.bl__logo--xtime i::before{ background-image:var(--a-bl-xtime); background-size:73.9% auto; }
.bl__logo--dealerfx i::before{ background-image:var(--a-bl-dealerfx); background-size:67.8% auto; }
.bl__logo--cdk i::before{ background-image:var(--a-bl-cdk); background-size:auto 63.6%; }
.bl__logo--dr i::before{ background-image:var(--a-bl-dr); background-size:42.9% auto; }
/* these four arrive as white artwork for dark ground, so they are flipped
 to read on the white plate the others sit on */
.bl__logo--solera i::before,
.bl__logo--autolive i::before,
.bl__logo--updatepromise i::before,
.bl__logo--vinsolutions i::before{ filter:invert(1); }
.bl__logo--solera i::before{ background-image:var(--a-bl-solera); background-size:auto 11.5%; }
.bl__logo--autolive i::before{ background-image:var(--a-bl-autolive); background-size:47.6% auto; }
.bl__logo--updatepromise i::before{ background-image:var(--a-bl-updatepromise); background-size:70.0% auto; }
.bl__logo--vinsolutions i::before{ background-image:var(--a-bl-vinsolutions); background-size:74.0% auto; }

@media (max-width:900px){
  .bl{ margin-top:80px; }
  .bl__stage{ aspect-ratio:1440/1320; }
}
/* The orbit stays an orbit on a phone. Not shrinking the whole composition
   into 390: where the rings would be thumbnails and the cards would have
   no arc to travel, the stage keeps a width of its own and the viewport
   crops it */
@media (max-width:760px){
  .bl{ overflow:hidden; }
  .bl__stage{
    width:760px;
    margin-left:calc(50% - 380px);
    aspect-ratio:1440/1210;
  }
  /* Shrunk by its own box not by a transform: the entrance writes an inline
     transform on this layer, so a CSS scale here loses to it. Insetting
     leaves the outer box: the one the orbit moves and the script measures to
     centre each mark, exactly as */
  /* Every card the same size, and the size is the largest of them: VinSolutions' 97 by 50. They were coming out anywhere from 68x34 to 97x50,
 because each outer box carries the width Figma gave that logo and the card
 was a percentage inset of it. */
  .bl__logo i{
    inset:0;
    margin:auto;
    width:97px;
    height:50px;
    border-radius:11px;
  }
  .bl__logo i::before{
    inset:9px 12px;
    background-size:contain;
    background-position:center;
  }
  /* the words keep the page's own margins, not the stage's, which is
 what had this one line running edge to edge while everything above it
 sat inside the gutter */
  .bl__text{ width:calc(100vw - var(--gutter) * 2); }
  .bl__title{ font-size:clamp(1.875rem,9vw,2.5rem); }
}

/* The hidden start state lives in the script, not here: the head sets.js
 whether or not GSAP actually arrives, so a CSS-only guard would leave the
 section blank any time the CDN is blocked. */

/* ---------- listen to flai ---------- */

.listen{ margin-top:120px; }
.listen__stage{
  position:relative;
  overflow:hidden;
  border-radius:var(--r-lg);
  background:var(--ink);
  color:var(--white);
  padding:112px var(--gutter) 104px;
}
.listen__title{
  margin:0 auto;
  max-width:678px;
  text-align:center;
  font-size:clamp(2.25rem,4.44vw,4rem);
  line-height:1.3;
}
.listen__lede{
  margin:8px auto 0;
  max-width:680px;
  text-align:center;
  font-size:16px;
  line-height:24px;
}

/* the haze the design lays over the foot of the panel. Figma also backdrop
 blurs it, but the wave underneath is animating, so a per-frame backdrop
 blur over this area is not worth the cost; the gradient carries it. */
.listen__haze{
  position:absolute;
  left:0; right:0; bottom:0;
  height:310px;
  z-index:1;
  pointer-events:none;
  background:linear-gradient(180deg,rgba(128,64,64,0) 0%,rgba(26,13,13,.1) 100%);
}

/* ---- the app window (Figma 179:8538) ---- */
.lw{
  position:relative;
  z-index:2;
  width:100%;
  max-width:1065px;
  /* 72 down from the lede. */
  margin:72px auto 0;
  padding:8px 8px 8px 40px;     /* the left strip is the icon rail */
  border-radius:16px;
  /* Figma: Main background is white at 5%, and it is the lighter of the two
 surfaces: the content panel inside it is the dark one. The background
 blur Figma also puts here is left off: */
  background:rgba(255,255,255,.05);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.07),
             0 40px 90px rgba(0,0,0,.45);
}
.lw__rail{
  position:absolute;
  left:0; top:0; bottom:0;
  z-index:2;
  width:40px;
  display:flex;
  flex-direction:column;
  align-items:center;
  padding:16px 0 8px;           /* Figma: the avatar sits 8px off the bottom */
}
/* Figma slides a #FA0741 gradient in behind the rail and clips it to the
 window, which is the crimson bleed down the left edge. */
/* Measured off the design: the light fills the rail's full width, runs from
 about 7% to 57% of its height and peaks at 51, fading slowly upward and
 more sharply below. */
.lw__rail::before{
  content:"";
  position:absolute;
  z-index:-1;
  inset:0;
  border-radius:16px 0 0 16px;
  background:linear-gradient(90deg,
    rgba(250,7,65,.92) 0%, rgba(250,7,65,.74) 52%, rgba(250,7,65,.36) 100%);
  -webkit-mask-image:linear-gradient(180deg,
    transparent 3%, rgba(0,0,0,.26) 14%, #000 48%, #000 56%,
    rgba(0,0,0,.4) 60%, transparent 66%);
  mask-image:linear-gradient(180deg,
    transparent 3%, rgba(0,0,0,.26) 14%, #000 48%, #000 56%,
    rgba(0,0,0,.4) 60%, transparent 66%);
  pointer-events:none;
}
/* Figma has no wash across the window itself: the fill is flat and the only
 coloured light is the one behind the rail. */
.lw__mark{
  width:11px; height:19px;
  background:var(--a-w-mark) no-repeat center/contain;
  opacity:.9;
}
.lw__ricon{
  width:24px; height:24px;
  margin-top:16px;
  border-radius:4px;   /* Figma */
  background-repeat:no-repeat;
  background-position:center;
  background-size:14px 14px;
  opacity:.55;
}
.lw__ricon--1{ margin-top:56px; background-image:var(--a-w-r1); }
.lw__ricon--2{ background-color:rgba(255,255,255,.12); opacity:1; }
.lw__ricon--2{ background-image:var(--a-w-r2); }
.lw__ricon--3{ background-image:var(--a-w-r3); }
.lw__ricon--4{ background-image:var(--a-w-r4); }
.lw__ricon--5{ background-image:var(--a-w-r5); }
.lw__me{
  margin-top:auto;
  width:24px; height:24px;
  border-radius:50%;
  display:grid;
  place-items:center;
  background:var(--cyan);           /* the design's pale blue disc */
  color:var(--ink);
  box-shadow:0 0 22px rgba(206,232,235,.45);
  font-size:10px;
  font-weight:500;
  letter-spacing:.02em;
}

.lw__content{
  position:relative;
  border-radius:12px;
  background:#110606;
  overflow:hidden;
}
.lw__bar{
  position:relative;
  display:flex;
  align-items:center;
  gap:8px;
  height:56px;                    /* Figma: content top strip is 56 tall */
  padding:0 16px;
  border-bottom:1px solid rgba(255,255,255,.08);
}
/* Figma: a 96x24 selector at 16 from the left, and a 200x24 search field
 centred on the bar with its magnifier at the right end. */
.lw__pill{
  width:96px; height:24px;
  border-radius:8px;
  background:rgba(255,255,255,.07) var(--a-w-chev) no-repeat right 6px center;
  background-size:auto, 12px 12px;
}
.lw__search{
  position:absolute;
  left:50%;
  transform:translateX(-50%);
  width:200px; height:24px;
  border-radius:8px;
  background:rgba(255,255,255,.07) var(--a-w-find) no-repeat right 7px center;
  background-size:auto, 12px 12px;
}
.lw__wbtn{
  width:24px; height:24px;
  border-radius:8px;   /* Figma */
  background:rgba(255,255,255,.04) no-repeat center;
  background-size:14px 14px;
  opacity:.85;
}
.lw__wbtn--gear{ margin-left:auto; background-image:var(--a-w-gear); }
/* --a-w-close does not exist, so this button has been drawing nothing: an empty square beside the gear. The bell's own token is right here. */
.lw__wbtn--bell{ background-image:var(--a-w-bell); }

.lw__body{
  position:relative;
  min-height:497px;              /* 56 more than Figma: the chat was tight */
}
/* The conversation runs like a real thread: new turns arrive at the foot and
 push the older ones up, where they slide under the chrome bar, blur and
 dissolve. */
.lw__stream{
  position:absolute;
  inset:0;
  z-index:2;
  overflow:hidden;
}
.lw__body::before{
  content:"";
  position:absolute;
  left:0; right:0; top:0;
  height:22%;
  z-index:3;                     /* over the stream, under the chrome */
  pointer-events:none;
  background:linear-gradient(180deg,
    #110606 0%,
    rgba(17,6,6,.7) 27%,
    rgba(17,6,6,0) 100%);
}
.lw__stream::after{
  content:"";
  position:absolute;
  left:0; right:0; top:0;
  /* 72px at blur(5) not 96 at blur(7): measured 58fps against 47,
 and the softening reads the same once the mask above has faded it */
  height:72px;
  pointer-events:none;
  backdrop-filter:blur(5px);
  -webkit-backdrop-filter:blur(5px);
  -webkit-mask-image:linear-gradient(180deg,#000 0,#000 30%,transparent 100%);
  mask-image:linear-gradient(180deg,#000 0,#000 30%,transparent 100%);
}
/* the haze Figma lays across the foot of the window */
.lw__body::after{
  content:"";
  position:absolute;
  left:0; right:0; bottom:0;
  height:101px;
  pointer-events:none;
  background:linear-gradient(180deg,rgba(26,13,13,0) 0%,rgba(26,13,13,.55) 100%);
}
.lw__talk{
  position:absolute;
  right:24px; bottom:24px;        /* Figma sits it 8 off the corner; this is
 the extra breathing room asked for */
  z-index:3;
  display:flex;
  /* the mark carries it on its own now: no pill, no label */
}
.lw__talk i{
  width:28px; height:28px;
  border-radius:50%;
  display:grid;
  place-items:center;
  /* the spark has to be the first layer: background paints layer one on top,
 so with the gradient listed first */
  background:var(--a-w-spark) no-repeat center / 14px 14px,
             linear-gradient(140deg,var(--red),#7a0722);
  box-shadow:0 0 14px rgba(250,7,65,.55);
}
/* the bubbles get their own row: with the wave as a sibling of this, the
 alternation cannot be thrown off by an extra element in the flow */
.listen__thread{
  z-index:2;
  position:absolute;
  left:139px; right:60px; bottom:56px;   /* the design's own column insets */
  display:flex;
  flex-direction:column;
  gap:10px;
  /* deliberately no will-change here: it makes this element a backdrop root,
 which cut the bubbles off from the wave behind them and left their
 backdrop-filter with nothing to blur */
}
.listen__bubble{
  width:min(395px,46%);
  max-width:100%;
  display:flex;
  flex-direction:column;
  gap:4px;
  padding:16px 24px;
  border-radius:8px;
  background:rgba(255,255,255,.05);
  /* Figma specifies 24; pushed to 36 so the bars behind clearly smear.
 It only reads at all because nothing between these bubbles and the
 wave creates a backdrop root any more. */
  backdrop-filter:blur(36px);
  -webkit-backdrop-filter:blur(36px);
  font-size:16px;
  line-height:24px;
}
/* Who is speaking decides the side, not the position in the list. It */
.listen__bubble--you{ align-self:flex-end; }
/* and the caller's mark mirrors to the edge its bubble is on */
.listen__bubble--you::after{ left:auto; right:0; }
/* Each turn is signed beside its bubble: Flai's circular mark on the right,
 the caller's initials on the left, both clear of the text column. */
.listen__bubble{ position:relative; }
.listen__bubble::after{
  content:"";
  position:absolute;
  left:0;
  top:calc(100% + 8px);           /* below the bubble, on its left edge */
  width:32px; height:32px;
  border-radius:50%;
  background:var(--a-caller) no-repeat center/cover, rgba(255,255,255,.14);
}
.listen__bubble--flai::after{
  content:"";
  background:var(--a-send) no-repeat center/contain;
}
.listen__time{ font-size:12px; font-weight:500; line-height:normal; opacity:.5; }

/* the wave sits behind the conversation, centred on the window body */
/* The wave lives inside the stream on purpose. The stream carries a mask,
   and a mask starts a new backdrop root: with the wave outside it the
   bubbles' backdrop-filter had nothing to sample and they read as flat
   panels over the bars instead of frosted glass. */
.listen__wave{
  position:absolute;
  left:50%; top:50%;
  transform:translate(-50%,-50%);
  z-index:1;                    /* behind the thread, which sits at 2 */
  pointer-events:none;
}
.listen__bars{
  position:relative;
  width:332px;                  /* Figma: 36 bars, 3px wide on a 9.4px pitch */
  height:88px;
}
/* Every bar is the full 88 tall and gets trimmed by a clip-path whose inset
 animates. scaleY squashed the corner radius into flat ends; height keeps
 the 3px radius intact so the caps stay full pills. */
.listen__bars i{
  position:absolute;
  top:50%;
  width:3px;
  border-radius:999px;
  background:var(--red);
  transform:translateY(-50%);
  contain:layout size;          /* the bar's box cannot affect anything else */
}

@media (max-width:900px){
  .listen{ margin-top:80px; }
  .listen__stage{ padding:72px var(--gutter) 64px; }
  /* the two headings keep the same distance from their panel down here too */
  .lw{ margin-top:64px; padding:8px; }
  .lw__rail{ display:none; }
  .lw__pill--lg{ display:none; }
  .lw__body{ min-height:340px; }
  .listen__thread{ left:16px; right:16px; bottom:40px; }
  .listen__bubble{ width:min(340px,72%); }
  .listen__bars{ zoom:.74; }
}
@media (max-width:620px){
  .lw__body{ min-height:300px; }
  .listen__thread{ left:8px; right:8px; bottom:36px; }
  .listen__bubble{ width:86%; }
  .listen__bubble::after{ left:auto; right:-4px; bottom:-38px; }
  .listen__bubble--flai::after{ right:auto; left:-4px; bottom:-38px; }
  .listen__thread{ gap:46px; }
}

/* ---------- faq (pre-footer) ---------- */

.eyebrow--start{ justify-content:flex-start; }

.faq{
  position:relative;
  margin-top:32px;
  padding:96px 0 102px;
  background:linear-gradient(180deg,var(--cyan) 0%,var(--white) 100%);
}
.faq__grid{
  margin-top:16px;
  display:grid;
  grid-template-columns:564px minmax(0,680px);
  gap:76px;          /* Figma: intro at 32, list at 672 */
  align-items:start;
}
.faq__title{
  font-size:clamp(2.25rem,4.44vw,4rem);
  line-height:1;
}
.faq__lede{ margin-top:24px; font-size:16px; line-height:24px; }

.faq__list{ display:flex; flex-direction:column; gap:32px; }

.faq__item{ border-bottom:1px solid rgba(26,13,13,.1); }
/* Figma puts the answer in the same column as the question, with the +/- to
 its right. Kept in the flow, that 32px control set the row height and shoved
 the answer 13px further down than the 8px the design asks for */
.faq__q{
  position:relative;
  display:flex;
  align-items:center;
  width:100%;
  min-height:56px;                /* border-box: the 32px control + 24 padding */
  padding:0 74px 24px 0;          /* 40 gap + 34 control */
  text-align:left;
  cursor:pointer;
  /* The row loses 24px of padding and its 56px floor the moment a panel opens.
 Left to the class change alone that happens in one frame, so the question
 jumped while the answer was still unfolding beneath it. */
  transition:min-height .52s cubic-bezier(.22,1,.36,1),
             padding-bottom .52s cubic-bezier(.22,1,.36,1);
}
/* Figma keeps question and answer in one column 8px apart, with the 16px
 sitting under the answer. Leaving the button's own bottom padding in place
 stacked the two and pushed the answer 24px down. */
.faq__item.is-open .faq__q{ min-height:0; padding-bottom:0; }
/* Open, the row is exactly its one line of text: 19px, which is under the
   24 a target needs and the one you have to hit again to close it. The hit
   area is stretched back over the space the collapse gave up, so the
   button is reachable without the question or the answer moving a pixel. */
.faq__item.is-open .faq__q::before{
  content:"";
  position:absolute;
  left:0; right:0;
  top:-8px; bottom:-5px;
}
.faq__label{ display:flex; align-items:center; gap:16px; flex:1; min-width:0; }
.faq__label::before{
  content:"";
  flex:none;
  align-self:flex-start;          /* held on the first line in both states */
  margin-top:2px;
  width:16px; height:16px;
  background:var(--a-check) no-repeat center/contain;
}
.faq__label span{ font-size:16px; line-height:normal; font-weight:500; }
.faq__toggle{
  position:absolute;
  right:0;
  top:0;
  display:grid;
  place-items:center;
  padding:8px;
  border-radius:8px;
  background:rgba(26,13,13,.05);
  /* No backdrop-filter here. What sits behind these is the card's own
 vertical gradient, and blurring a gradient returns the same gradient: so it bought nothing and cost eight composited layers that had to be
 repainted on every frame of the expand. */
}
.faq__toggle i{
  display:block;
  width:17.6px; height:16px;
  background:var(--a-faq-plus) no-repeat center/contain;
  transition:opacity .26s ease, transform .52s cubic-bezier(.22,1,.36,1);
}
/* The minus rides underneath the plus and they trade places, not the
 one background swapping out on the class change. */
.faq__toggle::after{
  content:"";
  position:absolute;
  inset:8px;
  background:var(--a-faq-minus) no-repeat center/contain;
  opacity:0;
  transform:rotate(-90deg);
  transition:opacity .26s ease, transform .52s cubic-bezier(.22,1,.36,1);
}
.faq__item.is-open .faq__toggle i{ opacity:0; transform:rotate(90deg); }
.faq__item.is-open .faq__toggle::after{ opacity:1; transform:none; }

.faq__a{
  overflow:hidden;
  height:0;
  transition:height .52s cubic-bezier(.22,1,.36,1);
  font-size:14px;
  line-height:normal;
}
.faq__a p{
  /* 32 clears the bullet, 74 clears the control column: the same 574 text
 measure Figma gives the answer, so it wraps identically */
  padding:8px 74px 16px 32px;
  /* the answer arrives not being revealed by the clip alone */
  opacity:0;
  transform:translateY(-6px);
  transition:opacity .3s ease, transform .52s cubic-bezier(.22,1,.36,1);
}
.faq__item.is-open .faq__a p{ opacity:1; transform:none; }

@media (prefers-reduced-motion:reduce){
  .faq__q, .faq__a, .faq__a p,
  .faq__toggle i, .faq__toggle::after{ transition:none; }
}

@media (max-width:1000px){
  .faq{ padding:64px 0 72px; }
  .faq__grid{ grid-template-columns:minmax(0,1fr); gap:40px; }
}

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

.footer{
  position:relative;
  overflow:hidden;
  border-radius:var(--r-lg) var(--r-lg) 0 0;
  background:var(--ink);
  color:var(--white);
  padding:88px var(--gutter) 24px;
}
.footer__title{
  margin:0 auto;
  max-width:912px;
  font-size:clamp(2.25rem,4.44vw,4rem);
  line-height:1.2;
  text-align:center;
}
.footer__cta{ display:flex; justify-content:center; gap:24px; margin-top:40px; }

/* the outlined second action: same reveal, inverted */
/* background-color, not the background shorthand: the shorthand resets
 background-image to none, and that is where the flood is painted: this
 line was quietly wiping it off the secondary and nothing else. */
.btn--ghost{ background-color:transparent; box-shadow:inset 0 0 0 1px var(--white); color:var(--white); }
.btn--ghost:hover,
.btn--ghost:focus-visible{ box-shadow:inset 0 0 0 1px var(--white), 0 8px 22px rgba(0,0,0,.35); }

.footer__press{
  display:flex;
  align-items:center;
  justify-content:center;
  flex-wrap:wrap;
  gap:43px;
  margin-top:56px;
  font-size:14px;
}
/* now that they lead somewhere, they get a hover and a focus ring. Resting
 opacity is a touch under full so the lift on hover is legible. */
.footer__press a{
  display:block;
  flex:none;
  opacity:.85;
  border-radius:4px;
  transition:opacity .3s ease, transform .4s cubic-bezier(.22,1,.36,1);
}
.footer__press a:hover,
.footer__press a:focus-visible{ opacity:1; transform:translateY(-2px); }
.footer__press a:focus-visible{ outline:2px solid rgba(255,255,255,.7); outline-offset:6px; }
.press--tc{ width:144.89px; height:16px; background:var(--a-press-tc) no-repeat center/contain; }
.press--cdg{ width:87.27px; height:32px; background:var(--a-press-cdg) no-repeat center/contain; }
.press--an{ width:141.6px; height:16px; background:var(--a-press-an) no-repeat center/contain; }

.footer__rule{ height:1px; background:rgba(255,255,255,.18); }
.footer__rule--top{ margin-top:24px; }
.footer__legal{
  display:grid;
  grid-template-columns:1fr auto 1fr;
  align-items:center;
  gap:24px;
  margin-top:23px;
  font-size:14px;
}
.footer__legal > :first-child{ justify-self:start; }
.footer__legal > :last-child{ justify-self:end; }
.footer__links{ display:flex; gap:32px; justify-self:center; }
.footer__legal > p a{ text-decoration:underline; text-underline-offset:2px; }
.footer__links a{ text-decoration:none; opacity:.85; transition:opacity .3s ease; }
.footer__links a:hover,
.footer__links a:focus-visible{ opacity:1; }
/* The red bloom the Figma drop shadow gave the wordmark. Masking happens on
 the inner element and the blur on the wrapper, so the halo spills outside
 the letterforms. It never animates, so it rasterises once. */
.footer__halo{
  position:absolute;
  left:0; right:0;
  height:100%;
  filter:blur(66px);
  opacity:0;
  pointer-events:none;
}
.footer__halo i{
  display:block;
  width:100%; height:100%;
  background:var(--red);
  -webkit-mask:var(--a-footer-mask) no-repeat top center/100% auto;
  mask:var(--a-footer-mask) no-repeat top center/100% auto;
}

/* The wordmark is a hole in the shape of the logo. Everything below it is
 flat colour, so the reveal costs one transform on one composited layer and
 nothing at all while the page is idle. */
.footer__stage{
  position:relative;
  margin-top:31px;
  /* This is the layer that moves */
  will-change:transform;
  transform:translateZ(0);
  backface-visibility:hidden;
}
.footer__mark{
  position:relative;
  isolation:isolate;
  /* Its own raster, and a still one: the mask below is resolved once and
 reused. The movement now lives on the stage above. */
  contain:paint;
  aspect-ratio:1376/467;
  -webkit-mask:var(--a-footer-mask) no-repeat top center/100% auto;
  mask:var(--a-footer-mask) no-repeat top center/100% auto;
}
.footer__mark i{
  position:absolute;
  inset:0;
  display:block;
}
/* resting state: the gradient the design calls for. Full strength without
 scripting, dimmed by the reveal when GSAP is there to light it. */
.footer__mark .mark-base{
  /* derived from the Figma gradient geometry: its t=0 clamp lands at 44.6%
 of the CSS gradient line and t=1 at 109.8%, so the forms stay fully red
 through the first stop instead of darkening immediately */
  background:linear-gradient(149.4deg,var(--red) 0%,var(--red) 44.6%,var(--ink) 109.8%);
}
/* The reflection that crosses the face. Narrow and quick, and its lightest
 point is a rose, never white. */
/* Both moving layers get a horizontal edge fade. Their gradients run at
   104 degrees, so the element's own vertical edges do not land on the
   transparent stop: at the end of a pass that showed up as a hard line
   straight down the letterforms. */
.footer__mark .mark-glint,
.footer__mark .mark-wash{
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 7%,#000 93%,transparent 100%);
  mask-image:linear-gradient(90deg,transparent 0,#000 7%,#000 93%,transparent 100%);
}
.footer__mark .mark-glint{
  left:0;
  width:34%;
  opacity:0;
  transform:translate3d(-100%,0,0);
  will-change:transform;
  background:linear-gradient(104deg,
    rgba(255,138,162,0)   0%,
    rgba(255,138,162,.16) 30%,
    rgba(255,172,192,.42) 50%,
    rgba(255,138,162,.14) 70%,
    rgba(255,138,162,0)   100%);
}

/* The broad light. In the reference the source is a wide soft wash raking
 across the forms, not a narrow band, so this is deliberately much wider
 than the glint and drifts slowly back and forth. */
.footer__mark .mark-wash{
  left:0;
  /* wide enough that the box always overhangs the wordmark on both sides at
 either end of its travel, so only the bright core is ever in view */
  width:300%;
  opacity:0;
  transform:translate3d(-57%,0,0);
  will-change:transform;
  background:linear-gradient(104deg,
    rgba(250,7,65,0)    0%,
    rgba(150,10,38,.42) 22%,
    rgba(222,14,60,.78) 42%,
    rgba(250,40,88,.92) 50%,
    rgba(222,14,60,.72) 58%,
    rgba(150,10,38,.38) 78%,
    rgba(250,7,65,0)    100%);
}

/* No drawn edge at all: the light does the work. A second, tighter glow sits
 under the wide one so the bloom has a core as well as a spread. Both are
 static once revealed, so the blur rasterises once. */
.footer__halo--tight{ filter:blur(18px); }

@media (max-width:1000px){
  .footer__press{ gap:32px; }
}
@media (max-width:760px){
  .footer{ padding-top:64px; }
  .footer__cta{ flex-wrap:wrap; gap:12px; }
  .footer__press{ gap:24px; margin-top:40px; }
  .footer__legal{
    grid-template-columns:minmax(0,1fr);
    gap:12px;
    text-align:left;
  }
  .footer__legal > :first-child,
  .footer__legal > :last-child,
  .footer__links{ justify-self:start; }
  .footer__links{ flex-wrap:wrap; gap:16px 24px; }
}

/* ---------- deferred photography ---------- */

/* Every photographic fill is declared up front and left to the browser. They
 */

/* The native scrollbar is hidden; the page still scrolls exactly as before,
 it does not draw the gutter. */
html{ scrollbar-width:none; -ms-overflow-style:none; }
html::-webkit-scrollbar,
body::-webkit-scrollbar{ width:0; height:0; display:none; }

/* One consistent gap between sections. Each carried its own margin: 56
   here, 80 there, 120 somewhere else, which is how the rhythm drifted.
   Naming them all here, after their own rules, settles it on one figure
   across the board, and that figure now lives in --gap-section so it can
   be moved in one place. */
.feature, .cases, .ps, .sales, .bl, .listen, .faq, .footer{
  margin-top:var(--gap-section);
}

/* The hero is the one join that does not take --gap-section. The film runs
 the full height now, so the dark ground that */
main > .hero + *{ margin-top:80px !important; }
@media (max-width:900px){
  main > .hero + *{ margin-top:64px !important; }
}

/* Below 1091 the tab type drops under 24px and stops counting as large, so
 the contrast bar moves from 3:1 to 4.5:1 and 42% no longer clears it. 55%
 measures 6.2:1. */
@media (max-width:1090px){
  .ftab__name{ color:rgba(255,255,255,.55); }
  .ftab:hover .ftab__name{ color:rgba(255,255,255,.82); }
}

/* The buttons stand 40 on a phone.btn carries a hard height:48px, so a
   min-height here would have lost to it and changed nothing: the height
   itself is what has to come down, and the faces lose the vertical padding
   that was sized for 48 so the label stays centred in 40. */
@media (max-width:900px){
  .btn{ height:56px; }
  .btn__face{ padding-block:0; }
}

/* ---------- touch targets -----------------------------------------
   Audited at 390 with a finger, not a cursor. WCAG 2.2 asks for 24x24 and
   a thumb wants more, and a row of these came in under it: --------
   -------------------------------------------------------------------- */
@media (max-width:900px){
  .nav__menu a,
  .nav__login{ padding-block:8px; }

  .ftab__name{ padding-block:10px; }
  .ftab{ margin-block:-4px; }

  .footer__legal a{ display:inline-block; padding-block:6px; }

  /* the logos keep their drawn size: the padding is added outside the content
 box and the artwork is told to stay inside it, so the target grows
 without the mark growing with it */
  .footer__press a{
    box-sizing:content-box;
    padding-block:6px;
    background-origin:content-box;
    background-clip:content-box;
  }

  /* the smallest type on the page: 10 is under what a phone should ask
 anyone to read, even for a timestamp */
  .scol__time{ font-size:11px; }
  .lw__me{ font-size:11px; }
}

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

.js [data-reveal]{ opacity:0; }

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;
    transition-duration:.001ms !important;
  }
  .js [data-reveal]{ opacity:1; }
}
/* with motion off nothing advances the band, so stack the cards instead of
 leaving the second one parked off-screen */
@media (prefers-reduced-motion:reduce) and (max-width:900px){
  .band__track{ flex-wrap:wrap; transform:none !important; }
  .band__stage{ min-height:0; }
}

/* ================================================================== Dark
 build. The page turns bordeaux and every surface that */

:root{
  --glass:rgba(255,255,255,.085);
  --glass-2:rgba(255,255,255,.13);
  --line:rgba(255,255,255,.17);
  --muted:rgba(255,255,255,.66);
}

body{
  background:var(--ink) !important;
  color:var(--white);
}

/* --- nav --- */
.nav__menu{
  background:var(--glass);
  box-shadow:inset 0 0 0 1px var(--line);
  backdrop-filter:blur(18px);
  -webkit-backdrop-filter:blur(18px);
}
.nav__menu a,
.nav__login{ color:var(--white); }
/* The drawer opens onto a near-solid white card and these were inheriting
 the bar's white, so the menu was there and unreadable: which */
@media (max-width:900px){
  .nav__drawer .nav__menu a,
  .nav__drawer .nav__login{ color:var(--ink); }
  /* The bar's own glass pill was landing inside the drawer as a second, paler
 card behind only part of the list: so the links looked half on it and
 half off. The drawer is the surface here; the pill is not. */
  /* The drawer's list is, not the bar's pill and must not wear its plate.
     `.nav.is-light.nav__menu` paints one, matches this selector's weight and
     comes later in the sheet, so on a light section the open menu showed a
     grey panel behind its links. */
  .nav .nav__drawer .nav__menu{
    background:none;
    box-shadow:none;
    backdrop-filter:none;
    -webkit-backdrop-filter:none;
  }
}
.nav.is-stuck .nav__shell{
  background:rgba(255,255,255,.07);
  box-shadow:none;
}
/* The hairline is a gradient, not one flat colour: bright where the light
   would catch the top-left of a glass edge and almost gone at the opposite
   corner. Painted as a one-pixel frame, a gradient filling the border box
   with the content box punched out of it, so the corners follow the radius
   exactly. */
.nav.is-stuck .nav__shell::after{
  content:"";
  position:absolute;
  inset:0;
  z-index:1;
  border-radius:inherit;
  padding:1px;
  background:linear-gradient(135deg,
    rgba(255,255,255,.34) 0%,
    rgba(255,255,255,.12) 38%,
    rgba(255,255,255,.05) 62%,
    rgba(255,255,255,.16) 100%);
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;
  mask-composite:exclude;
  pointer-events:none;
}
.nav__logo{ filter:invert(1) brightness(1.6); }

/* Over the cyan panel the bar is white-on-light and unreadable, so the mark
 and the links flip back to the dark bordeaux while it passes. */
.nav.is-light .nav__logo{ filter:none; }
.nav.is-light .nav__login,
.nav.is-light .nav__menu a{ color:var(--ink); }
.nav.is-light.is-stuck .nav__shell::after{
  background:linear-gradient(135deg,
    rgba(26,13,13,.22) 0%,
    rgba(26,13,13,.09) 38%,
    rgba(26,13,13,.04) 62%,
    rgba(26,13,13,.11) 100%);
}
.nav.is-light.is-stuck .nav__shell{
  background:rgba(26,13,13,.06);
  box-shadow:none;
}
.nav.is-light .nav__menu{
  background:rgba(26,13,13,.05);
  box-shadow:inset 0 0 0 1px rgba(26,13,13,.12);
}

/* --- hero --- */
/* 20, and set in the sans at normal weight: it is an h2 for the outline's
 sake, not a second headline, so nothing about it should compete with the
 48 above it. */
.hero__lede{
  margin:0;
  font-family:var(--sans);
  font-size:clamp(1rem,1.4vw,1.125rem);   /* 18 at the top */
  font-weight:400;
  line-height:1.5;
  color:var(--muted);
}

/* the media card carries a photograph, so it only takes the edge and the drop */
/* No ring on this card: only the drop it casts. The hairline read as a box
 drawn around the composition not as part of it. */
.feature__media{
  box-shadow:0 28px 70px rgba(0,0,0,.42);
}
/* The compositions are off the phone for now: the panel is the content.
 Written down here because .feature__media is declared again after the
 mobile block above and was winning the display back. */
@media (max-width:900px){
  .feature__media{ display:none; }
}
/* The cyan band behind this section existed so a white card would read; with
 the card now glass on bordeaux it is a pale slab, so it goes. */
.feature::before{ display:none; }

.feature__chip{
  background:var(--glass-2);
  box-shadow:inset 0 0 0 1px var(--line);
}
.feature__chip .brandmark{ filter:invert(1) brightness(1.7); }

/* --- case studies --- */
.cases{ background:transparent; }
.cases__title{ color:var(--white); }

/* --- the marquee --- */

/* --- built to connect --- */
.bl__title{ color:var(--white); }
.bl__lede{ color:var(--muted); }
.bl__eyebrow{ color:var(--red); }

/* --- FAQ stays on light: one big card on the dark page, same corner radius
 as every other panel, held inside the grid not bleeding out --- */
.faq{
  position:relative;
  /* the same 1376 box every other panel sits in, so the card lines up with
 them instead of running to the screen edges */
  max-width:calc(var(--max) - var(--gutter) * 2);
  margin:var(--gap-section) auto 0;
  padding:96px var(--gutter) 102px;
  border-radius:var(--r-lg);
  background:linear-gradient(180deg,var(--cyan) 0%,var(--white) 100%);
  color:var(--ink);
  overflow:hidden;
}
@media (max-width:1440px){
  .faq{ margin-inline:var(--gutter); }
}
/* The card's own padding is written further up as well, but that block sits
 above this rule and was never winning: */
@media (max-width:900px){
  .faq{ padding:56px 12px 64px; }
  /* The answer clears nothing on the right. It
 both stopped it short of the rules that divide the items, which is the
 edge it is measured against. */
  .faq__a p{ padding-right:0; }
}
.faq__title,
.faq__label span,
.faq__a{ color:var(--ink); }
.faq__lede{ color:rgba(26,13,13,.7); }
.faq .eyebrow{ color:var(--ink); }



/* ---------- the page holds still behind a dialog ------------------
   Everything on a CSS animation keeps running under a full-screen modal:
   the press band, the grain, the marquees. --------
   -------------------------------------------------------------------- */
html.is-modal *:not(.cv):not(.cv *){
  animation-play-state:paused !important;
}

/* And the page holds still under it. A dialog that covers the screen while
 the page keeps moving behind it is how a reader loses their place. */
html.is-modal,
html.is-modal body{
  overflow:hidden;
  touch-action:none;
}

/* ---------- mobile: the hero --------------------------------------
   The claim at 64, the line under it four points up and at full white, and
   the two distances the page asked for: the lede closer to the claim, the
   button 24 under the lede. --------
   -------------------------------------------------------------------- */
@media (max-width:900px){
  .hero__title{ font-size:64px; line-height:1.05; }
  .hero__lede{
    font-size:20px;                /* 16 before */
    color:var(--white);            /* was white at 66% */
    margin-top:16px;               /* 24 before */
  }
  /* The copy is a flex column with a 24 row gap, so a margin here lands on
 top of it: 16 read as 40 and 24 as 48. The gap goes and the two
 distances are said once each. */
  .hero__copy{ row-gap:0; }
  .hero__lede + *{ margin-top:24px; }

  /* A 30% wash over the film. It goes on a layer of its own not into
 the gradient already on:after, which reads over the foot of the shot
 only: this one has to cover the whole frame evenly. */
  .hero__video-wash{
    position:absolute;
    inset:0;
    z-index:1;
    background:rgba(0,0,0,.3);
    pointer-events:none;
  }

  /* 40 less between the orbit and the recording. */
  .listen{ padding-top:16px !important; }
}

/* ---------- mobile: three exceptions to the section box -----------
   The 56/64 box is the rule; these three are where the page needs
   something else said. --------
   -------------------------------------------------------------------- */
@media (max-width:900px){
  /* The logo wall belongs to the case studies above it: it is the same
 claim, said in marks instead of words, so it sits 32 under them rather
 than a section away. */
  .cases{ padding-bottom:0 !important; }
  .cases__carousel{ margin-bottom:0 !important; }
  /* the 64 that was left under the carousel lives on the panel, not the
 section: that is where the gap was still coming from */
  .cases__panel{ padding-bottom:0 !important; }
  .dealers{ padding-top:32px !important; }

  /* And the service section is where the page changes subject, so it opens
 with more air above it than the sections that follow one another. */
  .feature{ padding-top:96px !important; }

  /* The marks in the orbit fade in and out as they travel, which On a phone the orbit is cropped by the viewport
 and half of them sit at the edge permanently dim, so they all show at full
 strength instead. */
  .bl__logo i{ opacity:1 !important; }
}

/* mobile: the footer mark ------------------------------------- The
   wordmark's two moving layers come off on a phone. The glint sweeps
   across and parks where it lands, and on a 1376-wide box that is a
   quarter of the way in and
   -------------------------------------------------------------------- */
@media (max-width:900px){
  /* The haloes go too. Each is a solid red rectangle the size of the mark,
 blurred 66px and 18px. On a 1376-wide wordmark that blur has room to
 dissipate into a glow; */
  .footer__halo{ display:none !important; }

  .footer__mark .mark-wash,
  .footer__mark .mark-glint{ display:none !important; }
  /* The base starts at 7% and is opened by a scroll-triggered reveal. With the
 two moving layers gone there is nothing left to reveal it, and a trigger
 that does not fire would leave the wordmark at 7%: */
  .footer__mark .mark-base{ opacity:1 !important; }
}

/* ---------- mobile: the first Sales composition -------------------
   The call window reads from the right on a phone: its own panel is
   rounded on the left and square on the right, so it belongs against that
   edge: on the left it showed its flat side to the screen. Its blur pad
   goes with it. --------
   -------------------------------------------------------------------- */
@media (max-width:760px){
  .scol:first-child img.sfx,
  .scol:first-child .sfx-pad{
    left:auto !important;
    right:0;
  }
}

/* one step smaller on the narrowest phones, so the three marks keep a gap */
@media (max-width:380px){
  .footer__press{ --press-h:20px; }
}

/* At 24 the quotation needs less room above it on a narrow card. */
@media (max-width:760px){
  .case__foot::before{ top:-72px; }
}

/* ---------- mobile: the Listen window -----------------------------
   The phone build of this window, per its own reference: the bar carries
   the mark on the left and the two round buttons on the right: no
   dropdown, no search, neither of which a phone has room to mean anything
   with. --------
   -------------------------------------------------------------------- */
@media (max-width:760px){
  .lw{ aspect-ratio:auto; }
  .lw__body{ min-height:0; height:520px; }

  /* The rail's two ends become the window's two corners. Its red edge goes
 with it: that gradient is painted by a pseudo-element across the rail's
 whole box, and a rail stretched to the window floods the window. */
  .lw__rail{
    display:block;
    position:absolute;
    inset:0;
    width:auto;
    border:0;
    background:none;
    pointer-events:none;
  }
  .lw__rail::before,
  .lw__rail::after{ display:none; }
  .lw__ricon{ display:none; }
  .lw__mark{
    position:absolute;
    left:16px; top:18px;
    width:22px; height:22px;
  }
  .lw__me{
    position:absolute;
    left:16px; bottom:16px;
    top:auto;
  }

  /* the bar keeps the two round buttons and drops what a phone cannot use */
  .lw__pill,
  .lw__search{ display:none; }
  .lw__bar{
    justify-content:flex-end;
    gap:10px;
    padding-inline:16px;
  }

  /* the turns take the width, and the wave sits among them */
  .listen__thread{ left:16px; right:16px; bottom:56px; }
  .listen__bubble{ width:100%; max-width:none; }
  .listen__bubble p{ font-size:15px; line-height:1.5; }
  /* The wave is 36 bars placed at fixed pixels on a 332 box, so it cannot
     reflow: it can only be scaled. zoom not transform: the entrance
     animation writes a transform on this element and would overwrite one set
     here, and zoom scales the layout, so the box really is narrower and sits
     inside the window with room either side. */
  .listen__bars{ zoom:.74; }

  .lw__talk{ right:16px; bottom:16px; }
}

/* One step smaller on the narrowest phones. It has to come after the block
 above, not before: the two selectors weigh the same, so the later one is
 the one that counts. */
@media (max-width:380px){
  .listen__bars{ zoom:.62; }
}

/* ---------- mobile: the footer ------------------------------------
   The reference stacks it differently from the desktop row: the press line
   breaks so the label sits over its three marks, the legal links fall into
   two rows with LinkedIn beside them, and a rule separates all of that
   from the copyright. Nothing here applies above 760. --------
   -------------------------------------------------------------------- */
@media (max-width:760px){
  /* The label takes the whole line, so the three marks centre under it. They
 also come down to two thirds: at their own size the three measured 374
 against a 350 column and Automotive News dropped to a line of its own. */
  /* The label keeps the whole line and stays centred; the three marks take
     the row under it, spread across a band with 32 either side. The sizes
     come from each artwork's own ratio at one shared height: TechCrunch
     145x28, Automotive News 142x28, Car Dealership Guy 87x44, so nothing is
     stretched. */
  /* The marks run to the grid's own edges: the same line the rules and the
 legal links sit on, not a band of their own inside it. */
  .footer__press{
    justify-content:space-between;
    gap:20px 0;
    width:100%;
    margin-inline:0;
  }
  .footer__press > span{ width:100%; text-align:center; }
  /* One shared height drives all three widths through each artwork's own
 ratio, so the proportions are exact and a narrower phone shrinks them
 together instead of squeezing the gaps to nothing. */
  .footer__press{ --press-h:24px; }
  .footer__press .press--tc{ width:calc(var(--press-h) * 5.18); height:var(--press-h); }
  .footer__press .press--cdg{ width:calc(var(--press-h) * 1.98); height:var(--press-h); }
  .footer__press .press--an{ width:calc(var(--press-h) * 5.07); height:var(--press-h); }

  /* links first, then the rule, then the two lines of small print */
  .footer__legal{
    display:grid;
    grid-template-columns:1fr auto;
    align-items:start;
    gap:0;
    margin-top:28px;
  }
  .footer__links{
    grid-column:1;
    grid-row:1;
    display:flex;
    flex-wrap:wrap;
    gap:8px 32px;
    max-width:19rem;                 /* two to a row, as the reference has it */
  }
  .footer__in{
    grid-column:2;
    grid-row:1;
    align-self:start;
    width:24px; height:24px;
    margin-top:6px;
    background:var(--a-linkedin) no-repeat center / contain;
    opacity:.85;
    transition:opacity .3s ease;
  }
  .footer__rule--legal{
    grid-column:1 / -1;
    grid-row:2;
    margin:28px 0 24px;
  }
  .footer__legal > p{ grid-column:1 / -1; margin:0; }
  .footer__legal > p:first-of-type{ grid-row:3; }
  .footer__legal > p:last-of-type{ grid-row:4; margin-top:16px; }
}

/* the two pieces the phone adds are not part of the desktop footer */
@media (min-width:761px){
  .footer__in,
  .footer__rule--legal{ display:none; }
}

/* ---------- mobile: the section box -------------------------------
   Each section carries its own 56 above and 64 below, not a single margin
   between them. --------
   -------------------------------------------------------------------- */
@media (max-width:900px){
  .cases, .dealers, .ps, .feature, .sales, .bl, .listen, .faq, .footer{
    margin-top:0 !important;
    padding-top:56px;
    padding-bottom:64px;
  }
  /* The first section after the hero is pinned by its own rule: and `main >.hero + *` is more specific than a bare class, so it won the margin even
 against !important and left one 64px gap where the rest of the page had
 none. */
  main > .hero + *{ margin-top:0 !important; }

  /* the hero opens the page, so it keeps its own top */
  .hero{ padding-top:0; }
}

/* ---------- mobile rhythm -----------------------------------------
   A heading and its lede are one thing said in two lines, so the distance
   between them should be the same everywhere and smaller than the distance
   to anything else. --------
   -------------------------------------------------------------------- */
@media (max-width:900px){
  .feature__title,
  .sales__title,
  .bl__title,
  .listen__title{ margin-bottom:0; }

  .sales__lede,
  .bl__lede,
  .listen__lede{ margin-top:12px; }

  /* The service section is a grid with a 32px row gap, so its lede sat at 32
     + its own margin = 48 while the others sat at 16. The gap closes to 16
     and the parts below it take the air back on their own margins, so only
     the heading-to-lede distance changes. */
  /* align-items:start as well as the gap: the rows were taller than the
 title's own box, so the 12 measured 30 on the page. */
  .feature{ row-gap:12px; align-items:start; align-content:start; }
  .feature__lede{ margin-top:0; }
  .feature__media,
  .feature__panel{ margin-top:20px; }

}



/* ---------- the bare bar (the demo page) --------------------------
   Logo on one side, one action on the other, at every width. The drawer
   and the hamburger are not hidden here: they are not in the markup at
   all, so there is no panel to open and nothing for the toggle's script to
   find. --------
   -------------------------------------------------------------------- */
/* Only the logo is left in this bar, so there is nothing to space apart: justify-content:space-between would have pushed it nowhere, but saying
 flex-start makes the intent plain. */
.nav--bare .nav__shell{
  display:flex;
  align-items:center;
  justify-content:flex-start;
  gap:16px;
}
@media (max-width:900px){
  /* the bar keeps both ends visible where the landing folds its menu away */
  .nav--bare .nav__cta{ width:auto; }
}

/* ---------- selection ---------------------------------------------
   The browser's own highlight is a blue that belongs to nobody. Selecting
   text is something people do while reading: quoting a line, checking a
   number, so it is worth having it land in the brand not beside it.
   --------
   -------------------------------------------------------------------- */
::selection{
  background:var(--red);
  color:var(--white);
  text-shadow:none;
}
::-moz-selection{
  background:var(--red);
  color:var(--white);
  text-shadow:none;
}

/* ---------- the follow-up table -----------------------------------
   The same window as the dashboard, carrying a table instead of cards.
   Rows are drawn, not pictured: --------
   -------------------------------------------------------------------- */
.dash--table{ top:38.5%; }
.dash__head--sub{
  top:16.5%;
  font-size:16px;
  letter-spacing:.02em;
  color:rgba(255,255,255,.5);
}
.ftable{
  position:absolute;
  left:6.451%; right:3%;
  top:29%;
  border-radius:8px;
  background:rgba(255,255,255,.03);
  overflow:hidden;
  font-size:10px;
  line-height:24px;
}
.ftable__head,
.ftable__row{
  display:grid;
  grid-template-columns:17% 19% 1fr;
  gap:0 8px;
  padding:0 16px;
  white-space:nowrap;
}
.ftable__head{
  color:rgba(255,255,255,.2);
  text-transform:uppercase;
  padding-block:8px 0;
}
.ftable__row{
  color:var(--white);
  opacity:.5;
  border-top:1px solid rgba(255,255,255,.06);
  padding-block:8px;
}
.ftable__row span{ overflow:hidden; text-overflow:ellipsis; }
/* the rows arrive one after another; with motion off they are there */
html:not(.js) .ftable__row{ opacity:.5; }

/* The copy sits at the foot of the card. It the compositions that replaced
 it are absolute and take no space, so */
.scol__foot{ margin-top:auto; }

/* ---------- the Sales compositions --------------------------------
   Four overlays, one per card, exactly as they were drawn: each is the
   whole composition exported as a single SVG, placed at the figures the
   design gives inside the 332-wide card. --------
   -------------------------------------------------------------------- */
/* The second blur. The first composition's panel carries its own 8px
   backdrop-filter on top of the card's 12px, and an SVG cannot apply one
   to the HTML behind it: so this pad sits under the image, exactly where
   the panel is, and does the blurring the artwork cannot. */
.sfx-pad{
  position:absolute;
  display:block;
  pointer-events:none;
  backdrop-filter:blur(8px);
  -webkit-backdrop-filter:blur(8px);
  /* Cut to the panel's own outline: the same path string the artwork draws
     it with, copied out of the file. A border-radius was a second
     description of the same corner and the two drifted, which is how the
     blur came to sit outside the curve at the top and the bottom. */
  clip-path:path('M0 16C0 7.16344 7.16344 0 16 0H249V140H16C7.16344 140 0 132.837 0 124V16Z');
  opacity:0;
}
html:not(.js) .sfx-pad{ opacity:1; }
@media (prefers-reduced-motion:reduce){ .sfx-pad{ opacity:1; } }

img.sfx{
  position:absolute;
  display:block;
  max-width:none;
  pointer-events:none;
  opacity:0;
}
html:not(.js) img.sfx{ opacity:1; }
@media (prefers-reduced-motion:reduce){ img.sfx{ opacity:1; } }

/* The copy sits at the foot of the card. It the compositions that replaced
 it are absolute and take no space. */
.scol__foot{ margin-top:auto; }

/* ---------- the CSI cards -----------------------------------------
   Two cards from the design: the trend on the left and the same figure by
   advisor on the right, bleeding off the panel the way the dashboard
   window does. --------
   -------------------------------------------------------------------- */
.csicard{
  position:absolute;
  overflow:hidden;
  border-radius:var(--r-lg);
  padding:16px 32px;
  aspect-ratio:442/332;
}
.csicard--line{
  left:14.12%; top:43.13%; width:65%;
  background:linear-gradient(145.19deg, #36000C 10.878%, #1A0D0D 94.475%);
  z-index:2;
}
/* the second card runs off the panel's edge, as the design has it */
.csicard--bars{
  left:82.65%; top:43.13%; width:65%;
  background:#130707;
}

.csi{
  position:absolute;
  left:32px; right:32px; top:42px; bottom:16px;
  display:grid;
  grid-template-columns:auto 1fr;
  grid-template-rows:1fr auto;
  gap:6px 10px;
  font-size:clamp(8px, .9vw, 13px);
  letter-spacing:.5px;
  color:var(--white);
}
.csi__y{
  grid-area:1/1;
  display:flex;
  flex-direction:column;
  justify-content:space-between;
  line-height:1;
}
.csi__x{
  grid-area:2/2;
  display:flex;
  justify-content:space-between;
  line-height:1;
}
.csi__plot{ grid-area:1/2; position:relative; }

.csi__grid{
  position:absolute;
  inset:0 0 6% 0;
  display:flex;
  justify-content:space-between;
}
.csi__grid i{ width:1px; background:#37181E; }

/* The curve and its marker share one box, so the marker is written in the
 path's own coordinates and cannot drift from it at any size. */
.csi__curve{
  position:absolute;
  inset:26% 0 30% 4%;
}
.csi__line{
  position:absolute;
  inset:0;
  width:100%; height:100%;
  overflow:visible;
}
.csi__line path{
  fill:none;
  stroke:var(--red);
  stroke-width:3;
  stroke-linecap:round;
  vector-effect:non-scaling-stroke;
}

/* The curve's actual high point, sampled along the path not read off
 its anchors: a Bezier's apex is, not the point you wrote, it is where the
 segments meet the eye. */
.csi__dot{
  position:absolute;
  left:54.94%; top:10.29%;
  width:11px; height:11px;
  margin:-5.5px 0 0 -5.5px;
  border-radius:50%;
  background:var(--red);
  box-shadow:0 0 0 3px rgba(250,7,65,.25);
}
.csi__tip{
  position:absolute;
  left:54.94%; bottom:100%;
  margin-bottom:14px;
  transform:translateX(-50%);
  padding:7px 12px;
  border-radius:4px;
  background:#1A0D0D;
  font-size:clamp(7px,.62vw,9px);
  line-height:1;
  white-space:nowrap;
}

/* ---------- the bars ---------- */
.csibars{
  position:absolute;
  left:32px; right:32px; top:56px; bottom:24px;
  display:flex;
  flex-direction:column;
  justify-content:space-between;
}
.csibars i{
  display:block;
  width:var(--track);
  height:clamp(8px,1.1vw,16px);
  border-radius:50px;
  background:#431E26;
  overflow:hidden;
}
.csibars b{
  display:block;
  width:var(--fill);
  height:100%;
  border-radius:50px;
  background:var(--red);
  transform-origin:left center;
}

/* ---------- the follow-up table -----------------------------------
   The same window as the dashboard, carrying a table instead of cards.
   Rows are drawn, not pictured: --------
   -------------------------------------------------------------------- */
.dash--table{ top:38.5%; }
.dash__head--sub{
  top:16.5%;
  font-size:16px;
  letter-spacing:.02em;
  color:rgba(255,255,255,.5);
}
.ftable{
  position:absolute;
  left:6.451%; right:3%;
  top:29%;
  border-radius:8px;
  background:rgba(255,255,255,.03);
  overflow:hidden;
  font-size:10px;
  line-height:24px;
}
.ftable__head,
.ftable__row{
  display:grid;
  grid-template-columns:17% 19% 1fr;
  gap:0 8px;
  padding:0 16px;
  white-space:nowrap;
}
.ftable__head{
  color:rgba(255,255,255,.2);
  text-transform:uppercase;
  padding-block:8px 0;
}
.ftable__row{
  color:var(--white);
  opacity:.5;
  border-top:1px solid rgba(255,255,255,.06);
  padding-block:8px;
}
.ftable__row span{ overflow:hidden; text-overflow:ellipsis; }
/* the rows arrive one after another; with motion off they are there */
html:not(.js) .ftable__row{ opacity:.5; }

/* ---------- the CSI heat map --------------------------------------
   Six rows of eleven squares, the colours taken cell by cell from the
   design. Every one is an element, so it scales with the panel, costs no
   request, and stays crisp at any size: --------
   -------------------------------------------------------------------- */
/* ---------- images below the fold ---------------------------------
   Measured on a throttled phone: every photograph and logo on the page
   started downloading at 1.2s and took four seconds or more to arrive: a 4
   KB press mark among them. --------
   -------------------------------------------------------------------- */
[data-defer]:not([data-near]) .case__img,
[data-defer]:not([data-near]) .dealers__mark,
[data-defer]:not([data-near]) .mset__veil,
[data-defer]:not([data-near]) .scol__panel,
[data-defer]:not([data-near]) .bl__logo i::before,
[data-defer]:not([data-near]) .footer__press a,
[data-defer]:not([data-near]) .lw__wbtn,
[data-defer]:not([data-near]) .dash__wbtn{ background-image:none !important; }

/* ---------- listen: the play control ------------------------------
   The pill from the design: a red-to-ink gradient across it, a white disc
   holding the mark, and the name beside it. --------
   -------------------------------------------------------------------- */
/* The button centres on its own margins not on the container's
 text-align. text-align was what centred it before, and it fell through to
 the conversation: */
.listenbtn{
  position:relative;
  /* Over the section's haze, which is absolute at z-index 1 with
 pointer-events off: so */
  z-index:2;
  display:flex;
  width:fit-content;
  align-items:center;
  gap:12px;
  margin:40px auto 0;
  padding:8px 24px 8px 8px;
  border:0;
  border-radius:64px;
  /* The stop positions are not decoration: the artwork's gradient runs from
 (69.7, 18.5) to (122.6, 100.5) in a box only 56 tall, so its far end falls
 outside the pill and only the first part of the ramp is ever seen. */
  background:linear-gradient(147.2deg, #FA0741 36.301%, #1A0D0D 102.83%);
  color:var(--white);
  cursor:pointer;
  transition:transform .45s cubic-bezier(.22,1,.36,1), box-shadow .45s ease;
}
/* The darkening layer. It sits over the gradient and under the disc and the
 label, both of which are positioned for exactly that reason: otherwise an
 absolute pseudo-element paints over static text and dims the words too. */
.listenbtn::before{
  content:"";
  position:absolute;
  inset:0;
  border-radius:inherit;
  background:rgba(26,13,13,.16);
  opacity:0;
  transition:opacity .35s ease;
  pointer-events:none;
}
.listenbtn__icon,
.listenbtn__label{ position:relative; }

.listenbtn:hover,
.listenbtn:focus-visible{
  transform:scale(1.02);
  /* A ring at the edge, not a shadow beneath: an inset hairline of red
 and a short bloom outside it. No offset, so nothing */
  box-shadow:
    inset 0 0 0 1px rgba(250,7,65,.65),
    0 0 14px rgba(250,7,65,.38);
}
.listenbtn:hover::before,
.listenbtn:focus-visible::before{ opacity:1; }
.listenbtn:active{ transform:scale(.99); }

.listenbtn__icon{
  position:relative;
  width:40px; height:40px;
  flex:none;
  border-radius:20px;
  background:var(--white);
  display:grid;
  place-items:center;
}
/* The mark carries its own position inside the disc */
/* The glyph is 20 in a 40 disc, as the design has it. Both faces sit on the
 same spot and cross-fade, so neither moves when the state changes. */
.listenbtn__icon::before,
.listenbtn__icon::after{
  content:"";
  position:absolute;
  inset:0;
  background-repeat:no-repeat;
  background-position:center;
  background-size:20px 20px;
  transition:opacity .18s ease;
}
.listenbtn__icon::before{ background-image:var(--a-listen-play); }
.listenbtn__icon::after{ background-image:var(--a-listen-pause); opacity:0; }
.listenbtn[data-playing] .listenbtn__icon::before{ opacity:0; }
.listenbtn[data-playing] .listenbtn__icon::after{ opacity:1; }

.listenbtn__label{
  font-family:var(--display);
  font-size:20px;
  line-height:40px;
  white-space:nowrap;
}

@media (max-width:900px){
  /* 56 tall, the same as every other button on a phone: 8 + 40 + 8 */
  .listenbtn{ margin-top:32px; padding:8px 24px 8px 8px; gap:12px; }
  .listenbtn__icon{ width:40px; height:40px; border-radius:20px; }
  .listenbtn__label{ font-size:18px; line-height:40px; }
}
@media (prefers-reduced-motion:reduce){
  .listenbtn{ transition:none; }
}

/* ================================================================== Light
 pages: privacy, terms, security. The site is bordeaux everywhere else;
 these three are documents, and a document reads on white. */
body.is-doc{
  background:var(--white) !important;
  color:var(--ink);
  /* The brand red is #FA0741, which measures 4.06:1 on white: fine for a
 headline, short of the 4.5 small text needs. One notch darker on the same
 hue clears it at 4.58 and still */
  --red-ink:#EA053C;
}

.doc{
  display:grid;
  grid-template-columns:220px minmax(0,1fr);
  gap:80px;
  align-items:start;
  padding-block:172px 120px;
}
.doc__head{ grid-column:1/-1; max-width:760px; margin-bottom:64px; }
.doc__eyebrow{ color:var(--red-ink); }
.doc__title{
  margin:14px 0 0;
  font-family:var(--display);
  font-size:clamp(2.5rem,4.6vw,4rem);
  line-height:1.06;
  letter-spacing:-.01em;
}
.doc__meta{
  margin:20px 0 0;
  font-size:14px;
  color:rgba(26,13,13,.62);        /* 4.20:1 at.55, 5.35 here */
}

/* The contents list holds its place while the document scrolls past it. */
.doc__toc{ position:sticky; top:132px; }
.doc__toc p{
  margin:0 0 14px;
  font-size:12px;
  font-weight:600;
  letter-spacing:.08em;
  text-transform:uppercase;
  color:rgba(26,13,13,.62);        /* 3.06:1 at.45 */
}
.doc__toc ol{ margin:0; padding:0; list-style:none; counter-reset:toc; }
.doc__toc li{ counter-increment:toc; }
.doc__toc li + li{ margin-top:10px; }
.doc__toc a{
  display:block;
  padding-block:2px;
  font-size:14px;
  line-height:1.4;
  color:rgba(26,13,13,.7);
  text-decoration:none;
  transition:color .2s ease;
}
.doc__toc a::before{ content:counter(toc) ". "; color:rgba(26,13,13,.35); }
.doc__toc a:hover{ color:var(--ink); }

/* the three levels ---- h1 is the document. h2 opens a clause and carries
   a rule above it so the eye finds the break without reading. h3 is a
   point inside a clause and is set in the sans */
.doc__body{ max-width:720px; }
.doc__body > h2{
  margin:64px 0 0;
  padding-top:28px;
  border-top:1px solid rgba(26,13,13,.12);
  font-family:var(--display);
  font-size:clamp(1.5rem,2.4vw,1.875rem);
  line-height:1.25;
  font-weight:400;
}
.doc__body > h2:first-child{ margin-top:0; padding-top:0; border-top:0; }
.doc__body h3{
  margin:36px 0 0;
  font-size:17px;
  font-weight:600;
  line-height:1.4;
}
.doc__body p{
  margin:16px 0 0;
  font-size:16px;
  line-height:1.75;
  color:rgba(26,13,13,.78);
}
.doc__body ul,
.doc__body ol{ margin:18px 0 0; padding-left:0; list-style:none; }
.doc__body li{
  position:relative;
  padding-left:26px;
  margin-top:10px;
  font-size:16px;
  line-height:1.7;
  color:rgba(26,13,13,.78);
}
.doc__body ul > li::before{
  content:"";
  position:absolute;
  left:2px; top:.62em;
  width:6px; height:6px;
  border-radius:50%;
  background:var(--red);
}
.doc__body ol{ counter-reset:item; }
.doc__body ol > li{ counter-increment:item; }
.doc__body ol > li::before{
  content:counter(item) ".";
  position:absolute;
  left:0; top:0;
  font-variant-numeric:tabular-nums;
  color:rgba(26,13,13,.45);
}
/* Underlined, not coloured. A link sitting inside a paragraph has to be
 findable without relying on colour, and this is a document: most of its
 links are in the middle of a sentence. */
.doc__body a{
  color:var(--red-ink);
  text-decoration:underline;
  text-decoration-thickness:1px;
  text-underline-offset:3px;
}
.doc__body a:hover{ text-decoration-thickness:2px; }
/* the download is a button and carries its own affordance */
.doc__download,
.doc__download:hover{ text-decoration:none; }
.doc__body strong{ font-weight:600; color:var(--ink); }
/* the address block at the foot of a policy */
.doc__body address{
  margin-top:16px;
  font-style:normal;
  font-size:16px;
  line-height:1.75;
  color:rgba(26,13,13,.78);
}

/* One page has no clauses to list: Flai keeps the agreement as a PDF, so it
 drops the contents column and runs on the single reading measure. */
.doc--single{ grid-template-columns:minmax(0,1fr); }
.doc--single .doc__body{ max-width:720px; }
.doc__download{ margin-top:12px; }

/* Build note, not copy. One element, easy to delete. */
.doc__draft{
  grid-column:1/-1;
  margin:0 0 40px;
  padding:14px 18px;
  border-radius:var(--r-sm);
  background:rgba(250,7,65,.08);
  box-shadow:inset 0 0 0 1px rgba(250,7,65,.25);
  font-size:14px;
  line-height:1.5;
  color:var(--ink);
}

@media (max-width:1000px){
  .doc{ grid-template-columns:minmax(0,1fr); gap:0; padding-block:148px 96px; }
  .doc__head{ margin-bottom:40px; }
  .doc__toc{
    position:static;
    margin-bottom:48px;
    padding-bottom:36px;
    border-bottom:1px solid rgba(26,13,13,.12);
  }
}
@media (max-width:900px){
  .doc{ padding-block:128px 72px; }
  .doc__body > h2{ margin-top:48px; }
}


/* ================================================================== The
   case video. A dialog, not a div: <dialog> brings the top layer, the
   backdrop, Escape and the focus trap with it, which is most of what a
   modal has to get right and all of what hand-rolled ones get wrong. */
.cv{
  width:100vw;
  max-width:none;
  height:100vh;
  max-height:none;
  margin:0;
  padding:0;
  border:0;
  background:none;
  color:var(--white);
  overflow:hidden;
}
/* Scoped to [open] on purpose. An author display beats the browser's own
   dialog:not([open]){display:none} whatever the specificity says, so
   putting the grid on.cv left a closed dialog rendered in the flow: a full
   screen of it, 900px of document nobody could see and axe reading its
   empty heading. */
.cv[open]{
  display:grid;
  place-items:center;
}
.cv::backdrop{ background:rgba(0,0,0,.78); }   /*.5 before */

/* The width carries all three limits at once: the window's width, a
 ceiling, and the width a 16:9 box may have before it is taller than the
 room left for it. */
.cv__panel{
  width:min(96vw, 1920px, calc(88vh * 16 / 9));
  display:block;
}
@media (max-width:900px){
}
.cv__stage{
  position:relative;
  width:100%;
  aspect-ratio:16/9;
  margin-inline:auto;
  border-radius:var(--r-md);
  overflow:hidden;
  flex:none;
  /* A neutral grey, not the near-black Black */
  background:#444040;
  box-shadow:0 40px 120px rgba(0,0,0,.55);
  display:grid;
  place-items:center;
}
@supports (height: 1dvh){
  .cv{ height:100dvh; }
  /* the same figure in dvh, so a phone's collapsing chrome does not change
 what fits: and the quote's room is taken out here too */
  .cv__panel{ width:min(96vw, 1920px, calc(88dvh * 16 / 9)); }
}
.cv__stage iframe{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  border:0;
  display:block;
}
/* shown only until a card has a Vimeo reference on it */
.cv__missing{
  margin:0;
  padding:0 32px;
  text-align:center;
  font-size:15px;
  line-height:1.6;
  color:rgba(255,255,255,.55);
}
.cv__missing code{
  font-family:ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size:14px;
  color:rgba(255,255,255,.8);
}
.cv[data-has-video] .cv__missing{ display:none; }

.cv__close{
  position:fixed;
  right:clamp(16px, 2.5vw, 40px);
  top:clamp(16px, 2.5vw, 40px);
  z-index:2;
  width:44px; height:44px;
  display:grid;
  place-items:center;
  border:0;
  border-radius:50%;
  background:rgba(12,6,6,.5);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.22);
  backdrop-filter:blur(8px);
  -webkit-backdrop-filter:blur(8px);
  cursor:pointer;
}
/* Drawn, not borrowed: there is no close glyph in the set, and two rules
 beat hunting for one that only half means it. */
.cv__close span{ position:relative; width:16px; height:16px; }
.cv__close span::before,
.cv__close span::after{
  content:"";
  position:absolute;
  left:0; top:50%;
  width:16px; height:1.5px;
  border-radius:1px;
  background:var(--white);
}
.cv__close span::before{ transform:translateY(-50%) rotate(45deg); }
.cv__close span::after{ transform:translateY(-50%) rotate(-45deg); }

/* the card is a button now, so it needs the reset the anchor never did */
.case{ border:0; padding:0; text-align:left; font:inherit; color:inherit; cursor:pointer; background:none; }

@media (max-width:760px){
  .cv__panel{ width:min(96vw, 1920px, calc(88dvh * 16 / 9)); }
}

/* ---------- touch: nothing waits for a hover ----------------------
   A finger has no hover. What a pointer device reveals on the way past, a
   touch screen only reveals after a tap: and then keeps it, because the
   hover sticks until something else is tapped. --------
   -------------------------------------------------------------------- */
@media (hover:none){

  /* --- the case studies ---------------------------------------------
   The blurb is parked below the card's edge and rides up on hover; here it
   is up, with the wash it travels with. And the rotating arrow goes: it is
   a cursor's affordance, and the play mark in the middle already says the
   card opens a film.
   -------------------------------------------------------------------- */
  .case::before{ opacity:1 !important; }
  .case__play{ opacity:1 !important; }
  .case__cta{ display:none !important; }

  /* --- everything else that only answers a cursor -------------------- */
  .btn:hover,
  .btn:focus-visible{ transform:none; }
  .btn:hover{ --btn-fill:0%; box-shadow:none; }
  .btn:hover .btn__arrow{ background-color:var(--red); }
  .btn--ghost:hover{ color:var(--white); box-shadow:inset 0 0 0 1px var(--white); }
  .listenbtn:hover{ transform:none; box-shadow:none; }
  .listenbtn:hover::before{ opacity:0; }
  .scol:hover .scol__veil,
  .scol:hover .scol__chat,
  .scol:hover .scol__more{ transition:none; }
  .ftab:hover .ftab__name{ color:inherit; }
  .doc__toc a:hover,
  .doc__body a:hover,
  .footer__links a:hover,
  .footer__press a:hover{ color:inherit; opacity:inherit; }
  .case:hover .case__img{ transform:none; }
}

/* ---------- the blog ----------------------------------------------
   The page opens on the dark band: the title and the newest article, and
   the rest follows as a wall of cards on white. Both run the full width of
   the grid. --------
   -------------------------------------------------------------------- */

.shell--narrow{ max-width:720px; }

/* ---- the hero ---- */
.bhero{
  /* the band is the page's width; what sits in it keeps the grid's */
  width:100vw;
  margin-inline:calc(50% - 50vw);
  padding-block:164px 72px;
  /* Two layers in one declaration: the mark over the ink. As a pseudo-element
 behind the box it would sit under the element's own background and never
 be seen. */
  background:
    var(--a-bd-pattern) no-repeat center / cover,
    var(--ink);
  color:var(--white);
}
.bhero__eyebrow{
  margin:0 0 14px;
  font-size:12px;
  font-weight:500;
  text-transform:uppercase;
  letter-spacing:.1em;
  color:var(--red);
}
.bhero__title{
  max-width:18ch;
  margin:0 0 64px;
  font-family:var(--display);
  font-size:clamp(2.5rem, 5vw, 4rem);
  line-height:1.05;
  text-wrap:balance;
}

/* ---- the article it leads with ---- */
.blead__in{
  display:grid;
  grid-template-columns:1.05fr .95fr;
  align-items:center;
  gap:clamp(32px, 4vw, 64px);
  color:inherit;
  text-decoration:none;
}
/* No aspect-ratio and no cover: the picture is shown at the shape */
.blead__shot{
  display:block;
  width:100%;
  height:auto;
  border-radius:var(--r-md);
  background:#2A1618;
  transition:transform .6s cubic-bezier(.2,.7,.2,1);
}
.blead__words{ display:block; }
.blead__meta{
  display:flex; align-items:center; gap:8px;
  font-size:12px;
  text-transform:uppercase;
  letter-spacing:.1em;
  color:var(--red);
}
.blead__meta i{ width:3px; height:3px; border-radius:50%; background:currentColor; opacity:.55; }
.blead__title{
  display:block;
  margin-top:16px;
  font-family:var(--display);
  font-size:clamp(1.9rem, 3.2vw, 3rem);
  line-height:1.08;
  text-wrap:pretty;
}
.blead__blurb{
  display:block;
  max-width:46ch;
  margin-top:16px;
  font-size:17px;
  line-height:1.55;
  color:rgba(255,255,255,.76);
}
.blead__go{
  display:inline-block;
  margin-top:24px;
  padding-bottom:3px;
  border-bottom:1px solid rgba(255,255,255,.4);
  font-size:14px;
}

/* ---- the wall ---- */
.blog{ padding-block:72px 120px; }
.blog__grid{
  display:grid;
  grid-template-columns:repeat(3, minmax(0,1fr));
  gap:32px;
}
/* Each post is a card: a hairline, and on hover it lifts a little and the
 line darkens. Nothing moves inside it: a card that rearranges itself under
 the cursor is harder to read, not easier. */
.bpost{
  display:flex;
  flex-direction:column;
  padding:14px 14px 22px;
  border:1px solid rgba(26,13,13,.14);
  border-radius:var(--r-md);
  background:#fff;
  color:inherit;
  text-decoration:none;
  transition:transform .4s cubic-bezier(.2,.7,.2,1),
             border-color .3s ease,
             box-shadow .4s ease;
}
.bpost__shot{
  display:block;
  width:100%;
  height:auto;
  border-radius:calc(var(--r-md) - 6px);
  background:#1A0D0D;
}
/* a post with no cover still needs something to sit in the card */
.bpost__shot--none{ aspect-ratio:16/10; }
/* A deeper red than the brand's on a light ground: #FA0741 against white
 measures 4.06 and this label is 12px, which needs 4.5. */
.bpost__meta{
  display:flex; align-items:center; gap:8px;
  margin-top:18px;
  font-size:12px;
  text-transform:uppercase;
  letter-spacing:.08em;
  color:#C2042C;
}
.bpost__meta i{ width:3px; height:3px; border-radius:50%; background:currentColor; opacity:.5; }
.bpost__meta,
.bpage__meta{ font-style:normal; }
.bpost__title{
  margin:10px 0 0;
  font-family:var(--display);
  font-size:23px;
  line-height:1.25;
  text-wrap:pretty;
}
.bpost__blurb{
  margin:10px 0 0;
  font-size:15px;
  line-height:1.55;
  color:rgba(26,13,13,.8);
}

@media (hover:hover){
  .bpost:hover{
    transform:translateY(-3px);
    border-color:rgba(26,13,13,.3);
    box-shadow:0 14px 34px rgba(26,13,13,.08);
  }
  .blead__in:hover .blead__shot{ transform:translateY(-4px); }
}
.bpost:focus-visible{ outline:2px solid #C2042C; outline-offset:3px; }

@media (max-width:1000px){
  .blog__grid{ grid-template-columns:repeat(2, minmax(0,1fr)); gap:24px; }
}
@media (max-width:760px){
  .bhero{ padding-block:120px 48px; }
  .bhero__title{ margin-bottom:40px; }
  .blead__in{ grid-template-columns:1fr; gap:22px; }
  .blead__blurb{ max-width:none; font-size:16px; }
  .blog{ padding-block:44px 72px; }
  .blog__grid{ grid-template-columns:1fr; gap:20px; }
  .bpost__title{ font-size:21px; }
}

/* ---- one post ---- */
.bpage__head{ padding-block:8px 32px; }
.bpage__meta{
  display:flex; align-items:center; gap:8px;
  margin:0 0 16px;
  font-size:12px;
  text-transform:uppercase;
  letter-spacing:.08em;
  color:#C2042C;
}
.bpage__meta a{ color:inherit; }
.bpage__meta i{ width:3px; height:3px; border-radius:50%; background:currentColor; opacity:.5; }
.bpage__title{
  margin:0;
  font-family:var(--display);
  font-size:clamp(2rem, 4vw, 3rem);
  line-height:1.1;
  text-wrap:pretty;
}
.bpage__lede{
  margin:18px 0 0;
  font-size:19px;
  line-height:1.5;
  color:rgba(26,13,13,.8);
}
.bpage__shot{
  display:block;
  width:100%;
  height:auto;
  margin:40px 0 8px;
  border-radius:var(--r-md);
}

/* The article's own markup comes from the export */
.bpage__body{
  padding-block:32px 8px;
  font-size:17px;
  line-height:1.7;
  color:rgba(26,13,13,.82);
}
.bpage__body > *:first-child{ margin-top:0; }
.bpage__body p{ margin:0 0 20px; }
.bpage__body h2{
  margin:48px 0 14px;
  font-family:var(--display);
  font-size:30px;
  line-height:1.2;
  color:var(--ink);
}
.bpage__body h3{
  margin:34px 0 10px;
  font-size:21px;
  font-weight:500;
  line-height:1.3;
  color:var(--ink);
}
.bpage__body ul,
.bpage__body ol{ margin:0 0 22px; padding-left:22px; }
.bpage__body li{ margin:0 0 8px; }
/* Underlined, not coloured: a link inside a paragraph cannot be told
 apart by hue alone. */
/* Forty of the forty-three articles arrive with a <style> block of their
 own, and between them they set text-decoration:none on links a hundred and
 seventeen times. */
.bpage__body a,
.bpage__body a *{
  color:#C2042C !important;
  text-decoration:underline !important;
  text-underline-offset:3px;
  text-decoration-thickness:1px;
}
.bpage__body strong{ color:var(--ink); }
.bpage__body img{
  display:block;
  width:100%;
  height:auto;
  margin:28px 0;
  border-radius:var(--r-sm);
}
.bpage__body figure{ margin:28px 0; }
.bpage__body figure img{ margin:0; }
.bpage__body small{ display:block; margin-top:10px; font-size:13px; opacity:.65; }
/* a wide table or a code block scrolls in its own box not pushing
 the page sideways */
.bpage__body pre,
.bpage__scroll{ display:block; max-width:100%; overflow-x:auto; }
.bpage__scroll table{ width:100%; border-collapse:collapse; }
.bpage__scroll:focus-visible,
.bpage__scroll table:focus-visible,
.bpage__body pre:focus-visible{ outline:2px solid #C2042C; outline-offset:3px; }

.bpage__around{
  display:flex;
  justify-content:space-between;
  gap:24px;
  padding-block:40px 120px;
  border-top:1px solid rgba(26,13,13,.12);
  margin-top:48px;
}
.bpage__step{
  max-width:46%;
  font-size:15px;
  line-height:1.4;
  color:var(--ink);
  text-decoration:none;
}
.bpage__step span{
  display:block;
  margin-bottom:6px;
  font-size:11px;
  text-transform:uppercase;
  letter-spacing:.08em;
  color:#C2042C;
}
.bpage__step--next{ text-align:right; margin-left:auto; }

@media (hover:hover){
  .bpost:hover .bpost__shot{ transform:translateY(-4px); }
}
@media (max-width:760px){
  .blog{ padding-block:16px 72px; }
  .blog__grid{ grid-template-columns:1fr; gap:40px; }
  .bpost__title{ font-size:21px; }
  .bpage__body{ font-size:16px; }
  .bpage__body h2{ font-size:25px; margin-top:36px; }
  .bpage__around{ flex-direction:column; padding-bottom:72px; }
  .bpage__step{ max-width:none; }
  .bpage__step--next{ text-align:left; margin-left:0; }
}
