@import url('https://fonts.googleapis.com/css2?family=Rubik:ital,wght@0,300..700;1,300..700&family=JetBrains+Mono:wght@400;500&display=swap');

/* =====================================================================
   Profitcast 2026 — Design System (BRAND-ALIGNED, real brand)
   Tropical-tech palette from the Profitcast brand: ocean cyan → electric
   mint signature gradient, orange CTA punch, near-black ink, white space.
   Gilroy (display) × Rubik (body). Motifs kept, recoloured to brand.
   ===================================================================== */

/* ---- Gilroy (brand display face) ---- */
@font-face { font-family: "Gilroy"; src: url("fonts/Gilroy-Light.ttf")   format("truetype"); font-weight: 300; font-style: normal; font-display: swap; }
@font-face { font-family: "Gilroy"; src: url("fonts/Gilroy-Regular.ttf") format("truetype"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Gilroy"; src: url("fonts/Gilroy-Medium.ttf")  format("truetype"); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: "Gilroy"; src: url("fonts/Gilroy-Bold.ttf")    format("truetype"); font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: "Gilroy"; src: url("fonts/Gilroy-Heavy.ttf")   format("truetype"); font-weight: 800; font-style: normal; font-display: swap; }

:root {
  /* === Profitcast brand colours (per brand guideline pp. 18–19) === */
  --pc-cyan:      #00A1C7;   /* primary 1 */
  --pc-green:     #00FFAA;   /* primary 2 / gradient terminus */
  --pc-orange:    #FF6826;   /* secondary — CTA punch */
  --pc-grey:      #BCBEC0;   /* dividers, muted */
  --pc-near-black:#414042;   /* brand "K-95%" near-black */

  /* signature gradient */
  --pc-gradient:      linear-gradient(135deg, #00A1C7 0%, #00D4B5 55%, #00FFAA 100%);
  --pc-gradient-soft: linear-gradient(135deg, #00A1C7 0%, #00FFAA 100%);

  /* === Working palette (mapped onto brand) === */
  --cyan:        #00A1C7;
  --cyan-deep:   #0A7E9C;          /* deep cyan for filled cards / text */
  --green:       #00FFAA;
  --green-tint:  #DEFFF2;
  --mint:        #B7F4DE;          /* light mint card fill */
  --orange:      #FF6826;
  --orange-deep: #E14E0F;
  --peach:       #FFDAC6;          /* soft warm card fill (orange family) */
  --sky:         #E6F6FA;          /* cyan tint */
  --lavender:    #E6F6FA;

  /* aliases kept for compatibility with existing markup */
  --teal:        var(--cyan);
  --teal-bright: var(--green);
  --teal-deep:   var(--cyan-deep);
  --blue:        var(--cyan-deep);
  --blue-soft:   var(--sky);
  --lime:        var(--mint);
  --pink:        var(--peach);
  --navy:        var(--ink);
  --plum:        var(--ink);
  --coral:       var(--orange);
  --yellow:      var(--green);

  /* === Surfaces & ink === */
  --ink:         #1B1C1E;          /* primary text + dark surfaces */
  --ink-soft:    #5C6063;          /* muted body text */
  --paper:       #FFFFFF;
  --cream:       #F7F8F9;          /* grey-50 surface */
  --cream-deep:  #E6F6FA;          /* subtle cyan-tint section band */

  --line:       rgba(27, 28, 30, 0.12);
  --line-bold:  rgba(27, 28, 30, 0.85);
  --line-on-dark: rgba(255, 255, 255, 0.16);
  --border-strong: #BCBEC0;
  --pc-cyan-tint: #E6F6FA;

  /* === Type === */
  --font-display: "Gilroy", "Helvetica Neue", Arial, sans-serif;
  --font-body:    "Rubik", "Helvetica Neue", Arial, sans-serif;
  --font-italic:  "Gilroy", "Helvetica Neue", Arial, sans-serif;
  --font-light:   "Gilroy", "Helvetica Neue", sans-serif;
  --font-mono:    "JetBrains Mono", ui-monospace, "SF Mono", monospace;

  /* === Scale === */
  --radius-sm: 16px;
  --radius:    16px;
  --radius-lg: 16px;
  --radius-pill: 16px;

  /* brand soft, faintly-cool shadows */
  --shadow-card: 0 2px 6px rgba(20, 30, 40, 0.05), 0 18px 40px -20px rgba(20, 30, 40, 0.16);
  --shadow-brand: 0 16px 40px -12px rgba(0, 161, 199, 0.42);

  /* === Glass + Clay === */
  /* clay = soft inflated body: top specular highlight + inner bottom shade + puffy drop.
     glass = translucent frosted surface with a diagonal light sheen. Strokes KEPT (soft). */
  --clay-shadow:
    inset 0 2px 1px rgba(255, 255, 255, 0.9),
    inset 0 -16px 30px -22px rgba(10, 40, 55, 0.14),
    0 24px 54px -24px rgba(12, 40, 60, 0.20),
    0 8px 20px -14px rgba(0, 120, 150, 0.10);
  --clay-shadow-hover:
    inset 0 2px 1px rgba(255, 255, 255, 1),
    inset 0 -16px 30px -22px rgba(10, 40, 55, 0.14),
    0 40px 78px -30px rgba(0, 161, 199, 0.32),
    0 12px 28px -18px rgba(12, 40, 60, 0.14);
  --clay-shadow-tint:
    inset 0 2px 1px rgba(255, 255, 255, 0.7),
    inset 0 -18px 32px -24px rgba(10, 40, 55, 0.18),
    0 24px 54px -24px rgba(12, 40, 60, 0.18),
    0 8px 20px -14px rgba(0, 120, 150, 0.10);
  /* small clay shadow for chips/pills/inputs */
  --clay-shadow-sm:
    inset 0 1.5px 0 rgba(255, 255, 255, 0.9),
    0 6px 16px -10px rgba(12, 40, 60, 0.18);
  --glass-blur: blur(14px) saturate(140%);
  /* diagonal frosted sheen layered over translucent surfaces */
  --glass-sheen: linear-gradient(154deg, rgba(255,255,255,0.55) 0%, rgba(255,255,255,0.14) 40%, rgba(255,255,255,0) 72%);
  --glass-sheen-soft: linear-gradient(154deg, rgba(255,255,255,0.4) 0%, rgba(255,255,255,0.08) 46%, rgba(255,255,255,0) 76%);
}

/* gradient brand fills */
.brand-gradient { background: var(--pc-gradient); }
.brand-gradient-text,
.grad-text {
  background: var(--pc-gradient);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html { background-color: #ffffff !important; }
body {
  font-family: var(--font-body);
  color: var(--ink);
  background-color: #ffffff !important;
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; }

::selection { background: var(--pc-green); color: var(--ink); }

/* ---------- Type ---------- */
/* Gilroy reserved for hero display + big numbers + emphasis (~20%);
   Rubik carries everything else (~80%). Weights kept light & airy. */
.display, h1 {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.08;
  margin: 0;
  text-wrap: balance;
}
h2 {
  font-family: var(--font-body);
  font-weight: 600;
  letter-spacing: -0.012em;
  line-height: 1.1;
  margin: 0;
  text-wrap: balance;
}
h3 {
  font-family: var(--font-body);
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1.12;
  margin: 0;
  text-wrap: balance;
}
h1 { font-size: clamp(40px, 5.2vw, 76px); }
h2 { font-size: clamp(28px, 3.2vw, 46px); }
h3 { font-size: clamp(22px, 2.1vw, 30px); }
h4 { font-family: var(--font-body); font-weight: 500; font-size: 22px; margin: 0; letter-spacing: -0.01em; }
p  { margin: 0; text-wrap: pretty; }

/* Emphasis treatment — brand signature gradient text by default,
   solid colour when an explicit highlight class is present.
   (Replaces the old italic-serif accent; reads as gradient/orange mix.) */
.serif-it {
  font-family: var(--font-display);
  font-style: normal;
  font-weight: 700;
  letter-spacing: -0.018em;
  background: var(--pc-gradient);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
/* Emphasis words inherit the signature gradient (was orange) */
.serif-it.hl-orange,
.serif-it.hl-pink { background: var(--pc-gradient); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent; }
.serif-it.hl-blue,
.serif-it.hl-teal { background: none; -webkit-text-fill-color: var(--cyan-deep); color: var(--cyan-deep); }

.mono { font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase; }

.hl-orange { color: var(--cyan-deep); }
.hl-blue, .hl-teal { color: var(--cyan-deep); }
.hl-pink { color: var(--cyan-deep); }

/* Highlight-marker style */
.hl-mark {
  background: var(--cyan-deep);
  color: #fff;
  padding: 0 .18em;
  border-radius: 4px;
  white-space: nowrap;
}

/* hand-drawn gradient underline — one seamless standard site-wide.
   The wave tile carries a SYMMETRIC gradient (cyan -> mint -> cyan) over a
   long 6em colour cycle, so tiles butt together with no visible seam on any
   word length. Humps repeat every 1em, so the stroke weight, hump size and
   gap stay identical everywhere and scale with the text. A short word (~3em,
   e.g. "sales") shows a clean cyan -> mint sweep; wider phrases flow back to
   cyan without a break. */
.underline-wavy {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 144 8' preserveAspectRatio='none'><defs><linearGradient id='pcw' x1='0' y1='0' x2='1' y2='0'><stop offset='0' stop-color='%2300A1C7'/><stop offset='0.25' stop-color='%2300D4B5'/><stop offset='0.5' stop-color='%2300FFAA'/><stop offset='0.75' stop-color='%2300D4B5'/><stop offset='1' stop-color='%2300A1C7'/></linearGradient></defs><path d='M0 4 Q 6 1.6 12 4 T 24 4 T 36 4 T 48 4 T 60 4 T 72 4 T 84 4 T 96 4 T 108 4 T 120 4 T 132 4 T 144 4' fill='none' stroke='url(%23pcw)' stroke-width='2.4' stroke-linecap='round'/></svg>");
  background-repeat: repeat-x;
  background-position: 0 100%;
  background-size: 6em 0.32em;
  padding-bottom: 0.32em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

/* ---------- Layout ---------- */
.wrap { max-width: 1280px; margin: 0 auto; padding: 0 40px; }
.wrap-tight { max-width: 1020px; margin: 0 auto; padding: 0 40px; }
.section { padding: clamp(56px, 6vw, 84px) 0; }
.section-sm { padding: clamp(44px, 4.5vw, 64px) 0; }

/* ---------- Aura (aurora wash that fades out before the section edges,
   so it never cuts abruptly against a neighbouring white section) ---------- */
.aura { position: relative; background: var(--paper); }
.aura > * { position: relative; z-index: 1; }
/* Aura: a soft, symmetric wash that frames the section content, mint drifting
   down from the top edge, cyan rising from the bottom, both centred and low
   opacity. Reads as one calm gradient field rather than off-centre blobs. */
.aura::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(140% 90% at 50% -22%, rgba(0, 255, 170, 0.12), transparent 62%),
    radial-gradient(120% 80% at 50% 122%, rgba(0, 161, 199, 0.10), transparent 60%);
}
.aura--soft::before {
  background:
    radial-gradient(140% 90% at 50% -22%, rgba(0, 255, 170, 0.07), transparent 62%),
    radial-gradient(120% 80% at 50% 122%, rgba(0, 161, 199, 0.06), transparent 60%);
}

/* ---------- Buttons ---------- */
/* The hidden attribute only works through the UA stylesheet's display:none,
   which loses to ANY author display rule. .btn's inline-flex below was quietly
   beating it, which is how the contact form showed "Send it" and "Back" on
   step one with the markup plainly saying hidden. One rule ends the whole
   class of bug. */
[hidden] { display: none !important; }

.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 16px;
  padding: 14px 26px;
  border-radius: var(--radius);
  border: 0;
  background: var(--cyan-deep);
  color: var(--paper);
  transition: transform .18s var(--ease-out, cubic-bezier(0.2,0.7,0.2,1)), box-shadow .22s ease, background .18s ease, filter .18s ease;
  letter-spacing: -0.005em;
}
.btn:hover { transform: translateY(-2px); box-shadow: 0 14px 30px -10px rgba(0, 161, 199, 0.4); }
.btn:active { transform: scale(0.985); }
.btn .arr {
  width: 22px; height: 22px; border-radius: 50%; background: var(--pc-gradient); color: #fff;
  display: inline-flex; align-items: center; justify-content: center; font-size: 12px;
}
/* Buttons sit on --orange-deep, not --orange. White text on #FF6826 measures
   2.89:1, which fails even the relaxed large-text bar; on #E14E0F it is
   3.96:1. Still shy of strict AA for 16px text (that needs #CC4409, a visibly
   burnt orange, a brand call rather than a CSS one), but no longer failing
   everything. --orange stays the accent for stars and trim, where nothing has
   to be read on top of it. */
.btn-orange { background: var(--orange-deep); color: #fff; box-shadow: inset 0 2px 1px rgba(255,255,255,0.4), inset 0 -10px 18px -10px rgba(120,30,0,0.5), 0 14px 26px -12px rgba(225,78,15,0.5); }
.btn-orange:hover { background: #C74208; }
.btn-orange .arr { background: #fff; color: var(--orange-deep); }
.btn-ghost {
  background-color: rgba(255, 255, 255, 0.6);
  background-image: var(--glass-sheen);
  color: var(--ink); border: 1px solid var(--line);
  box-shadow: var(--clay-shadow-sm);
}
.btn-ghost:hover { background-color: rgba(255,255,255,0.85); border-color: var(--cyan); box-shadow: var(--clay-shadow-sm), 0 0 0 3px rgba(0,161,199,0.12); }
.btn-teal { background: var(--cyan-deep); color: #fff; box-shadow: inset 0 2px 1px rgba(255,255,255,0.35), inset 0 -10px 18px -10px rgba(0,40,55,0.5), 0 14px 26px -12px rgba(10,126,156,0.5); }
.btn-teal .arr { background: #fff; color: var(--cyan-deep); }
.btn-grad { background: var(--pc-gradient); color: #fff; box-shadow: inset 0 2px 1px rgba(255,255,255,0.55), inset 0 -10px 18px -10px rgba(0,80,90,0.4), 0 16px 30px -12px rgba(0,161,199,0.55); }
.btn-grad .arr { background: #fff; color: var(--cyan-deep); }

/* ---------- Stickers / badges (soft frosted-clay chips, NO neubrutalist black stroke) ---------- */
.sticker {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-mono); font-size: 11px;
  text-transform: uppercase; letter-spacing: 0.1em;
  padding: 9px 16px; border-radius: var(--radius-pill);
  background-color: rgba(255, 255, 255, 0.7);
  background-image: var(--glass-sheen);
  border: 1px solid var(--line);
  color: var(--ink);
  box-shadow: var(--clay-shadow-sm);
}
.sticker .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--cyan); box-shadow: 0 0 0 3px rgba(0,161,199,0.18); }
.sticker--lime { background-color: rgba(183, 244, 222, 0.8); border-color: rgba(0,120,90,0.16); }
.sticker--pink { background-color: rgba(255, 218, 198, 0.8); border-color: rgba(150,70,30,0.16); }
.sticker--blue { background-color: rgba(230, 246, 250, 0.85); border-color: rgba(0,90,120,0.16); }
.sticker--ink  { background-color: var(--cyan-deep); background-image: var(--glass-sheen-soft); color: var(--paper); border-color: rgba(255,255,255,0.14); box-shadow: inset 0 2px 1px rgba(255,255,255,0.2), 0 12px 22px -12px rgba(12,40,60,0.5); }
.sticker--ink .dot { background: var(--green); box-shadow: 0 0 0 3px rgba(0,255,170,0.22); }
.sticker--teal { background-color: rgba(183, 244, 222, 0.8); border-color: rgba(0,120,90,0.16); }

/* spinning sticker — brand gradient */
@keyframes spin-slow { from { transform: rotate(0); } to { transform: rotate(360deg); } }
.spin-sticker {
  width: 128px; height: 128px;
  border-radius: 50%;
  background: var(--ink);
  color: #fff;
  display: grid; place-items: center;
  font-family: var(--font-display); font-weight: 700; font-size: 16px;
  position: relative;
  box-shadow: 0 0 0 5px var(--paper), 0 18px 34px -14px rgba(12,20,28,0.55);
}
.spin-sticker svg { animation: spin-slow 16s linear infinite; }
.spin-sticker .core {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-family: var(--font-display); font-weight: 700;
}

/* ---------- Cards (glass sheen + clay body; soft stroke kept) ---------- */
.card {
  position: relative;
  background-color: rgba(255, 255, 255, 0.72);
  background-image: var(--glass-sheen);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 26px;
  box-shadow: var(--clay-shadow);
  transition: transform .24s cubic-bezier(0.2,0.7,0.2,1), box-shadow .24s ease;
}
.card:hover { transform: translateY(-5px); box-shadow: var(--clay-shadow-hover); }
.card--orange { background-color: var(--orange); background-image: var(--glass-sheen-soft); color: #fff; border-color: rgba(255,255,255,0.4); box-shadow: var(--clay-shadow-tint); }
.card--orange h3, .card--orange h4 { color: #fff; }
.card--blue, .card--teal { background-color: var(--cyan-deep); background-image: var(--glass-sheen-soft); color: #fff; border-color: rgba(255,255,255,0.32); box-shadow: var(--clay-shadow-tint); }
.card--blue h3, .card--blue h4, .card--teal h3, .card--teal h4 { color: #fff; }
.card--lime   { background-color: rgba(183, 244, 222, 0.82); background-image: var(--glass-sheen); border-color: rgba(0,120,90,0.16); box-shadow: var(--clay-shadow-tint); }
.card--pink   { background-color: rgba(255, 218, 198, 0.82); background-image: var(--glass-sheen); border-color: rgba(150,70,30,0.16); box-shadow: var(--clay-shadow-tint); }
.card--sky    { background-color: rgba(230, 246, 250, 0.86); background-image: var(--glass-sheen); border-color: rgba(0,90,120,0.16); box-shadow: var(--clay-shadow-tint); }
.card--ink    { background-color: #0A7E9C; background-image: linear-gradient(155deg, rgba(8,50,61,0.92) 0%, rgba(10,126,156,0.86) 100%), var(--glass-sheen-soft); color: var(--paper); border-color: rgba(255,255,255,0.2); box-shadow: var(--clay-shadow-tint); }
.card--ink h3, .card--ink h4 { color: var(--paper); }
.card--brand  { background-color: #00cfb0; background-image: var(--pc-gradient), var(--glass-sheen-soft); color: var(--ink); border-color: rgba(255,255,255,0.55); box-shadow: var(--clay-shadow-tint), var(--shadow-brand); }
.card--brand h3, .card--brand h4 { color: var(--ink); }

/* AEO direct-answer, rebuilt as a scannable "quick answer" card (question + calm answer + fact chips) */
.answer-card { position: relative; overflow: hidden; padding: 28px 32px; }
.answer-card .answer-q { margin: 16px 0 0; font-family: var(--font-display); font-weight: 600; font-size: clamp(18px, 1.7vw, 22px); line-height: 1.3; letter-spacing: -.01em; color: var(--ink); }
.answer-card .answer-a { margin: 12px 0 0; font-size: 16.5px; line-height: 1.62; color: var(--ink-soft); max-width: 78ch; }
.answer-card .answer-facts { list-style: none; display: flex; flex-wrap: wrap; gap: 10px; margin: 20px 0 0; padding: 0; }
.answer-card .answer-facts li { display: inline-flex; align-items: center; gap: 8px; font-family: var(--font-mono); font-size: 12px; letter-spacing: .02em; color: var(--ink); background-color: rgba(255,255,255,0.62); border: 1px solid var(--line); border-radius: 12px; padding: 8px 13px; }
.answer-card .answer-facts li::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--pc-gradient); flex-shrink: 0; }

/* Roadmap, retooled as a numbered timeline (one tight line per phase) */
.roadmap-grid .rm-step { display: flex; flex-direction: column; }
.rm-step .rm-num { font-family: var(--font-display); font-weight: 700; font-size: 30px; line-height: 1; background: var(--pc-gradient); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent; }
.rm-step .rm-when { font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); margin-top: 14px; }
.rm-step h3 { font-size: 19px; margin-top: 6px; }
.rm-step p { margin-top: 10px; color: var(--ink-soft); font-size: 14px; line-height: 1.5; }

/* Fallback: browsers without backdrop-filter keep surfaces fully opaque. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .card   { background-color: var(--paper); }
  .sticker { background-color: var(--paper); }
  .sticker--lime { background-color: var(--mint); }
  .sticker--pink { background-color: var(--peach); }
  .sticker--blue { background-color: var(--sky); }
  .card--lime { background-color: var(--mint); }
  .card--pink { background-color: var(--peach); }
  .card--sky  { background-color: var(--sky); }
  .tag { background-color: var(--paper); }
}

/* ---------- Header / Nav (sticky frosted glass) ---------- */
/* Wrapper must not create a box, or it shrink-wraps the nav and breaks
   position:sticky (the nav's containing block becomes <body>). */
#site-header { display: contents; }
.nav {
  position: sticky; top: 0; z-index: 50;
  background-color: rgba(255, 255, 255, 0.62);
  -webkit-backdrop-filter: saturate(180%) blur(18px);
  backdrop-filter: saturate(180%) blur(18px);
  border-bottom: 1px solid var(--line);
  box-shadow: 0 8px 24px -18px rgba(12,40,60,0.4);
}
.nav-inner {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 32px;
  max-width: 1440px; margin: 0 auto;
}
.brand {
  display: inline-flex; align-items: center; gap: 10px;
  color: var(--ink);
}
.brand img, .brand svg { height: 36px; width: auto; }

.nav-links { display: flex; gap: 8px; align-items: center; }
.nav-links a {
  padding: 9px 15px; border-radius: var(--radius);
  font-weight: 450; font-size: 15px; color: var(--ink);
  transition: background .15s ease, color .15s ease;
}
.nav-links a:hover { background: rgba(27,28,30,0.05); }
.nav-links a.active { background: var(--cyan-deep); color: var(--paper); }
.nav-cta { display: flex; gap: 10px; align-items: center; }

/* services dropdown */
.has-menu { position: relative; }
.menu-trigger { display: inline-flex; align-items: center; gap: 7px; cursor: pointer; }
.menu-trigger .caret { width: 13px; height: 13px; transition: transform .22s var(--ease-out, ease); opacity: .7; }
.has-menu:hover .menu-trigger .caret,
.has-menu:focus-within .menu-trigger .caret { transform: rotate(180deg); }
.menu {
  position: absolute; top: calc(100% + 12px); left: -20px;
  background-color: #ffffff;
  -webkit-backdrop-filter: saturate(180%) blur(26px);
  backdrop-filter: saturate(180%) blur(26px);
  border: 1px solid var(--line);
  border-radius: var(--radius); padding: 10px;
  box-shadow: var(--clay-shadow), 0 40px 90px -28px rgba(12,40,60,0.55);
  min-width: 320px;
  opacity: 0; visibility: hidden; transform: translateY(-6px);
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .menu { background-color: rgba(255, 255, 255, 0.97); }
}
.has-menu:hover .menu, .has-menu:focus-within .menu {
  opacity: 1; visibility: visible; transform: translateY(0);
}
/* The panel hangs 12px clear of the trigger and that gap belongs to neither,
   so reaching for a link crossed dead space, dropped :hover, and closed the
   menu before the pointer arrived. Nothing in it could be clicked.

   The bridge has to hang off .has-menu, not off .menu. Two reasons, and the
   first one is why an earlier attempt at this silently did nothing: .menu sets
   overflow: hidden, so a pseudo-element sitting above its top edge is clipped
   out of existence. The second is that .nav-inner runs to 90px, past the
   trigger's 66, so the header itself is what the pointer lands on in the gap.
   .has-menu is position: relative with overflow visible, and a positioned
   pseudo on it paints above the static header box.

   Only while open, so there is no invisible strip sitting over the header the
   rest of the time. */
.has-menu:hover::after,
.has-menu:focus-within::after {
  content: ""; position: absolute; top: 100%; height: 16px;
  /* Matched to .menu.mega, which is anchored right: -20px and runs 620px to
     the left. Sizing this to .has-menu instead covers only the width of the
     word "Services", so reaching diagonally for anything in the left column
     still crossed dead space and still closed the menu. */
  right: -20px; width: 620px;
}
.menu a {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px; border-radius: var(--radius);
  font-size: 14px; font-weight: 500;
}
.menu a:hover { background: var(--cream); }
.menu-icon {
  width: 32px; height: 32px; border-radius: var(--radius);
  display: grid; place-items: center; flex-shrink: 0;
  font-size: 14px; font-weight: 700;
  font-family: var(--font-display);
  color: var(--paper);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.3), 0 4px 10px -4px rgba(12,40,60,0.4);
}

/* ---------- Services mega-menu ---------- */
.menu.mega {
  left: auto; right: -20px; padding: 0; overflow: hidden;
  width: 620px; min-width: 0;
}
.mega-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 4px 16px;
  padding: 16px 18px;
}
.mega-col { display: flex; flex-direction: column; gap: 1px; }
.mega-label {
  font-family: var(--font-mono); font-size: 10px;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-soft); padding: 10px 10px 6px;
}
.mega-label:first-child { padding-top: 2px; }
.mega-item {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 10px; border-radius: var(--radius);
  transition: background .14s ease, transform .14s ease;
}
.mega-item:hover { background: rgba(27,28,30,0.05); }
.mega-tx { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.mega-tx b { font-size: 14px; font-weight: 600; color: var(--ink); letter-spacing: -0.01em; }
.mega-tx i { font-style: normal; font-size: 12px; color: var(--ink-soft); margin-top: 1px; }
.mega-promo {
  display: flex; flex-direction: column; gap: 5px;
  margin-top: 10px; padding: 16px;
  border-radius: var(--radius);
  background-color: rgba(0, 207, 176, 0.10);
  background-image: var(--glass-sheen-soft);
  border: 1px solid rgba(0, 120, 90, 0.18);
}
.mega-promo-ey {
  font-family: var(--font-mono); font-size: 10px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--cyan-deep);
}
.mega-promo-h { font-size: 15px; font-weight: 600; color: var(--ink); line-height: 1.2; }
.mega-promo-cta {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 600; color: var(--ink); margin-top: 4px;
}
.mega-promo:hover .mega-promo-cta { color: var(--cyan-deep); }
.mega-promo-cta span {
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--pc-gradient); color: #fff;
  display: grid; place-items: center; font-size: 11px;
}
.mega-foot {
  display: flex; align-items: center; justify-content: flex-end;
  padding: 8px 18px 16px; border-top: 1px solid var(--line); margin-top: 4px;
}
.mega-foot .lbl { font-size: 13px; color: var(--ink-soft); }
.mega-foot .go { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; color: var(--ink); }
.mega-foot:hover .go { color: var(--cyan-deep); }
.mega-foot .arr-mini {
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--pc-gradient); color: #fff;
  display: grid; place-items: center; font-size: 12px;
}

/* ---------- Testimonials ---------- */
.t-feature {
  max-width: 940px; margin: 0 auto;
  padding: 52px 56px; position: relative; overflow: hidden;
  text-align: left;
  background-color: var(--paper);
  background-image: var(--glass-sheen);
  box-shadow:
    inset 0 2px 1px rgba(255, 255, 255, 0.9),
    0 24px 50px -28px rgba(12, 40, 60, 0.22),
    0 6px 16px -12px rgba(0, 120, 150, 0.10);
}
.t-slide .t-feature:hover { transform: none; box-shadow:
    inset 0 2px 1px rgba(255, 255, 255, 0.9),
    0 24px 50px -28px rgba(12, 40, 60, 0.22),
    0 6px 16px -12px rgba(0, 120, 150, 0.10); }
.t-mark {
  position: absolute; top: 24px; right: 44px; z-index: 0;
  font-family: var(--font-display); font-weight: 800;
  font-size: 200px; line-height: 1;
  background: var(--pc-gradient); -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  opacity: .16; pointer-events: none; user-select: none;
}
.t-quote {
  position: relative; z-index: 1; margin: 0;
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(24px, 3vw, 38px); line-height: 1.2; letter-spacing: -0.012em;
  color: var(--ink); max-width: 760px; text-wrap: balance;
}
.t-author {
  position: relative; z-index: 1;
  display: flex; align-items: center; gap: 16px;
  margin-top: 36px; padding-top: 28px; border-top: 1px solid var(--line);
}
.t-avatar {
  width: 56px; height: 56px; border-radius: 50%; flex-shrink: 0;
  display: grid; place-items: center; overflow: hidden;
  font-family: var(--font-display); font-weight: 700; font-size: 17px; color: #fff;
  background: var(--cyan-deep);
  box-shadow: inset 0 2px 1px rgba(255,255,255,0.25), 0 6px 14px -6px rgba(12,40,60,0.4);
}
.t-avatar img { width: 100%; height: 100%; object-fit: cover; }
.t-name { font-weight: 600; font-size: 17px; color: var(--ink); }
.t-role { font-family: var(--font-mono); font-size: 12px; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft); margin-top: 3px; }
.t-stars { margin-left: auto; color: var(--orange); font-size: 15px; letter-spacing: 2px; white-space: nowrap; }

/* grid card variant */
.t-card { display: flex; flex-direction: column; min-height: 300px; }
.t-card .t-cardmark {
  font-family: var(--font-display); font-weight: 800; font-size: 52px; line-height: 0.5;
  background: var(--pc-gradient); -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  height: 30px; display: block; user-select: none;
}
.t-card .t-quote {
  font-family: var(--font-body); font-weight: 450; font-size: 18px; line-height: 1.55;
  letter-spacing: 0; margin-top: 18px; flex: 1; color: var(--ink);
}
.t-card .t-author { margin-top: 22px; padding-top: 20px; }
.t-card .t-avatar { width: 46px; height: 46px; font-size: 14px; }
.t-card .t-name { font-size: 15px; }
.t-card .t-stars { font-size: 13px; }

/* ---------- Claymorphic illustration placeholder ---------- */
.illus {
  position: relative; border-radius: var(--radius); overflow: hidden;
  border: 1px solid var(--line); box-shadow: var(--clay-shadow);
  background-color: rgba(255,255,255,0.55);
  background-image:
    radial-gradient(120% 120% at 24% 18%, rgba(0,255,170,0.22), transparent 55%),
    radial-gradient(120% 120% at 82% 88%, rgba(0,161,199,0.20), transparent 55%),
    repeating-linear-gradient(135deg, rgba(0,161,199,0.10) 0 2px, transparent 2px 13px);
  display: grid; place-items: center; min-height: 200px;
  /* With `aspect-ratio: 21/9` and no width, the 200px min-height wins and the
     browser back-computes the width from it: 200 x 21/9 = 467px, which blew
     past a 390px phone. Pinning the width makes height follow instead. */
  width: 100%;
}
.illus-inner { text-align: center; padding: 28px; display: flex; flex-direction: column; align-items: center; gap: 16px; }
.illus-glyph {
  width: 72px; height: 72px; border-radius: 22px;
  background: var(--pc-gradient);
  box-shadow: inset 0 3px 3px rgba(255,255,255,0.6), inset 0 -8px 14px -6px rgba(0,90,120,0.4), 0 18px 30px -12px rgba(0,161,199,0.55);
  display: grid; place-items: center; color: #fff;
}
.illus-glyph svg { width: 34px; height: 34px; }
.illus-label { font-family: var(--font-mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft); max-width: 280px; line-height: 1.5; }

/* ---------- Marquee ---------- */
.marquee {
  background: var(--pc-gradient); color: var(--ink);
  overflow: hidden; white-space: nowrap;
  padding: 20px 0;
}
.marquee .serif-it { background: none; -webkit-text-fill-color: var(--ink); color: var(--ink); }
.marquee-track {
  display: inline-flex; gap: 56px; align-items: center;
  animation: marquee 30s linear infinite;
  font-family: var(--font-display); font-weight: 700;
  font-size: 28px; letter-spacing: -0.01em;
}
@keyframes marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.marquee-track span { display: inline-flex; align-items: center; gap: 56px; }
.marquee .star { color: #fff; font-size: 22px; }

/* ---------- Hero ornaments ---------- */
.dotgrid {
  background-image: radial-gradient(rgba(27, 28, 30, 0.16) 1.2px, transparent 1.2px);
  background-size: 14px 14px;
}

/* ---------- Image placeholders ---------- */
.placeholder {
  background:
    repeating-linear-gradient(135deg, rgba(27, 28, 30, 0.04) 0 6px, transparent 6px 12px),
    var(--cream-deep);
  border: 1.5px dashed rgba(27, 28, 30, 0.28);
  border-radius: var(--radius);
  display: grid; place-items: center;
  color: var(--ink-soft);
  font-family: var(--font-mono); font-size: 11px;
  text-transform: uppercase; letter-spacing: 0.12em;
  text-align: center; padding: 16px;
  aspect-ratio: 4/3;
}
.placeholder--portrait { aspect-ratio: 3/4; }
.placeholder--wide { aspect-ratio: 16/9; }
.placeholder--square { aspect-ratio: 1/1; }

/* ---------- Stats ---------- */
.stat-num {
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(46px, 5vw, 84px);
  letter-spacing: -0.04em; line-height: 0.95;
}

/* ---------- Footer ---------- */
.foot {
  background: var(--paper); color: var(--ink);
  padding: 80px 0 32px;
  position: relative; overflow: hidden;
  border-top: 1px solid var(--line);
}
.foot::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: radial-gradient(46% 80% at 92% 8%, rgba(0, 255, 170, 0.16), transparent 68%);
}
.foot .wrap { position: relative; z-index: 1; }
.foot a:hover { color: var(--cyan-deep); opacity: 1; }
.foot .col h5 {
  font-family: var(--font-mono); font-size: 11px;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-soft); margin: 0 0 16px;
}
.foot ul { list-style: none; padding: 0; margin: 0; display: grid; gap: 10px; }
.foot ul a { font-size: 15px; }

/* ---------- Utility ---------- */
.grid { display: grid; gap: 24px; }
.flex { display: flex; }
.center { display: grid; place-items: center; }
.relative { position: relative; }

.tag {
  display: inline-flex; align-items: center;
  font-family: var(--font-mono); font-size: 11px;
  letter-spacing: 0.1em; text-transform: uppercase;
  padding: 6px 10px; border-radius: var(--radius);
  border: 1px solid var(--line);
  background-color: rgba(255, 255, 255, 0.7);
  background-image: var(--glass-sheen);
  color: var(--ink);
  box-shadow: var(--clay-shadow-sm);
}

/* ---------- Mobile nav toggle (hidden on desktop) ---------- */
.nav-toggle {
  display: none;
  width: 44px; height: 44px; border: 1px solid var(--line);
  background-color: rgba(255,255,255,0.6); background-image: var(--glass-sheen);
  border-radius: var(--radius); box-shadow: var(--clay-shadow-sm);
  flex-direction: column; align-items: center; justify-content: center; gap: 5px;
}
.nav-toggle span { display: block; width: 20px; height: 2px; background: var(--cyan-deep); border-radius: 2px; transition: transform .2s ease, opacity .2s ease; }
.nav.open .nav-toggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav.open .nav-toggle span:nth-child(2) { opacity: 0; }
.nav.open .nav-toggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
.nav-mobile-cta { display: none; }

/* ---------- Accessibility ---------- */
:focus-visible {
  outline: 3px solid rgba(0, 161, 199, 0.55);
  outline-offset: 2px;
  border-radius: 6px;
}
@media (prefers-reduced-motion: reduce) {
  .spin-sticker svg, .marquee-track { animation: none !important; }
  * { scroll-behavior: auto !important; }
}

/* small screens */
@media (max-width: 880px) {
  .nav-toggle { display: inline-flex; }
  .nav-cta .btn-orange { display: none; }      /* CTA moves into the menu panel */
  .nav-links {
    position: absolute; top: 100%; left: 0; right: 0;
    display: none; flex-direction: column; align-items: stretch; gap: 4px;
    padding: 12px; margin: 0;
    background-color: rgba(255,255,255,0.86); background-image: var(--glass-sheen);
    border-bottom: 1px solid var(--line);
    box-shadow: var(--clay-shadow);
  }
  .nav.open .nav-links { display: flex; }
  .nav-links a { padding: 14px 16px; border-radius: var(--radius); font-size: 16px; }
  .nav-links a:hover { background: var(--cream); }
  .has-menu .menu { display: none; }            /* hide mega-menu on mobile; Services link still works */
  /* The caret has to go with it. Leaving it there advertised a dropdown that
     cannot open at this width, so Services looked like the one nav item that
     was broken when it is simply a link to the services page. */
  .menu-trigger .caret { display: none; }
  .has-menu:hover::after, .has-menu:focus-within::after { content: none; }
  .nav-mobile-cta {
    display: block; text-align: center;
    background: var(--orange); color: #fff !important; font-weight: 600;
    margin-top: 6px;
  }
  .section { padding: 48px 0; }
  .wrap, .wrap-tight { padding: 0 22px; }
}

/* ---------- Responsive grid collapse (covers inline grid templates) ---------- */
@media (max-width: 960px) {
  [style*="grid-template-columns: repeat(4"] { grid-template-columns: repeat(2, 1fr) !important; }
  [style*="grid-template-columns: repeat(3"] { grid-template-columns: repeat(2, 1fr) !important; }
  [style*="grid-template-columns: 1.25fr"],
  [style*="grid-template-columns: 1.4fr"],
  [style*="grid-template-columns: 1.1fr 0.9fr"],
  [style*="grid-template-columns: 1.18fr"],
  [style*="grid-template-columns: 0.8fr 1.2fr"],
  [style*="grid-template-columns: 0.9fr 1.1fr"],
  [style*="grid-template-columns: 1fr 1.6fr"],
  [style*="grid-template-columns: 1fr 1.4fr"] { grid-template-columns: 1fr !important; }
}
@media (max-width: 620px) {
  [style*="grid-template-columns: repeat(4"],
  [style*="grid-template-columns: repeat(3"],
  [style*="grid-template-columns: repeat(2"],
  [style*="grid-template-columns: 1fr 1fr"] { grid-template-columns: 1fr !important; }
  /* service rows: drop the leading number + trailing arrow columns into one stack */
  [style*="grid-template-columns: 80px 1.4fr 1fr 60px"] { grid-template-columns: 1fr !important; gap: 12px !important; }
}

/* ---------- Tap targets: 44px minimum on touch devices ---------- */
/* Gated on `pointer: coarse` alone, these never applied in a narrow window on a
   desktop, and `pointer` is not dependable across every touch device either. A
   width clause covers both: an audit at 390px found 17 filter chips and 7
   portfolio chips sitting at 39px. */
@media (pointer: coarse), (max-width: 1024px) {
  /* Footer legal row and the contact page's email and phone are standalone
     actions sitting in spans and divs, not links inside a sentence, so the
     inline-link exemption does not cover them. */
  .foot-legal a, .foot .foot-bottom span a { display: inline-flex; align-items: center; min-height: 44px; }
  #contact-details a, a[href^="mailto:"]:not(p a):not(li a),
  a[href^="tel:"]:not(p a):not(li a) { display: inline-flex; align-items: center; min-height: 44px; }

  /* Footer nav is a stacked list of 18px inline links, 25 of them per page, and
     they are navigation rather than prose, so they get a real target. Inline
     links inside a sentence are deliberately left alone; WCAG exempts those and
     padding them would break the line box. */
  .foot ul a { display: inline-flex; align-items: center; min-height: 44px; }
  .foot ul { gap: 2px; }
  /* The "← All services" / "← All work" back links are standalone controls,
     not prose, so they get a real target. */
  a.mono[href$="services.html"], a.mono[href$="portfolio.html"],
  .svc-hero > div > a.mono {
    display: inline-flex; align-items: center; min-height: 44px;
  }

  .pill-opt, .budget-opt, .timeline-opt,
  .filter-chip, #reset-filters,
  .pf-sub-chip, .site-pill, .pf-chip,
  a.tag {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  /* carousel dots: keep the small visual dot but grow the tappable area.
     .ts-dot (homepage depth slider) had been left out of this, so its 9px dots
     were the smallest targets on the site at tablet width. */
  .t-dot, .ts-dot, .car-dot { position: relative; }
  .t-dot::after, .ts-dot::after, .car-dot::after {
    content: ""; position: absolute; top: 50%; left: 50%;
    width: 44px; height: 44px; transform: translate(-50%, -50%);
  }
}

/* ---------- Industry/location: roadmap + key-facts responsiveness ---------- */
@media (max-width: 900px) {
  .roadmap-grid { grid-template-columns: repeat(2, 1fr) !important; }
}
@media (max-width: 520px) {
  .roadmap-grid { grid-template-columns: 1fr !important; }
}

/* ---------- Big-numbers band: proportionate, divided, responsive ---------- */
.numgrid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  border-top: 1px solid var(--line); padding-top: 48px;
}
.numstat { padding-left: 34px; border-left: 1px solid var(--line); }
.numgrid > .numstat:first-child { padding-left: 0; border-left: 0; }
.numstat .stat-num { font-size: clamp(44px, 5.4vw, 70px); line-height: 1; }
.numstat .mono { margin-top: 16px; color: var(--ink-soft); }
.numstat .sub { margin-top: 6px; font-size: 14px; color: var(--ink-soft); opacity: .8; line-height: 1.4; }
@media (max-width: 760px) {
  .numgrid { grid-template-columns: repeat(2, 1fr); gap: 36px 0; padding-top: 40px; }
  .numstat { padding-left: 28px; }
  .numstat:nth-child(odd) { padding-left: 0; border-left: 0; }
  .numstat:nth-child(even) { border-left: 1px solid var(--line); }
}
@media (max-width: 440px) {
  .numgrid { grid-template-columns: 1fr; gap: 0; }
  /* The nth-child selectors have to be repeated here, not just .numstat. The
     two-column block above sets border-left on :nth-child(even) at a higher
     specificity, and it still applies at this width, so a plain .numstat rule
     could not turn it off. Every other stat ended up with a left border as
     well as its top border, which read as half a box drawn round it. */
  .numstat,
  .numstat:nth-child(odd),
  .numstat:nth-child(even) {
    padding-left: 0; border-left: 0;
    border-top: 1px solid var(--line); padding-top: 24px; margin-top: 24px;
  }
  .numgrid > .numstat:first-child { border-top: 0; padding-top: 0; margin-top: 0; }
}

/* ---------- Image sections: mobile-first tidy-ups ---------- */
@media (max-width: 760px) {
  /* 3-up photo gallery stacks on phones */
  [style*="grid-template-columns: 1fr 1.25fr 1fr"] { grid-template-columns: 1fr !important; }
  /* war-room breather: tuck the floating note inline so it can't overflow */
  .field-note {
    position: static !important; transform: none !important;
    max-width: none !important; margin-top: 16px !important;
  }
  .field-caption { left: 14px !important; bottom: 14px !important; }
}

/* ---------- Floating contact buttons (WhatsApp + Call) — clay + glass ---------- */
.pc-fab {
  position: fixed; right: 22px; bottom: 22px; z-index: 200;
  display: flex; flex-direction: column; align-items: flex-end; gap: 14px;
}
.pc-fab-btn {
  position: relative; isolation: isolate;
  display: inline-flex; align-items: center; justify-content: flex-end;
  height: 58px; max-width: 58px; border-radius: 999px; color: #fff;
  overflow: hidden; white-space: nowrap;
  box-shadow:
    0 13px 26px -8px rgba(8,70,82,0.5),
    0 5px 12px -4px rgba(0,0,0,0.18),
    inset 0 2px 3px rgba(255,255,255,0.6),
    inset 0 -5px 10px rgba(0,40,52,0.32);
  transition: max-width .46s var(--ease-out, cubic-bezier(.2,.7,.2,1)),
              box-shadow .26s ease,
              transform .22s var(--ease-out, cubic-bezier(.2,.7,.2,1));
  animation: pc-fab-bob 4.4s ease-in-out infinite;
  will-change: transform;
}
/* glass sheen highlight */
.pc-fab-btn::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: 2;
  background: linear-gradient(157deg, rgba(255,255,255,0.5) 0%, rgba(255,255,255,0.13) 34%, rgba(255,255,255,0) 56%);
}
/* lower clay shade for the puffed look */
.pc-fab-btn::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: 1;
  background: radial-gradient(120% 82% at 50% 118%, rgba(0,30,42,0.34), transparent 60%);
}
.pc-fab-ic, .pc-fab-label { position: relative; z-index: 3; }
.pc-fab-wa { background-image: var(--pc-gradient); animation-delay: 0s; }
.pc-fab-call { background-image: linear-gradient(157deg, #1aa3c2, var(--cyan-deep)); animation-delay: -2.2s; }
.pc-fab-btn:hover, .pc-fab-btn:focus-visible {
  max-width: 320px; animation-play-state: paused;
  transform: translateY(-4px) scale(1.03);
  box-shadow:
    0 22px 38px -10px rgba(8,70,82,0.55),
    0 9px 18px -5px rgba(0,0,0,0.22),
    inset 0 2px 3px rgba(255,255,255,0.72),
    inset 0 -5px 10px rgba(0,40,52,0.34);
}
.pc-fab-btn:active { transform: translateY(-1px) scale(.97); transition-duration: .1s; }
.pc-fab-ic { flex: 0 0 58px; width: 58px; height: 58px; display: inline-flex; align-items: center; justify-content: center; }
.pc-fab-ic svg { width: 27px; height: 27px; display: block; filter: drop-shadow(0 1px 1.5px rgba(0,30,42,0.3)); transition: transform .32s var(--ease-out, cubic-bezier(.2,.7,.2,1)); }
.pc-fab-wa:hover .pc-fab-ic svg { transform: scale(1.12) rotate(-7deg); }
.pc-fab-call:hover .pc-fab-ic svg { transform: scale(1.12) rotate(8deg); }
.pc-fab-label {
  font-family: var(--font-mono); font-size: 13px; font-weight: 500; letter-spacing: .02em;
  padding: 0 4px 0 20px; opacity: 0; transform: translateX(8px);
  transition: opacity .2s ease .08s, transform .3s var(--ease-out, cubic-bezier(.2,.7,.2,1)) .06s;
}
.pc-fab-btn:hover .pc-fab-label, .pc-fab-btn:focus-visible .pc-fab-label { opacity: 1; transform: translateX(0); }
@keyframes pc-fab-bob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-5px); } }
@media (max-width: 600px) { .pc-fab { right: 16px; bottom: 16px; gap: 12px; } }
@media (prefers-reduced-motion: reduce) { .pc-fab-btn { animation: none; } }
@media print { .pc-fab { display: none; } }
/* ---------- Trusted-by logo wall ----------
   Was an auto-scrolling marquee of thirty-five logos in white cards. Two
   problems with that: a reader never saw the set, only whatever happened to be
   sliding past, and the cards competed with the marks inside them. They sit
   still now, in rows, with no chrome. Quiet grey at rest, full strength on
   hover, and nothing moving next to the copy above it. */
.logo-wall { background: var(--cream); }
/* Five across, not six. At six the marks were capped so small that half the
   wordmarks were unreadable, which defeats the point of a client wall. */
.logo-grid {
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 42px 44px; align-items: center; justify-items: center;
}
.logo-cell { display: flex; align-items: center; justify-content: center;
  width: 100%; min-height: 72px; }
.logo-img {
  max-width: 100%; max-height: 66px; width: auto; height: auto;
  object-fit: contain; display: block;
  /* Muted so the wall reads as one texture rather than thirty-five marks all
     shouting. Colour returns when you point at one. */
  filter: grayscale(1); opacity: .5;
  transition: filter .28s ease, opacity .28s ease;
}
.logo-cell:hover .logo-img,
.logo-cell:focus-within .logo-img { filter: grayscale(0); opacity: 1; }
.logo-cell:hover, .logo-cell:focus-within { transform: translateY(-3px); }
.logo-cell { transition: transform .24s cubic-bezier(.2,.7,.3,1); }

/* The wall settles in a wave rather than appearing all at once. Fast per cell
   and a short step between them, because thirty-five marks at any slower turns
   the entrance into something you have to sit and wait out. */
.js .logo-wall.is-in .logo-cell {
  animation: pc-rise .38s cubic-bezier(.2,.7,.3,1) both;
  animation-delay: calc(var(--i, 0) * 22ms);
}
.logo-mark {
  display: grid; place-items: center; width: 34px; height: 34px; border-radius: 9px;
  background: rgba(27,28,30,.07); color: var(--ink-soft);
  font-family: var(--font-display); font-weight: 700; font-size: 14px; line-height: 1;
}
.logo-nm { margin-left: 9px; font-size: 13px; color: var(--ink-soft); white-space: nowrap; }
@media (max-width: 1000px) {
  .logo-grid { grid-template-columns: repeat(4, minmax(0,1fr)); gap: 34px 32px; }
  .logo-cell { min-height: 62px; }
  .logo-img { max-height: 56px; }
}
/* Two across on a phone. Three squeezed each mark into roughly 90px of width,
   which is why they were unreadable there. */
@media (max-width: 640px) {
  .logo-grid { grid-template-columns: repeat(2, minmax(0,1fr)); gap: 28px 24px; }
  .logo-cell { min-height: 56px; }
  .logo-img { max-height: 50px; }
}
@media (prefers-reduced-motion: reduce) {
  .logo-img, .logo-cell { transition: none; }
  .js .logo-wall.is-in .logo-cell { animation: none; }
}

/* ---------- Services bento (quirky core grid) ---------- */
.svc-bento { display: grid; grid-template-columns: repeat(12, 1fr); gap: 22px; }
.svc-card { position: relative; overflow: hidden; display: flex; flex-direction: column; justify-content: space-between; min-height: 320px; }
.svc-7 { grid-column: span 7; }
.svc-5 { grid-column: span 5; }
.svc-card > div { position: relative; z-index: 1; }
.svc-ghost {
  position: absolute; top: -6px; right: 18px; z-index: 0;
  font-family: var(--font-display); font-weight: 800; font-size: 150px; line-height: 1;
  opacity: 0.10; pointer-events: none; user-select: none;
}
.svc-pin { position: absolute; top: 16px; right: 16px; z-index: 4; transform: rotate(4deg); transition: transform .2s var(--ease-out, ease); }
.svc-card:hover .svc-pin { transform: rotate(-2deg) scale(1.05); }
.svc-get { margin-top: 16px; display: flex; gap: 9px; align-items: baseline; font-size: 15px; line-height: 1.4; }
.svc-get .svc-arrow { flex: 0 0 auto; font-family: var(--font-mono); font-weight: 600; transition: transform .22s var(--ease-out, ease); }
.svc-card:hover .svc-get .svc-arrow { transform: translateX(5px); }

/* Service bento — readability fixes on colour cards */
.svc-card.card--blue,
.svc-card.card--teal {
  background-image:
    linear-gradient(155deg, rgba(7,58,72,0.97) 0%, rgba(9,104,128,0.9) 100%),
    var(--glass-sheen-soft);
}
/* accent words: bright mint on dark/teal cards so they don't sink into the bg */
.svc-card.card--ink .serif-it,
.svc-card.card--blue .serif-it,
.svc-card.card--teal .serif-it {
  background: none;
  -webkit-text-fill-color: var(--green);
  color: var(--green);
}
/* full-strength body copy on the coloured cards */
.svc-card.card--ink p,
.svc-card.card--blue p,
.svc-card.card--teal p { opacity: 1 !important; }

.svc-stack-note { display: flex; justify-content: center; margin: 28px 0; }
.svc-stack-note span {
  font-family: var(--font-mono); font-size: 12px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--ink-soft); background: rgba(255,255,255,0.6);
  border: 1px dashed var(--pc-grey); border-radius: 999px; padding: 9px 20px; transform: rotate(-1.2deg);
}
.svc-also-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin: 0 0 18px; }
.svc-also { position: relative; display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; }
/* clean glass cards: a gradient hairline that wipes in on hover, plus a soft lift.
   (replaces the scattered corner-glow blobs, which read as smudges) */
.svc-also .card {
  position: relative; z-index: 1; overflow: hidden;
  transition: transform .2s var(--ease-out, ease), box-shadow .25s ease;
}
.svc-also .card::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px; z-index: 2;
  background: var(--pc-gradient); transform: scaleX(0); transform-origin: left;
  transition: transform .3s var(--ease-out, ease);
}
.svc-also .card > * { position: relative; z-index: 1; }
.svc-also .card:hover { transform: translateY(-4px); box-shadow: var(--clay-shadow-hover); }
.svc-also .card:hover::before { transform: scaleX(1); }

/* ---------- "Whole funnel, one place" convergence diagram ---------- */
.funnel-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: center; }

/* two-column redirect teaser (Featured work -> results page) */
.redir-grid { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 64px; align-items: center; }
.redir-grid .illus { min-height: 320px; }
@media (max-width: 880px) { .redir-grid { grid-template-columns: 1fr; gap: 36px; } }

@media (max-width: 880px) {
  .funnel-grid { grid-template-columns: 1fr; gap: 34px; }
}

@media (max-width: 880px) {
  .svc-bento { grid-template-columns: 1fr; }
  .svc-7, .svc-5 { grid-column: auto; }
  .svc-also { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 480px) {
  .svc-also { grid-template-columns: 1fr; }
  .svc-ghost { font-size: 108px; }
}

/* ---------- Process timeline (How it works) ---------- */
.timeline { position: relative; display: grid; gap: 16px; }
.timeline::before {
  content: ""; position: absolute; left: 23px; top: 22px; bottom: 22px; width: 2px;
  background: linear-gradient(var(--cyan), var(--green)); border-radius: 2px; opacity: .55;
}
.tl-step { position: relative; display: grid; grid-template-columns: 48px 1fr; gap: 22px; align-items: start; }
.tl-node {
  position: relative; z-index: 1; width: 48px; height: 48px; border-radius: 50%;
  display: grid; place-items: center;
  font-family: var(--font-display); font-weight: 800; font-size: 17px; color: #fff;
  background: var(--pc-gradient); border: 3px solid var(--paper);
  box-shadow: var(--shadow-brand);
}
.tl-eyebrow {
  font-family: var(--font-mono); font-size: 12px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--cyan-deep);
}
.tl-card h4 { margin-top: 6px; }
.tl-step.is-final .tl-node { background: var(--green); color: var(--ink); box-shadow: 0 10px 26px -10px rgba(0,255,170,.6); }
.tl-step.is-final .tl-eyebrow { color: var(--green); }
@media (max-width: 560px) {
  .tl-step { grid-template-columns: 40px 1fr; gap: 16px; }
  .tl-node { width: 40px; height: 40px; font-size: 15px; }
  .timeline::before { left: 19px; }
}

/* Process section: stack to one column and drop sticky on narrow screens */
@media (max-width: 760px) {
  .process-grid { grid-template-columns: 1fr !important; gap: 40px !important; }
  .process-intro { position: static !important; top: auto !important; }
}

/* ---------- Behind-the-scenes editorial mosaic ---------- */
.bts-mosaic {
  display: grid;
  grid-template-columns: 1.5fr 1fr;
  grid-template-areas: "hero tall" "wide tall";
  gap: 18px;
}
.bts-mosaic .card { padding: 0; overflow: hidden; }
.bts-hero { grid-area: hero; position: relative; }
.bts-wide { grid-area: wide; }
.bts-tall { grid-area: tall; }
.bts-hero image-slot { display: block; width: 100%; height: auto; aspect-ratio: 16 / 10; }
.bts-wide image-slot { display: block; width: 100%; height: auto; aspect-ratio: 20 / 9; }
.bts-tall, .bts-tall image-slot { height: 100%; }
.bts-tall image-slot { display: block; width: 100%; min-height: 340px; }
.bts-caption { position: absolute; left: 16px; bottom: 16px; z-index: 3; }
@media (max-width: 760px) {
  .bts-mosaic { grid-template-columns: 1fr; grid-template-areas: "hero" "tall" "wide"; }
  .bts-tall, .bts-tall image-slot { height: auto; }
  .bts-tall image-slot { aspect-ratio: 4 / 5; min-height: 0; }
}

/* ---------- Testimonials, versatile masonry ---------- */
.t-masonry { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; align-items: stretch; }
.t-masonry .t-card {
  display: flex; flex-direction: column; width: 100%; margin: 0;
}
.t-card .t-stars { margin: 0 0 16px; color: var(--orange); font-size: 15px; letter-spacing: 2px; }
.t-card .t-metric {
  display: flex; align-items: baseline; gap: 10px; margin: 0 0 12px;
}
.t-card .t-metric b {
  font-family: var(--font-display); font-weight: 800; font-size: 40px; line-height: 1; letter-spacing: -0.02em;
  background: var(--pc-gradient); -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}
.t-card .t-metric span {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-soft); max-width: 130px; line-height: 1.35;
}
.t-card .t-quote { margin-top: 0; font-size: 17px; font-weight: 450; line-height: 1.55; color: var(--ink); }
.t-card .t-author { margin-top: auto; padding-top: 18px; border-top: 1px solid var(--line); }
/* one uniform type scale across every card, colour is the only variant */
/* colour variants keep text legible */
.t-card.card--blue .t-quote, .t-card.card--blue .t-name { color: #fff; }
.t-card.card--blue .t-role { color: rgba(255,255,255,.72); }
.t-card.card--blue .t-metric span { color: rgba(255,255,255,.8); }
.t-card.card--blue .t-metric b { background: none; -webkit-text-fill-color: var(--green); color: var(--green); }
.t-card.card--blue .t-author { border-top-color: rgba(255,255,255,.28); }
.t-card.card--lime .t-metric b { background: none; -webkit-text-fill-color: var(--cyan-deep); color: var(--cyan-deep); }
@media (max-width: 900px) { .t-masonry { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .t-masonry { grid-template-columns: 1fr; } }

/* ---------- Featured testimonial carousel ---------- */
.t-carousel { position: relative; max-width: 940px; margin: 0 auto; }
/* The slides are stacked in a single grid cell instead of strung along a
   sliding track, so only the live quote is ever on screen.

   The track used to be 14 cards wide and had to be clipped, and the clip cut
   through the card's shadow. Padding the viewport to move the clip off the
   shadow then left a 34px gutter on each side with the neighbouring cards
   showing through it, which read as two broken slivers flanking the quote.
   Stacking removes the cause: nothing overflows, so nothing is clipped, and
   the shadow is whole on all four sides again.

   Slides stretch to the tallest quote (285-342px across the current 14), so
   the card holds one size and the section never jumps as quotes change.

   The waiting slides sit 30px off to one side, which would otherwise push the
   page 3px wider and raise a horizontal scrollbar, so the x axis is clipped.
   No padding this time: the card's shadow is `0 24px 50px -28px`, which spreads
   about 21px below the card and effectively nothing either side, so a clip on
   the card's own edge takes none of it. `clip` rather than `hidden` so this
   never becomes a scroll container, and y stays visible for that shadow. */
.t-viewport { position: relative; overflow-x: clip; overflow-y: visible; }
.t-track { display: grid; }
/* Both cards are the same white surface in the same rect, so fading one out
   while the other fades in punches a hole through to the section background:
   at the crossover the pair composited to about 60%, which read as the card
   flashing pale. Instead the incoming card sits on top (z-index) and fades in
   over the outgoing one, which holds full opacity underneath until it is
   covered (.26s delay) and only then drops. The union stays solid, so the
   quote reads as being replaced rather than blinking. */
.t-slide {
  grid-area: 1 / 1; min-width: 0; z-index: 1;
  opacity: 0; pointer-events: none;
  transform: translateX(30px) scale(.985);
  transition: opacity .28s ease .26s, transform .5s cubic-bezier(.22,.68,.28,1);
}
.t-slide.is-active {
  opacity: 1; pointer-events: auto; transform: none; z-index: 2;
  transition: opacity .36s ease 0s, transform .5s cubic-bezier(.22,.68,.28,1);
}
/* Every slide is as tall as the longest quote, so a short one would otherwise
   leave the author stranded mid-card with dead space under it. Push the author
   rule to the floor instead, the same way the grid testimonial cards do. */
.t-slide .t-feature { margin: 0; width: 100%; height: 100%; box-sizing: border-box; display: flex; flex-direction: column; }
.t-slide .t-author { margin-top: auto; }
.t-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 46px; height: 46px; border-radius: 50%;
  border: 1px solid var(--line); background: var(--paper); color: var(--ink);
  display: grid; place-items: center; cursor: pointer; font-size: 18px;
  box-shadow: var(--clay-shadow-sm, 0 6px 16px -8px rgba(12,40,60,.3)); z-index: 3;
  transition: background .18s, color .18s, border-color .18s;
}
.t-nav:hover { background: var(--cyan-deep); color: #fff; border-color: var(--cyan-deep); }
.t-prev { left: -22px; }
.t-next { right: -22px; }
.t-dots { display: flex; justify-content: center; gap: 8px; margin-top: 24px; }
.t-dot { width: 8px; height: 8px; border-radius: 50%; border: 0; background: var(--pc-grey, #cfd6da); cursor: pointer; padding: 0; transition: width .2s, background .2s; }
.t-dot.active { width: 22px; border-radius: 4px; background: var(--pc-gradient); }
/* Reduced motion still needs the quote to change, so keep the fade and drop
   the drift rather than freezing the carousel on one review. */
@media (prefers-reduced-motion: reduce) {
  .t-slide { transform: none; transition: opacity .2s linear .18s; }
  .t-slide.is-active { transform: none; transition: opacity .2s linear 0s; }
}
/* The counter only exists below 560px, where the dot row takes over. */
.t-count { display: none; font-family: var(--font-mono); font-size: 12px; letter-spacing: .04em; color: var(--ink-soft); }
.t-count b { color: var(--ink); font-weight: 600; }
@media (max-width: 640px) {
  .t-prev { left: 6px; } .t-next { right: 6px; }
  /* Was 40px, under the 44px tap-target floor. */
  .t-nav { width: 44px; height: 44px; }
}
/* 14 dots at 8px each is not a control anyone can hit on a phone: a 44px target
   apiece would need 616px of row. Same answer as the homepage slider, swap the
   dots for a counter and let the arrows, which clear 44px, do the driving. */
@media (max-width: 560px) {
  .t-dots { display: none; }
  .t-count { display: block; text-align: center; margin-top: 24px; }
}

/* ---- Blog (PHP CMS) ---- */
.blog-main .wrap{max-width:1080px;margin:0 auto;padding:40px 20px 80px}
.blog-post.wrap{max-width:760px}
.blog-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
.blog-card{display:block;background:var(--paper,#fff);border:1px solid var(--line,#e3e8ea);border-radius:16px;overflow:hidden;text-decoration:none;color:inherit;box-shadow:var(--clay-shadow-sm,0 6px 16px -12px rgba(12,40,60,.4))}
.blog-card img{width:100%;aspect-ratio:16/10;object-fit:cover;display:block}
.blog-card h2{font-size:19px;margin:12px 16px 6px}
.blog-card p{margin:0 16px 10px;color:var(--ink-soft,#5b6b73);font-size:14px}
.blog-card time,.blog-card .cat{display:inline-block;margin:0 16px 14px;font-size:12px;color:var(--ink-soft,#5b6b73)}
.blog-post .hero{width:100%;height:auto;border-radius:16px;margin:18px 0}
.blog-post .tldr{background:var(--cream-deep,#eef3f4);border-radius:12px;padding:16px 18px;margin:18px 0}
.blog-post .post-body{line-height:1.7;font-size:17px}
.blog-post .post-body h2{margin-top:1.6em}
.blog-post .faq details{border-bottom:1px solid var(--line,#e3e8ea);padding:10px 0}
.blog-post .author-box{background:var(--cream-deep,#eef3f4);border-radius:12px;padding:16px 18px;margin:24px 0}
.blog-post .tags span{display:inline-block;background:var(--cream-deep,#eef3f4);border-radius:999px;padding:4px 12px;font-size:12px;margin:0 6px 6px 0}
.pager{display:flex;gap:8px;margin-top:28px}
.pager a{padding:8px 12px;border:1px solid var(--line,#e3e8ea);border-radius:8px;text-decoration:none;color:inherit}
.pager a.on{background:var(--ink,#0c1418);color:#fff}
.blog-toolbar{display:flex;justify-content:space-between;align-items:center;gap:16px;margin-bottom:24px;flex-wrap:wrap}
.blog-count{font-family:var(--font-mono);font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-soft)}
.blog-cols{display:inline-flex;align-items:center;gap:4px;background:var(--cream-deep);border:1px solid var(--line);border-radius:999px;padding:4px 4px 4px 12px}
.blog-cols-lbl{font-family:var(--font-mono);font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-soft);margin-right:4px}
.blog-cols button{width:32px;height:28px;border:0;background:none;border-radius:999px;font-family:var(--font-mono);font-size:12px;color:var(--ink-soft);cursor:pointer;transition:background .15s,color .15s,box-shadow .15s}
.blog-cols button:hover{color:var(--ink)}
.blog-cols button.on{background:var(--paper);color:var(--ink);box-shadow:var(--clay-shadow-sm)}
.blog-grid[data-cols="2"]{grid-template-columns:repeat(2,1fr)}
.blog-grid[data-cols="4"]{grid-template-columns:repeat(4,1fr)}
@media(max-width:900px){.blog-grid[data-cols]{grid-template-columns:repeat(2,1fr)!important}}
@media(max-width:540px){.blog-grid[data-cols]{grid-template-columns:1fr!important}}

/* ==== Blog redesign · Section 1: archive hero ==== */
.blog-hero{position:relative;overflow:hidden}
.blog-hero .blog-hero-inner{max-width:820px;text-align:center;padding-top:72px;padding-bottom:10px}
.blog-hero .eyebrow{font-family:var(--font-mono);font-size:12px;letter-spacing:.18em;text-transform:uppercase;color:var(--cyan-deep)}
.blog-hero h1{font-family:var(--font-display);font-weight:700;font-size:clamp(44px,6.4vw,76px);line-height:1;letter-spacing:-.025em;margin:16px 0 0;color:var(--ink)}
.blog-hero h1 .grad{background:var(--pc-gradient);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent}
.blog-hero .lede{margin:22px auto 0;max-width:54ch;font-size:19px;line-height:1.55;color:var(--ink-soft)}
.blog-hero-proof{list-style:none;display:flex;justify-content:center;flex-wrap:wrap;gap:12px;margin:32px 0 0;padding:0}
.blog-hero-proof li{display:inline-flex;align-items:center;gap:8px;font-size:14px;color:var(--ink-soft);background-color:rgba(255,255,255,0.6);background-image:var(--glass-sheen);border:1px solid var(--line);box-shadow:var(--clay-shadow-sm);border-radius:var(--radius);padding:10px 16px}
.blog-hero-proof b{font-family:var(--font-display);font-weight:700;font-size:17px;color:var(--ink)}

/* ==== Blog redesign · Section 3-7: single post ==== */
.blog-post.wrap{max-width:720px;padding-top:40px}
.blog-post .crumbs{font-size:13px;color:var(--ink-soft);margin-bottom:18px}
.blog-post .crumbs a{color:var(--ink-soft);text-decoration:none}
.blog-post .crumbs a:hover{color:var(--cyan-deep)}
.blog-post > .cat{display:inline-block;font-family:var(--font-mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--cyan-deep);background:var(--sky);border-radius:999px;padding:6px 12px}
.blog-post h1{font-family:var(--font-display);font-weight:700;font-size:clamp(32px,4.6vw,52px);line-height:1.06;letter-spacing:-.02em;margin:16px 0 0;color:var(--ink)}
.blog-post .byline{margin:18px 0 0;font-size:14px;color:var(--ink-soft)}
.blog-post .hero{width:100%;height:auto;aspect-ratio:16/9;object-fit:cover;border-radius:var(--radius);margin:28px 0 8px;box-shadow:var(--shadow-card)}
.blog-post pre,.blog-post table{display:block;max-width:100%;overflow-x:auto}
/* Embeds. Providers hand out fixed width and height attributes, which on a
   phone means a 560px video in a 350px column. Ratio comes from the box, not
   from whatever the paste happened to carry. */
.blog-post iframe{display:block;width:100%;height:auto;aspect-ratio:16/9;border:0;border-radius:var(--radius);margin:28px 0;background:var(--cream-deep);box-shadow:var(--clay-shadow-sm)}
/* Audio embeds are short and wide, not 16:9. */
.blog-post iframe[src*="spotify.com"]{aspect-ratio:auto;height:152px}
.blog-post iframe[src*="transistor.fm"]{aspect-ratio:auto;height:180px}
.blog-post .tldr{background:var(--cream-deep);border:1px solid rgba(0,161,199,.18);border-radius:16px;padding:20px 22px;margin:30px 0}
.blog-post .tldr strong{display:block;font-family:var(--font-mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--cyan-deep);margin-bottom:8px}
.blog-post .tldr p{margin:0;font-size:16.5px;line-height:1.6;color:var(--ink)}
.blog-post .post-body{margin-top:34px;font-size:18px;line-height:1.75;color:#2a2d30}
.blog-post .post-body > *:first-child{margin-top:0}
.blog-post .post-body p{margin:0 0 1.25em}
.blog-post .post-body h2{font-family:var(--font-display);font-weight:700;font-size:29px;line-height:1.15;letter-spacing:-.01em;color:var(--ink);margin:2em 0 .5em}
.blog-post .post-body h3{font-family:var(--font-display);font-weight:600;font-size:22px;line-height:1.25;color:var(--ink);margin:1.6em 0 .4em}
.blog-post .post-body ul,.blog-post .post-body ol{margin:0 0 1.25em;padding-left:1.3em}
.blog-post .post-body li{margin:.4em 0}
.blog-post .post-body a{color:var(--cyan-deep);text-decoration:underline;text-underline-offset:2px}
.blog-post .post-body img{width:100%;border-radius:16px;margin:1.7em 0;box-shadow:var(--shadow-card)}
.blog-post .post-body blockquote{margin:1.7em 0;padding:4px 0 4px 22px;border-left:3px solid var(--cyan);font-family:var(--font-display);font-weight:500;font-size:22px;line-height:1.4;color:var(--ink)}
.blog-post .post-body strong{font-weight:600;color:var(--ink)}
.blog-post .post-body figure{margin:1.7em 0}
.blog-post .post-body figcaption{font-size:13px;color:var(--ink-soft);text-align:center;margin-top:8px}
.blog-post .faq{margin-top:56px;border-top:1px solid var(--line);padding-top:40px}
.blog-post .faq h2{font-family:var(--font-display);font-weight:700;font-size:26px;margin:0 0 14px;color:var(--ink)}
.blog-post .faq details{border:1px solid var(--line);border-radius:14px;margin:10px 0;background:var(--paper)}
.blog-post .faq summary{list-style:none;cursor:pointer;padding:16px 18px;font-weight:600;font-size:16.5px;color:var(--ink);display:flex;justify-content:space-between;align-items:center;gap:16px}
.blog-post .faq summary::-webkit-details-marker{display:none}
.blog-post .faq summary::after{content:"+";font-size:22px;color:var(--cyan-deep);font-weight:400;line-height:1}
.blog-post .faq details[open] summary::after{content:"\2013"}
.blog-post .faq details p{margin:0;padding:0 18px 18px;color:var(--ink-soft);line-height:1.6}
.blog-post .tags{margin-top:40px;display:flex;flex-wrap:wrap;gap:8px}
.blog-post .tags span{background:var(--cream);border:1px solid var(--line);border-radius:999px;padding:6px 14px;font-size:13px;color:var(--ink-soft)}
.blog-post .author-box{margin-top:36px;background:var(--cream);border-radius:18px;padding:22px 24px}
.blog-post .author-box strong{display:block;font-size:16px;color:var(--ink);margin-bottom:4px}
.blog-post .author-box p{margin:0;font-size:14.5px;line-height:1.6;color:var(--ink-soft)}
.blog-post .related{margin-top:64px;border-top:1px solid var(--line);padding-top:40px}
.blog-post .related h2{font-family:var(--font-display);font-weight:700;font-size:24px;margin:0 0 20px;color:var(--ink)}
.blog-post .cta{margin-top:56px;background:var(--pc-gradient-soft);border-radius:var(--radius);padding:44px 40px;text-align:center;box-shadow:var(--shadow-brand)}
.blog-post .cta h2{font-family:var(--font-display);font-weight:700;font-size:clamp(26px,3.4vw,34px);line-height:1.1;color:#fff;margin:0}
.blog-post .cta p{margin:16px 0 0;color:rgba(255,255,255,.94);font-size:16px;display:flex;gap:16px;align-items:center;justify-content:center;flex-wrap:wrap}
.blog-post .cta .btn{background:var(--orange);color:#fff}
@media(max-width:640px){ .blog-post .cta{padding:32px 22px} }

/* ==== Blog redesign · Section 2: cards + CTA polish ==== */
.blog-grid{grid-template-columns:repeat(auto-fit,minmax(288px,1fr));gap:26px}
.blog-card{display:flex;flex-direction:column;background:var(--paper);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;box-shadow:var(--shadow-card);transition:transform .22s cubic-bezier(.2,.7,.2,1),box-shadow .22s ease}
.blog-card:hover{transform:translateY(-5px);box-shadow:var(--shadow-brand)}
.blog-card .thumb{aspect-ratio:16/11;display:grid;place-items:center;padding:18px;background:linear-gradient(150deg,#E6F6FA 0%,#F4FBF9 55%,#DEFFF2 100%)}
.blog-card .thumb img{width:100%;height:100%;object-fit:contain;filter:drop-shadow(0 18px 24px rgba(10,60,80,.18))}
.blog-grid > .blog-card:nth-child(3n+2) .thumb{background:linear-gradient(150deg,#EAFBF3 0%,#F6FFFB 55%,#DFF4FF 100%)}
.blog-grid > .blog-card:nth-child(3n+3) .thumb{background:linear-gradient(150deg,#FFF1E9 0%,#FFF8F3 55%,#FFE7DB 100%)}
.blog-card .body{display:flex;flex-direction:column;gap:9px;padding:20px 22px 22px;flex:1}
.blog-card .body .cat{margin:0;font-family:var(--font-mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--cyan-deep)}
.blog-card .body h2{font-family:var(--font-display);font-weight:700;font-size:20px;line-height:1.22;letter-spacing:-.01em;margin:0;color:var(--ink);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.blog-card .body p{margin:0;color:var(--ink-soft);font-size:14.5px;line-height:1.55;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.blog-card .body .meta{margin-top:auto;padding-top:13px;border-top:1px solid var(--line);font-family:var(--font-mono);font-size:12px;letter-spacing:.03em;color:var(--ink-soft)}
.blog-post .hero{object-fit:contain;background:linear-gradient(150deg,#E6F6FA 0%,#F4FBF9 55%,#DEFFF2 100%);padding:14px}
.blog-post .related .blog-card .thumb{aspect-ratio:16/10}
.blog-post .cta{position:relative;overflow:hidden;margin-top:64px;background:var(--pc-gradient);border-radius:var(--radius);padding:52px 40px;text-align:center;box-shadow:0 34px 64px -26px rgba(0,161,199,.55)}
.blog-post .cta::before{content:"";position:absolute;inset:0;background:radial-gradient(130% 120% at 50% -20%,rgba(255,255,255,.4),transparent 55%);pointer-events:none}
.blog-post .cta > *{position:relative}
.blog-post .cta .eyebrow{font-family:var(--font-mono);font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:rgba(255,255,255,.82)}
.blog-post .cta h2{font-family:var(--font-display);font-weight:700;font-size:clamp(28px,3.6vw,38px);line-height:1.06;color:#fff;margin:12px 0 0}
.blog-post .cta p{margin:14px auto 0;max-width:44ch;color:rgba(255,255,255,.92);font-size:16px;line-height:1.5;display:block}
.blog-post .cta .btn{display:inline-flex;align-items:center;gap:8px;margin-top:26px;background:var(--orange);color:#fff;padding:14px 26px;box-shadow:0 14px 26px -10px rgba(255,104,38,.7)}
.blog-post .cta .btn:hover{background:var(--orange-deep)}

/* ==== Blog · image placeholders (no generated art) ==== */
.img-ph{display:grid;place-items:center;gap:10px;text-align:center;color:var(--ink-soft);border:1.5px dashed var(--border-strong);border-radius:var(--radius);background:linear-gradient(150deg,#E6F6FA 0%,#F4FBF9 55%,#DEFFF2 100%)}
.img-ph--sq{aspect-ratio:1/1;width:100%;padding:26px}
.img-ph .cap{font-family:var(--font-mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;max-width:72%;line-height:1.5}
.blog-card .thumb-ph{display:grid;place-items:center;width:100%;height:100%;color:var(--ink-soft);border:1.5px dashed var(--border-strong);border-radius:12px;background:rgba(255,255,255,.28)}
.blog-post .hero.hero-ph{aspect-ratio:16/9;display:grid;place-items:center;gap:10px;text-align:center;color:var(--ink-soft);border:1.5px dashed var(--border-strong);box-shadow:none;padding:20px}
.blog-post .hero.hero-ph .cap{font-family:var(--font-mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;line-height:1.5}
@media(max-width:860px){
  .blog-hero-inner{padding-top:44px;padding-bottom:8px}
}

/* ==== AEO tables + related cards (industry / location landing pages) ==== */
.aeo-table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--clay-shadow-sm); background: var(--paper); -webkit-overflow-scrolling: touch; }
.aeo-table { width: 100%; border-collapse: collapse; font-size: 15px; }
.aeo-table th, .aeo-table td { padding: 14px 18px; text-align: left; border-bottom: 1px solid var(--line); white-space: nowrap; }
.aeo-table thead th { font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); background: var(--cream); }
.aeo-table tbody tr:last-child td { border-bottom: 0; }
.aeo-table td { color: var(--ink-soft); }
.aeo-table .aeo-th { font-weight: 600; color: var(--ink); white-space: normal; }
.cmp-table th, .cmp-table td { text-align: center; }
.cmp-table .aeo-th { text-align: left; }
.cmp-table .cmp-col-us { background: rgba(0,161,199,0.06); }
.cmp-table thead .cmp-col-us { color: var(--cyan-deep); font-weight: 700; }
.cmp-ic { display: inline-flex; align-items: center; justify-content: center; line-height: 0; vertical-align: middle; }
.cmp-ic svg { display: block; }
.cmp-y { color: #0F9D63; }
.cmp-n { color: #9AA3A8; }
.cmp-m { color: var(--orange-deep); }
.cmp-na { color: var(--ink-soft); font-size: 12px; font-family: var(--font-mono); }
/* The column count was hardcoded to 3 while these sections carry anywhere from
   1 to 4 quotes, so four left a lone card stranded under a row of three, two
   left half the row empty, and one stretched across the full width. The count
   is published as data-n and the track set to match: four balances as 2x2, and
   a single quote is held to a readable measure instead of running the width of
   the page. align-items:stretch so the cards in a row share one height rather
   than stepping down like a bar chart. */
.ind-tgrid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 22px; align-items: stretch; justify-content: center; }
.ind-tgrid[data-n="1"] { grid-template-columns: minmax(0, 620px); }
.ind-tgrid[data-n="2"] { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 880px; margin-inline: auto; }
.ind-tgrid[data-n="4"] { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 940px; margin-inline: auto; }
.ind-tgrid .t-card { display: flex; flex-direction: column; min-height: 0; height: 100%; }
.ind-tgrid .t-card .t-quote { margin: 0; }
.ind-tgrid .t-card .t-author { margin-top: 18px; padding-top: 16px; }

/* ---------- Testimonial wall ----------
   Quotes pinned at slightly different heights and angles over a faint sheet of
   graph paper, the way a board of real notes actually sits. Replaces the
   carousel on the industry pages: with only one to four quotes per sector, a
   scroller mostly served up a card sliced down the middle at the track edge,
   and nothing here needs paging through. */
.ind-wall-sec { position: relative; }
.ind-wall-sec::after {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image:
    linear-gradient(to right, rgba(0, 161, 199, 0.14) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(0, 161, 199, 0.14) 1px, transparent 1px);
  background-size: 38px 38px;
  /* Fade it out well before the section edges so it reads as a field the cards
     sit on, not as a boxed-in panel. */
  -webkit-mask-image: radial-gradient(94% 74% at 50% 50%, #000 28%, transparent 76%);
  mask-image: radial-gradient(94% 74% at 50% 50%, #000 28%, transparent 76%);
}
.ind-wall {
  position: relative; z-index: 1;
  display: flex; flex-wrap: wrap; justify-content: center; align-items: flex-start;
  gap: 30px 20px; padding: 22px 0 30px;
}
.ind-wall .t-card {
  flex: 0 1 338px; min-height: 0; height: auto;
  transition: transform .32s cubic-bezier(.2,.7,.3,1), box-shadow .32s ease;
}
.ind-wall .t-card .t-quote { margin: 0; }
/* Not `margin-top: auto`. These cards size to their own content rather than
   stretching to a shared height, so auto resolves to zero and the rule crowded
   the last line of the quote. */
.ind-wall .t-card .t-author { margin-top: 22px; padding-top: 18px; }
/* Cards tuck under each other slightly, so the wall reads as one pinned group
   rather than a row of separate tiles. */
.ind-wall .t-card:nth-child(even) { margin-inline: -18px; }
.ind-wall .t-card:nth-child(1) { transform: rotate(-1.5deg) translateY(18px); z-index: 1; }
.ind-wall .t-card:nth-child(2) { transform: rotate(1.2deg)  translateY(-10px); z-index: 3; }
.ind-wall .t-card:nth-child(3) { transform: rotate(-1deg)   translateY(24px); z-index: 2; }
.ind-wall .t-card:nth-child(4) { transform: rotate(1.7deg)  translateY(-4px); z-index: 4; }
.ind-wall .t-card:nth-child(5) { transform: rotate(-1.3deg) translateY(14px); z-index: 2; }
/* After the nth-child rules: same specificity, so source order decides. */
.ind-wall .t-card:hover, .ind-wall .t-card:focus-within {
  transform: rotate(0deg) translateY(-8px); z-index: 6;
  box-shadow: var(--clay-shadow), 0 30px 52px -22px rgba(0, 90, 120, .38);
}
/* A single quote has nothing to sit askew against. */
.ind-wall[data-n="1"] .t-card { flex-basis: 560px; }
.ind-wall[data-n="1"] .t-card:nth-child(1) { transform: none; }
/* Four across needs more room than the wrap gives, so the fourth card dropped
   to its own row and sat there alone. Cluster them two by two instead. */
.ind-wall[data-n="4"] { max-width: 740px; margin-inline: auto; }
/* Five or more. Flex wrapping leaves whatever does not divide by three stranded
   on a short final row: Chennai's seven quotes came out 3, 3, then one. Columns
   balance the heights themselves and never orphan a card. */
.ind-wall--many { display: block; columns: 3; column-gap: 22px; padding-bottom: 8px; }
.ind-wall--many .t-card {
  width: 100%; break-inside: avoid; -webkit-column-break-inside: avoid;
  margin: 0 0 22px; flex: none;
}
.ind-wall--many .t-card:nth-child(even) { margin-inline: 0; }
@media (max-width: 1040px) { .ind-wall--many { columns: 2; } }
@media (max-width: 860px)  { .ind-wall--many { columns: 1; } }
@media (max-width: 860px) {
  /* Straighten up and stack. Rotated cards widen their own bounding box, which
     is exactly what pushes a phone viewport sideways. */
  .ind-wall { gap: 16px; padding: 6px 0 8px; }
  .ind-wall .t-card { flex: 1 1 100%; }
  .ind-wall .t-card:nth-child(n) { transform: none; margin-inline: 0; }
  .ind-wall-sec::after { background-size: 30px 30px; }
}
@media (prefers-reduced-motion: reduce) {
  .ind-wall .t-card { transition: none; }
  .ind-wall .t-card:hover, .ind-wall .t-card:focus-within { transform: none; }
}
/* Flex, not grid. The industry pages carry 4 related cards and every service
   page carries 3, and a fixed 4-column grid left an empty fourth column that
   made the row look truncated. auto-fit would collapse that empty track, but
   only reserves whole tracks, so the count still has to divide evenly. Flex
   with flex-grow always fills the row for any number of cards. */
.ind-related { display: flex; flex-wrap: wrap; gap: 18px; align-items: stretch; }
.ind-related-card {
  flex: 1 1 230px; min-width: 0;
  text-decoration: none; color: inherit;
  transition: transform .18s var(--ease-out, ease), box-shadow .22s ease;
}
.ind-related-card:hover { transform: translateY(-4px); box-shadow: var(--clay-shadow-hover); }
@media (max-width: 560px) { .ind-related-card { flex-basis: 100%; } }

/* ==== Local NAP + map (location landing pages) ==== */
.loc-nap-grid { display: grid; grid-template-columns: 0.9fr 1.1fr; gap: 48px; align-items: center; }
.loc-nap { display: grid; gap: 16px; margin: 24px 0 0; }
.loc-nap > div { display: flex; flex-direction: column; gap: 3px; }
.loc-nap dt { font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); }
.loc-nap dd { margin: 0; font-size: 16px; color: var(--ink); font-weight: 500; }
.loc-nap dd a { color: var(--cyan-deep); font-weight: 600; }
.loc-map { border-radius: var(--radius); overflow: hidden; border: 1px solid var(--line); box-shadow: var(--clay-shadow); aspect-ratio: 4/3; background: var(--cream-deep); }
.loc-map iframe { width: 100%; height: 100%; border: 0; display: block; }
@media (max-width: 820px) { .loc-nap-grid { grid-template-columns: 1fr; gap: 28px; } .loc-map { aspect-ratio: 16/10; } }

/* ==== Hero proof strip (glass, divided cells) ==== */
.hero-proof { display:flex; margin-top:40px; max-width:560px; background-color:rgba(255,255,255,0.62); background-image:var(--glass-sheen); border:1px solid var(--line); border-radius:var(--radius); box-shadow:var(--clay-shadow-sm); overflow:hidden; }
.hero-proof-cell { flex:1; padding:20px 22px; }
.hero-proof-cell + .hero-proof-cell { border-left:1px solid var(--line); }
.hero-proof-cell .stat-num { font-size:clamp(34px,4vw,48px); line-height:1; }
.hero-proof-cell .mono { margin-top:8px; color:var(--ink-soft); font-size:11px; }
@media (max-width:560px){ .hero-proof-cell { padding:15px 13px; } .hero-proof-cell .stat-num { font-size:28px; } .hero-proof-cell .mono { font-size:11px; } }

.inc-tick { display:inline-flex; align-items:center; justify-content:center; line-height:0; flex-shrink:0; color: var(--cyan-deep); }
.inc-tick svg { display:block; }

/* ==== Testimonial depth slider ==== */
/* The stacked slides fan out well past the viewport (14 cards reaching ~1356px
   on a 345px screen), which gave the whole page a horizontal scrollbar on
   mobile. Clip horizontally only: `clip` rather than `hidden` so this never
   becomes a scroll container, and overflow-y stays visible so the active card's
   shadow is not sliced off. */
.ts { position: relative; margin-top: 40px; overflow-x: clip; overflow-y: visible; }
.ts-stage { position: relative; height: 340px; perspective: 1400px; transform-style: preserve-3d; cursor: grab; }
.ts-stage:active { cursor: grabbing; }
.ts-slide {
  position: absolute; top: 50%; left: 50%; width: min(430px, 82vw);
  margin: 0; padding: 30px 32px; box-sizing: border-box;
  transform-origin: 50% 50%; backface-visibility: hidden;
  transition: transform .62s cubic-bezier(.22,.68,.28,1), opacity .45s ease, box-shadow .45s ease, filter .45s ease;
  will-change: transform, opacity;
  /* The card surface is normally 72% translucent glass. Here the neighbours
     overlap the live quote by 165px a side, so that translucency printed two
     other people's testimonials straight through the one you are reading.
     This stack has to be opaque; the sheen above still carries the glass look.

     Each tint needs its own opaque value rather than a blanket white. Painting
     every card white flattened the blue variant's background while leaving its
     white type, so three testimonials rendered white on white and read as empty
     cards. Values below are the translucent originals composited over white. */
  background-color: #fff;
}
.ts-slide.card--blue, .ts-slide.card--teal { background-color: var(--cyan-deep); }
.ts-slide.card--ink  { background-color: #0A7E9C; }
.ts-slide.card--lime { background-color: #c4f6e4; }
.ts-slide.card--pink { background-color: #ffe1d0; }
.ts-slide.card--sky  { background-color: #eaf7fb; }
/* Neighbours are depth, not reading material. Throwing them out of focus lets
   them stay present as cards without competing for the eye, which is what
   raising their opacity to make them "read as cards" accidentally caused. */
.ts-slide:not(.is-active) { filter: blur(2.5px); }
.ts-slide.is-active { box-shadow: var(--clay-shadow); filter: none; }
.ts-slide .t-quote { font-size: 19px; line-height: 1.5; }
.ts-controls { display: flex; align-items: center; justify-content: center; gap: 18px; margin-top: 26px; }
.ts-arrow {
  width: 46px; height: 46px; border-radius: 50%; flex-shrink: 0;
  border: 1px solid var(--line); background: rgba(255,255,255,0.75);
  box-shadow: var(--clay-shadow-sm); color: var(--ink); cursor: pointer;
  display: grid; place-items: center; transition: transform .18s ease, background .18s ease, color .18s ease;
}
.ts-arrow:hover { transform: translateY(-2px); background: var(--cyan-deep); color: #fff; border-color: var(--cyan-deep); }
.ts-dots { display: flex; align-items: center; gap: 9px; }
.ts-dot {
  width: 9px; height: 9px; padding: 0; border-radius: 50%; cursor: pointer;
  border: 0; background: var(--border-strong); opacity: .5;
  transition: width .32s cubic-bezier(.22,.68,.28,1), opacity .25s ease, background .25s ease;
}
.ts-dot.is-on { width: 30px; border-radius: 999px; opacity: 1; background: var(--pc-gradient); }
@media (max-width: 720px) {
  .ts-stage { height: 380px; }
  .ts-slide { padding: 24px 22px; }
}
/* With 14 reviews the dot row plus both arrows measures ~371px, so on a 345px
   screen the arrows were pushed past the edge. Shrink the dots rather than drop
   the arrows: the arrows are the control people actually reach for. */
@media (max-width: 560px) {
  .ts-controls { gap: 12px; }
  .ts-dots { gap: 4px; }
  .ts-dot { width: 7px; height: 7px; }
  .ts-dot.is-on { width: 22px; }
}
@media (prefers-reduced-motion: reduce) {
  .ts-slide { transition: opacity .2s linear; }
}

/* ==== Footer layout (5 columns, collapses gracefully) ==== */
.foot-grid{display:grid;grid-template-columns:1.7fr 1fr 1.2fr 1.35fr 1.2fr;gap:44px 36px;padding-bottom:52px;border-bottom:1px solid var(--line);align-items:start}
.foot-brand .foot-blurb{margin-top:16px;max-width:300px;font-size:14px;line-height:1.6;color:var(--ink-soft)}
.foot-social{display:flex;gap:10px;margin-top:22px}
.foot-social .tag{background:transparent;color:var(--ink);border-color:var(--line)}
.foot-grid .col h5{margin:0 0 14px}
.foot-grid .col h5 + ul + h5{margin-top:26px}
.foot-grid .col ul{margin:0;padding:0;list-style:none}
.foot-grid .col li{margin:0 0 9px}
.foot-grid .col a{font-size:14.5px;line-height:1.45}
.foot-addr{margin-top:22px;font-style:normal;font-size:13px;line-height:1.6;color:var(--ink-soft);opacity:.85;max-width:230px}
.foot-base{display:flex;justify-content:space-between;align-items:center;gap:20px;flex-wrap:wrap;padding:26px 0 0;font-size:13px;opacity:.6}
@media(max-width:1180px){
  .foot-grid{grid-template-columns:1.6fr 1fr 1.2fr 1.3fr;}
  .foot-contact{grid-column:2 / -1;display:grid;grid-template-columns:repeat(3,1fr);gap:0 32px;align-items:start}
  .foot-contact h5{margin-top:0 !important}
  .foot-contact .foot-addr{grid-column:1 / -1}
}
@media(max-width:860px){
  .foot-grid{grid-template-columns:1fr 1fr;gap:36px 28px}
  .foot-brand{grid-column:1 / -1}
  .foot-contact{grid-column:1 / -1;grid-template-columns:1fr 1fr}
}
@media(max-width:520px){
  .foot-grid{grid-template-columns:1fr;gap:30px}
  .foot-contact{grid-template-columns:1fr}
  .foot-base{justify-content:flex-start;gap:10px}
}

/* ==========================================================================
   Mobile refinement layer
   Measured at 390px before this block: 11 distinct body font sizes between
   11px and 27px, 22 of 47 paragraphs below 15px, 52 tap targets under 44px,
   and section padding of only 44-56px so sections ran into each other.
   Desktop is deliberately untouched.
   ========================================================================== */
@media (max-width: 600px) {

  /* --- Type scale. Five steps instead of eleven, body floored at 16px.
       !important is deliberate and scoped to this breakpoint: the pages carry
       inline font-size on some paragraphs, and inline styles beat any selector.
       Without it the scale silently does nothing. --- */
  p, li, .t-quote, .svc-pitch { font-size: 16px !important; line-height: 1.6; }
  p.sub, .foot-blurb, .cc-blurb { font-size: 15.5px !important; line-height: 1.58; }
  .mono, p.mono, span.mono, div.mono,
  .tl-eyebrow, .cc-eyebrow, .cc-ind, .svc-chip, .tag, .cc-chip, .sticker {
    font-size: 12px !important; letter-spacing: .08em;
  }
  .t-role, .cc-label { font-size: 13px !important; }
  h1 { font-size: clamp(32px, 8.6vw, 40px) !important; line-height: 1.12; }
  h2 { font-size: clamp(25px, 6.8vw, 30px) !important; line-height: 1.18; }
  h3, h4 { font-size: 19px !important; line-height: 1.28; }
  /* the big gradient stat numbers stay expressive, just reined in */
  .stat-num, .cc-num { font-size: clamp(30px, 9vw, 40px) !important; }

  /* --- Rhythm. Sections need to read as separate chapters, not one scroll. --- */
  .section { padding-top: 64px; padding-bottom: 64px; }
  .section-sm { padding-top: 44px; padding-bottom: 44px; }
  .section > .wrap > * + * { margin-top: 18px; }

  /* --- Tap targets. Everything clickable clears 44px. --- */
  .foot-grid .col ul li a,
  .foot-contact ul li a {
    display: block; min-height: 44px; line-height: 44px;
  }
  a.tag, .foot-social a {
    min-height: 44px; min-width: 44px;
    display: inline-flex; align-items: center; justify-content: center;
  }
  .nav-links a { min-height: 44px; display: flex; align-items: center; }
  /* the last three: Privacy / Legal / Team portal in the footer base */
  .foot-base a { display: inline-flex; align-items: center; min-height: 44px; padding: 0 2px; }
  .foot-base span { display: flex; flex-wrap: wrap; align-items: center; gap: 0 6px; }

  /* A 7px dot is not a control. Arrows drive the slider on a phone and the
     position is shown as a count instead. */
  .ts-dots { display: none; }
  .ts-count {
    font-family: var(--font-mono); font-size: 13px; letter-spacing: .06em;
    color: var(--ink-soft); min-width: 62px; text-align: center;
  }
  .ts-count b { color: var(--ink); font-weight: 600; }
  .ts-controls { gap: 14px; }
}

/* The count only replaces the dots on small screens. */
@media (min-width: 601px) { .ts-count { display: none; } }

/* ==========================================================================
   Motion layer
   transform + opacity only, so every one of these is GPU-composited and costs
   no layout or paint. will-change is set on entry and dropped after, so we are
   not holding a compositor layer for the life of the page.
   ========================================================================== */
/* Gated on .js, set inline in <head> before first paint. Without it the
   reveal styles would hide this content permanently for anyone whose JS never
   arrives, and for any crawler that does not run scripts. */
/* Reveal without ever hiding.
   The old approach set opacity:0 here and waited for JS to add .is-in. Every
   way that trigger could fail, and there turned out to be several, left whole
   sections permanently invisible. Now the resting state is simply visible, and
   .is-in plays a keyframe that starts from hidden and finishes at the resting
   state. No script, a failed trigger, a throttled tab: the content still reads.
   The animation only ever runs when something explicitly asks for it. */
/* At the top level, not under .js. A @keyframes block cannot be nested inside a
   selector: ".js @keyframes pc-rise" is invalid, so the browser threw both of
   these away and every "animation: pc-rise" on the site referred to a keyframe
   that did not exist. Nothing animated, elements simply appeared. The .js gate
   belongs on the rules that USE the animation, which is where it already is. */
@keyframes pc-rise { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
@keyframes pc-rise-sm { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }

/* The rule that actually drives all of it. This had gone missing, and without
   it the direction variants further down set an animation-name against no
   duration, which resolves to 0s: the whole reveal system was inert and every
   section simply appeared. Declared here, ahead of those variants, so they only
   have to swap the keyframe and inherit the timing from this shorthand. */
.js [data-anim].is-in { animation: pc-rise .62s cubic-bezier(.2,.7,.3,1) both; }
.js .is-in [data-anim-child] { animation: pc-rise-sm .5s cubic-bezier(.2,.7,.3,1) both; }

/* Nothing moves, and nothing is left hidden, when the visitor asks for that. */
@media (prefers-reduced-motion: reduce) {
  [data-anim], [data-anim].is-in, [data-anim-child] {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
}

/* ---------- Editorial image blocks, to break up the long text runs ---------- */
.ed-split {
  display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: center;
}
.ed-split.is-flipped .ed-media { order: 2; }
.ed-media {
  border-radius: var(--radius); overflow: hidden;
  border: 1px solid var(--line); box-shadow: var(--clay-shadow);
  background: var(--cream-deep);
}
.ed-media image-slot { display: block; width: 100%; }
.ed-cap {
  margin-top: 12px; font-family: var(--font-mono); font-size: 11px;
  letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft);
}
.ed-band { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
@media (max-width: 880px) {
  .ed-split { grid-template-columns: 1fr; gap: 28px; }
  .ed-split.is-flipped .ed-media { order: 0; }
  .ed-band { grid-template-columns: 1fr; gap: 18px; }
}

/* Office hours sit under the address in the footer and on contact. */
.foot-hours { margin-top: 8px; font-family: var(--font-mono); font-size: 11px;
  letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); opacity: .8; }

/* ---------- Why-us section head (heading beside the team photo) ---------- */
/* Was an editorial split carrying one sentence against a 3:2 photo, which left
   most of the block empty and pushed the section's own heading below it. */
.why-head {
  display: grid; grid-template-columns: 1fr 0.85fr; gap: 52px;
  align-items: center; margin-bottom: 56px;
}
.why-head-tx { max-width: 560px; }
.why-lead { margin-top: 20px; font-size: 18px; line-height: 1.6; color: var(--ink-soft); }
.why-media { margin: 0; }
.why-media figcaption {
  margin-top: 12px; font-family: var(--font-mono); font-size: 11px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft); opacity: .75;
}
@media (max-width: 900px) {
  .why-head { grid-template-columns: 1fr; gap: 30px; margin-bottom: 40px; }
  .why-head-tx { max-width: none; }
  /* Lead with the words on a phone; the photo is support, not the headline. */
  .why-media { order: 2; }
}

/* ---------- Industry & location two-column blocks ---------- */
/* These were inline `grid-template-columns: repeat(2, 1fr)` in the templates,
   which no media query can override, so at 390px each LEAP card computed to
   411px and pushed the page 43px wider than the viewport. As classes they can
   collapse properly on a phone. */
.ind-2col { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 22px; }
.ind-facts > *:last-child:nth-child(odd) { grid-column: 1 / -1; border-right: 0 !important; }
.ind-facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0; margin: 0;
  border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; background: var(--paper); }
@media (max-width: 760px) {
  .ind-2col { grid-template-columns: 1fr; gap: 18px; }
  .ind-facts { grid-template-columns: 1fr; }
}

/* The LEAP card was inline `grid-template-columns: auto 1fr`. A bare 1fr refuses
   to shrink below its content's min-content width, so on a phone the card grew
   to 411px inside a 346px track and pushed the page 43px wide. minmax(0,1fr)
   lets the text column actually shrink, and inline styles can't be overridden
   by a media query, so the layout lives here instead. */
.leap-card { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 22px; align-items: start; }
@media (max-width: 760px) { .leap-card { gap: 16px; } }
@media (max-width: 420px) { .leap-card { grid-template-columns: 1fr; gap: 10px; } }

/* "Google Business Profile Management" carried an inline white-space:nowrap, so
   it could not shrink and set a min-content floor that pushed the whole LEAP
   card 24px past its grid track on a phone. It stays on one line where there is
   room and wraps where there isn't. */
/* Pinning this to nowrap only moved the problem to the next breakpoint: at
   768px the two-column LEAP grid still gave it 360px and "Google Business
   Profile Management" needs 299px plus card padding, so the page went 15px
   wide. Let it wrap whenever it has to; with room it stays on one line anyway. */
.leap-tag { white-space: normal; }

/* ---------- Testimonial carousel (industry + location pages) ---------- */
/* Seven quotes in a rigid three-column grid left a ragged last row, and it was
   unusable on a phone. Above two reviews they become a swipeable track: three
   across on desktop, one at a time on a phone, driven by scroll-snap so touch
   works natively and the arrows are only an affordance on top. */
/* Declared on the wrapper so the track and the arrows both inherit it. */
.tcar { position: relative; --tcar-gutter: 26px; }
.tcar-track {
  display: flex; gap: 22px; overflow-x: auto; align-items: stretch;
  /* `mandatory` fought the programmatic scrollTo: the snap pulled the track back
     to its current point and the arrows moved it about a pixel. `proximity`
     keeps the nice resting position for a touch swipe without overriding a
     deliberate jump to a card. */
  scroll-snap-type: x proximity; scroll-padding-left: var(--tcar-gutter, 26px);
  scroll-behavior: smooth; -webkit-overflow-scrolling: touch;
  /* The track is the scroll container, so it also clips. With only 2px of side
     padding the clay shadow got sliced off at both ends. Give the shadow a
     gutter and pull the box back out by the same amount, so the first card
     still lines up with the heading above it. 26px of bleed sits inside the
     wrap's own 40px padding, so nothing reaches the viewport edge. */
  /* The bleed has to stay under .wrap's own side padding, which drops from 40px
     to 22px at 880px, or the track pushes the page sideways. */
  padding: 16px var(--tcar-gutter) 30px;
  margin-inline: calc(var(--tcar-gutter) * -1); scrollbar-width: none;
  /* The old 40px fade ran across the cards themselves, which read as a card cut
     in half. Keep the fade inside the gutter instead. */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 14px, #000 calc(100% - 14px), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 14px, #000 calc(100% - 14px), transparent 100%);
}
.tcar.is-static .tcar-track { -webkit-mask-image: none; mask-image: none; justify-content: center; }
.tcar-track::-webkit-scrollbar { display: none; }
.tcar-track > * {
  flex: 0 0 calc((100% - 44px) / 3); min-width: 0; scroll-snap-align: start;
  display: flex; flex-direction: column;
}
.tcar-track .t-card .t-quote { margin: 0; }
.tcar-track .t-card .t-author { margin-top: auto; padding-top: 18px; }
.tcar-arrow {
  position: absolute; top: calc(50% - 12px); transform: translateY(-50%); z-index: 4;
  width: 46px; height: 46px; border-radius: 50%; border: 1px solid var(--line);
  background: var(--paper); box-shadow: var(--clay-shadow); color: var(--ink);
  display: grid; place-items: center; cursor: pointer;
  transition: background .18s ease, color .18s ease, opacity .18s ease;
}
.tcar-arrow svg { width: 20px; height: 20px; }
.tcar-arrow:hover { background: var(--cyan-deep); color: #fff; border-color: var(--cyan-deep); }
.tcar-arrow:disabled { opacity: 0; pointer-events: none; }
/* Sit the arrows in the track's gutter. At -14px the arrow's inner edge landed
   exactly on the card's 32px text inset, so it read as covering the copy. */
.tcar-prev { left: calc(var(--tcar-gutter, 26px) * -1 - 4px); }
.tcar-next { right: calc(var(--tcar-gutter, 26px) * -1 - 4px); }
.tcar.is-static .tcar-arrow { display: none; }
.tcar-count { display: none; text-align: center; margin: 2px 0 0;
  font-family: var(--font-mono); font-size: 12px; letter-spacing: .04em; color: var(--ink-soft); }
.tcar-count b { color: var(--ink); font-weight: 600; }
@media (max-width: 1000px) { .tcar-track > * { flex: 0 0 calc((100% - 22px) / 2); } }
/* .wrap drops to 22px of side padding here, so the bleed has to fit inside it,
   while staying wide enough that the arrow clears the card's 32px text inset. */
@media (max-width: 880px) { .tcar { --tcar-gutter: 18px; } }
@media (max-width: 700px) {
  /* One card at a time on a phone, and the arrows give way to a counter, the
     same call the homepage slider and the reels strip already make. */
  .tcar-track > * { flex: 0 0 100%; }
  .tcar-arrow { display: none; }
  .tcar-count { display: block; }
  .tcar.is-static .tcar-count { display: none; }
}
@media (prefers-reduced-motion: reduce) { .tcar-track { scroll-behavior: auto; } }

/* ---------- Services index rows ---------- */
/* Each row carried an inline `grid-template-columns: 80px 1.4fr 1fr 60px` with
   32px gaps and 32px side padding. That is 300px of fixed space before any
   content, so on a 390px phone the two flexible columns had about 90px between
   them and the row blew out to 488px, taking the page with it. Inline styles
   cannot be overridden by a media query, so the layout lives here. */
.service-row {
  display: grid; grid-template-columns: 80px minmax(0, 1.4fr) minmax(0, 1fr) 60px;
  gap: 32px; align-items: center; padding: 48px 32px;
}
@media (max-width: 900px) {
  .service-row { grid-template-columns: 56px minmax(0, 1fr); gap: 18px 20px; padding: 30px 22px; }
  /* The blurb and the arrow drop under the title rather than fighting for width. */
  .service-row > *:nth-child(3) { grid-column: 2; }
  .service-row > *:nth-child(4) { grid-column: 2; justify-self: start; }
}

/* A flex child will not shrink below its content's min-content width unless it
   is told to. "Mithun Venkata Perumal" therefore held the author block wider
   than its card and pushed the coworking page 6px past the viewport. */
.t-author > div { min-width: 0; }
.t-name, .t-role { overflow-wrap: anywhere; }

/* Three frames of the floor, under the culture cards. */
.careers-strip { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 24px; margin-top: 24px; }
@media (max-width: 780px) { .careers-strip { grid-template-columns: 1fr; gap: 16px; } }

/* ===========================================================================
   PCViz, the animated page visuals (see assets/pc-viz.js)

   Everything below draws the FINISHED state by default. Every animation is
   gated behind .js and .is-in, so a reader whose script never arrives, and any
   crawler that does not run one, still gets a complete picture.
   =========================================================================== */
.pc-viz {
  --pcv-accent: var(--cyan-deep);
  position: relative; display: flex; flex-direction: column; gap: 14px;
  padding: 20px 20px 18px; border-radius: var(--radius);
  border: 1px solid var(--line);
  background:
    radial-gradient(120% 90% at 50% -10%, rgba(0,255,170,0.13), transparent 58%),
    linear-gradient(158deg, rgba(233,255,247,0.86), rgba(230,246,250,0.86));
  box-shadow: var(--clay-shadow), var(--shadow-brand);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  overflow: hidden;
}
.pc-viz::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background-image:
    linear-gradient(to right, rgba(0,161,199,0.09) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(0,161,199,0.09) 1px, transparent 1px);
  background-size: 26px 26px;
  -webkit-mask-image: radial-gradient(110% 80% at 50% 40%, #000 30%, transparent 82%);
  mask-image: radial-gradient(110% 80% at 50% 40%, #000 30%, transparent 82%);
}
.pc-viz > * { position: relative; z-index: 1; }
.pc-viz-head { display: flex; align-items: center; gap: 10px; }
.pcv-live { display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-soft); }
.pcv-live i { width: 7px; height: 7px; border-radius: 50%; background: var(--green); }
.pcv-title { margin-left: auto; font-family: var(--font-mono); font-size: 11px;
  letter-spacing: .06em; text-transform: uppercase; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* The stage reserves its height up front so nothing shifts as the concept
   animates in. */
.pcv-stage { position: relative; min-height: 208px; display: flex;
  flex-direction: column; justify-content: center; gap: 12px; }

/* One footprint for every hero board. The concepts carry very different amounts
   of content, so heights ran from 280px to 533px and the eighteen service and
   industry pages each looked a different shape. The Meta Ads board is the
   reference. The stage takes the slack, and it already centres its own content,
   so a short concept sits in the middle of the box rather than clinging to the
   top of it. */
.svc-hero > .pc-viz,
.section[data-screen-label="hero"] > .wrap > div > .pc-viz { min-height: 520px; }
.svc-hero > .pc-viz > .pcv-stage,
.section[data-screen-label="hero"] > .wrap > div > .pc-viz > .pcv-stage { flex: 1 1 auto; }
@media (max-width: 880px) {
  .svc-hero > .pc-viz,
  .section[data-screen-label="hero"] > .wrap > div > .pc-viz { min-height: 0; }
}
.pcv-cap { margin: 0; font-size: 13px; line-height: 1.45; color: var(--ink-soft); text-align: center; }
.pcv-cap b { color: var(--ink); font-weight: 600; }

/* Sits at the foot of a board, so it has to read as a footnote to the picture
   above it rather than a second headline arriving out of nowhere. A hairline
   and real top padding do the separating; before this it simply abutted the
   caption. */
.pc-viz-metrics { display: grid; grid-template-columns: repeat(3, minmax(0,1fr));
  gap: 12px; align-items: start; margin-top: 2px; padding-top: 14px;
  border-top: 1px solid var(--line); }
/* Centred, because the rest of the board is. The node, the area pills and the
   caption all sit on the middle axis, so left-aligned figures were the one
   element pulling against it. */
.pcv-metric { min-width: 0; text-align: center; }
.pcv-metric b { display: block; font-family: var(--font-display); font-weight: 500;
  font-size: clamp(18px, 1.8vw, 22px); line-height: 1; letter-spacing: -.02em; color: var(--ink); }
/* Sentence case, not caps. These labels run to thirty characters ("average
   ROI, India track record"), and the house rule keeps ALL CAPS for the
   wordmark, mono eyebrows and short tags. Caps was also costing about a tenth
   of the width, which is what pushed two of the three onto a second line while
   the third stayed on one and left the row looking ragged. */
.pcv-metric span { display: block; margin-top: 6px; font-family: var(--font-mono);
  font-size: 10px; letter-spacing: .02em; color: var(--ink-soft); line-height: 1.5;
  text-wrap: balance; }
@media (max-width: 640px) {
  .pc-viz-metrics { gap: 10px; padding-top: 12px; }
  /* Three columns of ~92px, so the longer labels take two lines and the short
     one takes a single line, which leaves the foot of the board ragged. Giving
     every label the height of two lines squares the row off. */
  .pcv-metric span { font-size: 9px; min-height: 3em; }
}

/* ---- split-test: nine creatives, eight cut, budget follows the winner ---- */
.pcv-grid9 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 9px; }
.pcv-ad { position: relative; aspect-ratio: 1; border-radius: 10px;
  background: rgba(255,255,255,.72); border: 1px solid var(--line); overflow: hidden; }
.pcv-ad-bar { position: absolute; left: 0; bottom: 0; height: 4px;
  width: var(--w); background: var(--pcv-accent); opacity: .5; }
.pcv-ad.is-winner { border-color: var(--green);
  box-shadow: 0 0 0 2px rgba(0,255,170,.4), 0 10px 24px -10px rgba(0,161,199,.5); }
.pcv-ad.is-winner .pcv-ad-bar { width: 100%; background: var(--green); opacity: 1; }

/* ---- query: a buyer types, the buried result climbs ---- */
.pcv-search { display: flex; align-items: center; gap: 9px; padding: 10px 13px;
  background: #fff; border: 1px solid var(--line); border-radius: 999px; }
.pcv-mag { width: 13px; height: 13px; border: 2px solid var(--ink-soft);
  border-radius: 50%; position: relative; flex: none; }
.pcv-mag::after { content: ""; position: absolute; right: -4px; bottom: -4px;
  width: 6px; height: 2px; background: var(--ink-soft); transform: rotate(45deg); }
.pcv-typed { overflow: hidden; white-space: nowrap; font-size: 14px; color: var(--ink); }
.pcv-caret { width: 2px; height: 15px; background: var(--pcv-accent); flex: none; }
.pcv-sugg { display: flex; flex-direction: column; gap: 5px; }
.pcv-sugg span { font-size: 12px; color: var(--ink-soft); padding: 5px 12px;
  background: rgba(255,255,255,.66); border-radius: 8px; }
.pcv-sugg b { color: var(--ink); font-weight: 600; }
.pcv-serp { display: flex; flex-direction: column; gap: 6px; }
.pcv-serp-row { display: flex; align-items: center; gap: 9px; padding: 8px 11px;
  background: rgba(255,255,255,.66); border-radius: 9px; }
.pcv-serp-row i { font-family: var(--font-mono); font-size: 10px; font-style: normal;
  color: var(--ink-soft); min-width: 16px; }
.pcv-serp-row span { flex: 1; height: 7px; border-radius: 4px; background: rgba(27,28,30,.12); }
.pcv-serp-you { background: #fff; border: 1px solid var(--green);
  box-shadow: 0 8px 20px -10px rgba(0,161,199,.5); order: -1; }
.pcv-serp-you i { color: var(--ink); background: var(--green); border-radius: 4px;
  padding: 1px 5px; min-width: 0; }
.pcv-serp-you span { flex: none; height: auto; background: none; font-size: 13px;
  font-weight: 600; color: var(--ink); }

/* ---- rank: outside the map pack, then inside it ---- */
.pcv-map { position: relative; height: 84px; border-radius: 12px;
  background: linear-gradient(150deg, rgba(0,255,170,.12), rgba(0,161,199,.10));
  border: 1px solid var(--line); overflow: hidden; }
.pcv-pin { position: absolute; left: 50%; top: 44%; width: 14px; height: 14px;
  margin: -7px 0 0 -7px; border-radius: 50% 50% 50% 0; transform: rotate(-45deg);
  background: var(--orange); }
.pcv-ripple { position: absolute; left: 50%; top: 44%; width: 14px; height: 14px;
  margin: -7px 0 0 -7px; border-radius: 50%; border: 2px solid var(--orange); opacity: 0; }
.pcv-pack { display: flex; flex-direction: column; gap: 6px; }
.pcv-pack-row { display: flex; align-items: center; gap: 10px; padding: 8px 12px;
  background: rgba(255,255,255,.66); border-radius: 9px; font-size: 13px; color: var(--ink-soft); }
.pcv-pack-row i { font-family: var(--font-mono); font-style: normal; font-size: 11px;
  color: var(--ink-soft); min-width: 14px; }
.pcv-pack-you { background: #fff; border: 1px solid var(--green); color: var(--ink);
  font-weight: 600; order: -1; }
.pcv-pack-you i { color: var(--ink); }

/* ---- calendar: an empty month, then a planned one ---- */
.pcv-cal { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
.pcv-day { aspect-ratio: 1; border-radius: 6px; background: rgba(255,255,255,.6);
  border: 1px solid var(--line); }
.pcv-day.is-post { background: var(--pcv-accent); border-color: transparent; }

/* ---- timeline: clips, waveform, and the hook that decides everything ---- */
.pcv-track { position: relative; height: 40px; border-radius: 9px;
  background: rgba(255,255,255,.6); border: 1px solid var(--line); overflow: hidden; }
.pcv-clip { position: absolute; top: 6px; bottom: 6px; left: var(--x); width: var(--w);
  border-radius: 5px; background: var(--pcv-accent); opacity: .35; }
.pcv-hook { position: absolute; top: 0; bottom: 0; left: 0; width: 26%;
  border-right: 2px dashed var(--orange); background: rgba(255,107,53,.12); }
.pcv-playhead { position: absolute; top: 0; bottom: 0; left: 26%; width: 2px; background: var(--ink); }
.pcv-wave { display: flex; align-items: flex-end; gap: 3px; height: 54px; }
.pcv-wave span { flex: 1; height: var(--h); border-radius: 2px; background: var(--pcv-accent); opacity: .45; }

/* ---- cascade: one share, then the ring it sets off ---- */
.pcv-net { position: relative; height: 168px; }
.pcv-node { position: absolute; left: var(--x); top: var(--y); width: 9px; height: 9px;
  margin: -4.5px 0 0 -4.5px; border-radius: 50%; background: var(--pcv-accent); opacity: .55; }
.pcv-node--seed { width: 18px; height: 18px; margin: -9px 0 0 -9px;
  background: var(--green); opacity: 1; box-shadow: 0 0 0 4px rgba(0,255,170,.22); }
.pcv-wave1, .pcv-wave2 { position: absolute; left: 50%; top: 50%; border-radius: 50%;
  border: 1px solid var(--pcv-accent); opacity: 0;
  width: 120px; height: 104px; margin: -52px 0 0 -60px; }

/* ---- answer: the AI reply, with the brand inside it ---- */
.pcv-answer { display: flex; flex-direction: column; gap: 10px; padding: 16px 18px;
  background: rgba(255,255,255,.7); border: 1px solid var(--line); border-radius: 12px; }
.pcv-ai-dot { width: 20px; height: 20px; border-radius: 6px; background: var(--pc-gradient); }
.pcv-answer > span:not(.pcv-ai-dot) { height: 9px; border-radius: 5px; background: rgba(27,28,30,.13); }
.pcv-line-1 { width: 94%; } .pcv-line-2 { width: 78%; } .pcv-line-4 { width: 56%; }
.pcv-line-3 { width: 88%; background: none !important; height: auto !important;
  font-size: 14px; color: var(--ink-soft); }
.pcv-line-3 em { font-style: normal; font-weight: 700; color: var(--ink);
  background: rgba(0,255,170,.3); border-radius: 4px; padding: 1px 6px; }

/* ---- buybox: the one box on the page that takes the money ---- */
.pcv-listing { display: grid; grid-template-columns: 74px 1fr auto; gap: 14px;
  align-items: center; padding: 14px; background: rgba(255,255,255,.72);
  border: 1px solid var(--line); border-radius: 12px; }
.pcv-thumb { aspect-ratio: 1; border-radius: 9px;
  background: linear-gradient(150deg, rgba(0,255,170,.3), rgba(0,161,199,.24)); }
.pcv-listing-body { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.pcv-sponsored { align-self: flex-start; font-family: var(--font-mono); font-size: 9px;
  letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft);
  border: 1px solid var(--line); border-radius: 5px; padding: 2px 7px; }
.pcv-lline { height: 8px; border-radius: 4px; background: rgba(27,28,30,.13); }
.pcv-lline--a { width: 82%; } .pcv-lline--b { width: 58%; }
.pcv-rank { font-family: var(--font-mono); font-size: 12px; color: var(--ink); }
.pcv-rank small { color: var(--ink-soft); font-size: 10px; }
.pcv-box { font-size: 12px; font-weight: 600; color: var(--ink);
  border: 1.5px solid var(--green); border-radius: 9px; padding: 9px 12px;
  background: rgba(0,255,170,.14); white-space: nowrap; }

/* ---- slots: bays, chairs, cabins, desks, seats. Time, either sold or gone ---- */
.pcv-slots { display: grid; grid-template-columns: repeat(8, 1fr); gap: 7px; }
.pcv-slot { aspect-ratio: 1; border-radius: 6px; background: rgba(255,255,255,.6);
  border: 1px solid var(--line); }
.pcv-slot.is-booked { background: var(--pcv-accent); border-color: transparent; }

/* ---- coverage: a city, lit pin by pin ---- */
.pcv-cover { position: relative; height: 116px; border-radius: 12px; overflow: hidden;
  background: linear-gradient(150deg, rgba(0,255,170,.11), rgba(0,161,199,.10));
  border: 1px solid var(--line); }
.pcv-dot { position: absolute; left: var(--x); top: var(--y); width: 8px; height: 8px;
  margin: -4px 0 0 -4px; border-radius: 50%; background: var(--pcv-accent); }
.pcv-scan { position: absolute; inset: 0; background:
  linear-gradient(100deg, transparent 40%, rgba(255,255,255,.55) 50%, transparent 60%); opacity: 0; }
.pcv-areas { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; }
.pcv-area { font-family: var(--font-mono); font-size: 10px; letter-spacing: .04em;
  color: var(--ink-soft); background: rgba(255,255,255,.7); border: 1px solid var(--line);
  border-radius: 999px; padding: 4px 10px; }

/* ---- demand (locations): every channel converging on one market ----
   Stretches to whatever height the board gives it. The old coverage board was
   a fixed 116px strip inside a 520px hero, which is where all that empty space
   in the middle came from. */
.pcv-demand { display: flex; flex-direction: column; gap: 14px; height: 100%; }
.pcv-dm-channels { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.pcv-dm-ch { font-family: var(--font-mono); font-size: 10px; letter-spacing: .04em;
  color: var(--ink); background: rgba(255,255,255,.78); border: 1px solid var(--line);
  border-radius: 999px; padding: 6px 8px; text-align: center; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
/* The flow takes the slack, so the board fills top to bottom at any height. */
/* Takes the slack, but only so much of it. The viewBox is stretched with
   preserveAspectRatio="none", so an uncapped flex here turns the lanes into
   very long, very thin near-vertical lines with nothing happening along them. */
.pcv-dm-flow { flex: 1 1 auto; width: 100%; min-height: 84px; max-height: 168px;
  display: block; overflow: visible; }
.pcv-dm-line { stroke: var(--pcv-accent); stroke-width: 1.25; opacity: .5;
  vector-effect: non-scaling-stroke; stroke-linecap: round; }
.pcv-dm-spark { fill: var(--pcv-accent); opacity: 0; }
.pcv-dm-target { align-self: center; display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 20px; border-radius: 999px; border: 1px solid var(--line);
  background: linear-gradient(150deg, rgba(0,255,170,.16), rgba(0,161,199,.14));
  box-shadow: 0 6px 18px rgba(0,161,199,.14); }
.pcv-dm-target b { font-family: var(--font-display); font-weight: 500; font-size: 20px;
  line-height: 1; color: var(--ink); }
.pcv-dm-areas { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; }
.pcv-dm-area { font-family: var(--font-mono); font-size: 10px; letter-spacing: .04em;
  color: var(--ink-soft); background: rgba(255,255,255,.7); border: 1px solid var(--line);
  border-radius: 999px; padding: 4px 10px; }
@media (max-width: 640px) {
  /* Stays three across on purpose. The lanes below are drawn from three fixed
     columns, so reflowing the chips to two would leave the lines pointing at
     nothing. Six short labels fit three-up even at 360px. */
  .pcv-dm-ch { font-size: 9px; padding: 6px 5px; }
  .pcv-dm-flow { min-height: 64px; }
  .pcv-dm-target b { font-size: 17px; }
  /* Twelve neighbourhood pills is a wall of text on a phone. */
  .pcv-dm-area:nth-child(n+6) { display: none; }
}

/* ---- coating (detailers): the bay board ---- */
.pcv-bays { display: grid; grid-template-columns: repeat(4, 1fr); gap: 9px; }
.pcv-bay { display: flex; flex-direction: column; gap: 6px; }
.pcv-bay-lab { font-family: var(--font-mono); font-size: 9px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--ink-soft); text-align: center; }
.pcv-bay-job { height: 30px; border-radius: 8px; display: grid; place-items: center;
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .03em;
  text-transform: uppercase; color: transparent; }
.pcv-bay-job.is-on { background: var(--pcv-accent); color: #fff; }

/* ---- blueprint (architects): the drawing draws itself ---- */
.pcv-blue { border-radius: 12px; border: 1px solid var(--line); padding: 8px;
  background: linear-gradient(150deg, rgba(0,161,199,.09), rgba(0,255,170,.06)); }
.pcv-blue svg { display: block; width: 100%; height: auto; }
.pcv-bp { fill: none; stroke: var(--cyan-deep); stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round; }
.pcv-bp-node { fill: var(--green); }

/* ---- route (travel): seats selling against a fixed departure ---- */
.pcv-deps { display: flex; flex-direction: column; gap: 10px; }
.pcv-dep { display: grid; grid-template-columns: 58px 44px 1fr 42px;
  align-items: center; gap: 9px; }
.pcv-dep-to { font-size: 13px; font-weight: 600; color: var(--ink); }
.pcv-dep-when { font-family: var(--font-mono); font-size: 10px; color: var(--ink-soft); }
.pcv-dep-bar { height: 14px; border-radius: 7px; background: rgba(255,255,255,.62);
  border: 1px solid var(--line); overflow: hidden; display: block; }
.pcv-dep-bar i { display: block; height: 100%; width: var(--w); border-radius: 7px;
  background: var(--pcv-accent); }
.pcv-dep-n { font-family: var(--font-mono); font-size: 10px; color: var(--ink-soft);
  text-align: right; }
.pcv-dep-n.is-out { color: var(--ink); font-weight: 700; }

/* ---- ring (gyms): the number closing the loop ---- */
.pcv-ringwrap { position: relative; width: 132px; margin: 0 auto; }
.pcv-ringwrap svg { display: block; width: 100%; height: auto; transform: rotate(-90deg); }
.pcv-ring-bg { fill: none; stroke: rgba(27,28,30,.10); stroke-width: 11; }
.pcv-ring-fg { fill: none; stroke: var(--green); stroke-width: 11; stroke-linecap: round; }
.pcv-ring-num { position: absolute; inset: 0; display: flex; align-items: center;
  justify-content: center; gap: 1px; font-family: var(--font-display); font-weight: 700;
  font-size: 27px; line-height: 1; color: var(--ink); }
.pcv-ring-num i { font-style: normal; font-size: 17px; }
.pcv-ring-lab { display: block; text-align: center; font-family: var(--font-mono);
  font-size: 10px; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-soft); }
.pcv-classes { display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px; }
.pcv-class { aspect-ratio: 1; border-radius: 5px; background: rgba(255,255,255,.6);
  border: 1px solid var(--line); }
.pcv-class.is-full { background: var(--pcv-accent); border-color: transparent; }

/* ---- direct (hotels): commission you keep ---- */
.pcv-split { display: flex; flex-direction: column; gap: 12px; }
.pcv-bar-row { display: grid; grid-template-columns: 56px 1fr; align-items: center; gap: 10px; }
.pcv-bar-lab { font-family: var(--font-mono); font-size: 10px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--ink-soft); }
.pcv-bar { height: 16px; border-radius: 8px; background: rgba(255,255,255,.6);
  border: 1px solid var(--line); overflow: hidden; display: block; }
.pcv-bar-fill { display: block; height: 100%; border-radius: 8px; }
.pcv-bar-direct { width: 74%; background: var(--green); }
.pcv-bar-ota { width: 26%; background: rgba(27,28,30,.2); }
.pcv-nights { display: grid; grid-template-columns: repeat(14, 1fr); gap: 4px; }
.pcv-night { aspect-ratio: 1; border-radius: 3px; background: var(--pcv-accent); opacity: .5; }

/* ---- chairs (salons): four chairs, a day stacking ---- */
.pcv-chairs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.pcv-chair { display: flex; flex-direction: column; gap: 5px; }
.pcv-chair-lab { font-family: var(--font-mono); font-size: 9px; color: var(--ink-soft);
  text-align: center; }
.pcv-appt { height: 16px; border-radius: 4px; background: rgba(255,255,255,.6);
  border: 1px solid var(--line); }
.pcv-appt.is-on { background: var(--pcv-accent); border-color: transparent; }

/* ---- dates (wedding venues): the Saturdays go first ---- */
.pcv-dates { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
.pcv-date { aspect-ratio: 1; border-radius: 5px; background: rgba(255,255,255,.55);
  border: 1px solid var(--line); }
.pcv-date.is-sat { border-color: var(--orange); }
.pcv-date.is-booked:not(.is-sat) { background: var(--pcv-accent); border-color: transparent; }
.pcv-date.is-booked { background: var(--orange); border-color: transparent; }

/* ---- seats (coaching): a batch filling ---- */
.pcv-hall { display: flex; flex-direction: column-reverse; gap: 7px; align-items: center; }
.pcv-board { width: 66%; height: 16px; border-radius: 5px; background: var(--ink); opacity: .82; }
.pcv-seatrow { display: flex; gap: 6px; justify-content: center; }
.pcv-seat { width: 18px; height: 18px; border-radius: 5px 5px 2px 2px;
  background: rgba(255,255,255,.6); border: 1px solid var(--line); }
.pcv-seat.is-taken { background: var(--pcv-accent); border-color: transparent; }

/* ---- floor (coworking): desks lighting up ---- */
.pcv-floor { position: relative; display: grid; grid-template-columns: repeat(6, 1fr);
  gap: 8px; padding: 14px; border-radius: 12px; border: 1px solid var(--line);
  background: linear-gradient(150deg, rgba(0,255,170,.08), rgba(0,161,199,.07)); }
.pcv-desk { aspect-ratio: 3/2; border-radius: 4px; background: rgba(255,255,255,.62);
  border: 1px solid var(--line); }
.pcv-desk.is-taken { background: var(--pcv-accent); border-color: transparent; }
.pcv-cabin { grid-column: 1 / -1; text-align: center; font-family: var(--font-mono);
  font-size: 9px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft);
  border: 1px dashed var(--line); border-radius: 6px; padding: 6px; }

/* ---- daysheet (clinics): consultations, not clicks ---- */
.pcv-sheet { display: flex; flex-direction: column; gap: 7px; }
.pcv-appt-row { display: grid; grid-template-columns: 46px 1fr; align-items: center; gap: 10px; }
.pcv-time { font-family: var(--font-mono); font-size: 10px; color: var(--ink-soft); }
.pcv-slotbar { height: 18px; border-radius: 6px; background: rgba(255,255,255,.6);
  border: 1px solid var(--line); }
.pcv-appt-row.is-booked .pcv-slotbar { background: var(--pcv-accent); border-color: transparent; }

/* ---- chart fallback ---- */
.pcv-chart { display: block; width: 100%; aspect-ratio: 360 / 180; }
.pcv-line2 { stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
.pcv-area2 { fill: var(--pcv-accent); opacity: .14; }
.pcv-dot2 { fill: #fff; stroke: var(--pcv-accent); stroke-width: 2.4; }
.pcv-dot2.is-last { fill: var(--green); stroke: #fff; }

/* ---------------------------------------------------------------------------
   Motion lives in assets/pc-motion.js, driven by anime.js.

   Nothing above is hidden by CSS. The stylesheet draws the finished picture and
   the script sets the "before" state itself just before it animates, so if the
   script never arrives, or a crawler never runs one, the page still shows a
   complete visual rather than an empty box.
   --------------------------------------------------------------------------- */
.js .pc-viz.is-in .pcv-stage {
  transform: translate3d(calc(var(--mx, 0) * 6px), calc(var(--my, 0) * 4px), 0);
  transition: transform .5s cubic-bezier(.2,.7,.3,1);
}
.js .pc-viz.is-tilting .pcv-stage { transition: transform .12s linear; }

@media (max-width: 700px) {
  .pc-viz { padding: 16px 16px 14px; }
  .pcv-stage { min-height: 178px; }
  .pcv-metric b { font-size: 19px; }
  .js .pc-viz.is-in .pcv-stage { transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .js .pc-viz.is-in .pcv-stage { transform: none; transition: none; }
}

/* ---------------------------------------------------------------------------
   Glass and clay on the animation surfaces.

   The concept internals were flat rectangles with a hairline border, which sat
   oddly inside a site built on translucent glass and soft clay. Every tile, bar
   and row now carries the same treatment as a .card: a translucent fill, a
   frosted sheen, an inset top highlight and a soft clay shadow.
   --------------------------------------------------------------------------- */
.pcv-ad, .pcv-day, .pcv-slot, .pcv-class, .pcv-date, .pcv-seat, .pcv-desk,
.pcv-appt, .pcv-bay-job, .pcv-night, .pcv-bar, .pcv-dep-bar, .pcv-slotbar,
.pcv-serp-row, .pcv-pack-row, .pcv-sugg span, .pcv-job, .pcv-area,
.pcv-listing, .pcv-answer, .pcv-search, .pcv-box, .pcv-sponsored {
  background-color: rgba(255, 255, 255, 0.55);
  backdrop-filter: blur(6px) saturate(1.15);
  -webkit-backdrop-filter: blur(6px) saturate(1.15);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.75),
    0 3px 8px -4px rgba(0, 90, 120, 0.28);
}

/* The "on" states are the payoff, so they get the clay lift rather than the
   flat fill: a little depth, a little brand light under them. */
.pcv-ad.is-winner, .pcv-day.is-post, .pcv-slot.is-booked, .pcv-class.is-full,
.pcv-seat.is-taken, .pcv-desk.is-taken, .pcv-appt.is-on, .pcv-bay-job.is-on,
.pcv-appt-row.is-booked .pcv-slotbar {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.45),
    0 6px 14px -6px rgba(0, 161, 199, 0.55);
  backdrop-filter: none; -webkit-backdrop-filter: none;
}
.pcv-date.is-booked {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.4),
    0 6px 14px -6px rgba(255, 107, 53, 0.55);
  backdrop-filter: none; -webkit-backdrop-filter: none;
}
/* Fills inside a track should not carry their own shadow, or the track reads
   as two stacked objects. */
.pcv-bar-fill, .pcv-dep-bar i, .pcv-ad-bar { box-shadow: none; backdrop-filter: none; }

/* The framed stages (bay board, blueprint, floor plan, map, network) are
   surfaces in their own right, so they get the full card treatment. */
.pcv-blue, .pcv-route, .pcv-floor, .pcv-map, .pcv-cover, .pcv-track, .pcv-net {
  backdrop-filter: blur(7px) saturate(1.15);
  -webkit-backdrop-filter: blur(7px) saturate(1.15);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.7),
    0 8px 20px -12px rgba(0, 90, 120, 0.34);
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  /* Same fallback rule the rest of the site uses: opaque rather than muddy. */
  .pcv-ad, .pcv-day, .pcv-slot, .pcv-class, .pcv-date, .pcv-seat, .pcv-desk,
  .pcv-appt, .pcv-bay-job, .pcv-night, .pcv-bar, .pcv-dep-bar, .pcv-slotbar,
  .pcv-serp-row, .pcv-pack-row, .pcv-sugg span, .pcv-job, .pcv-area,
  .pcv-listing, .pcv-answer, .pcv-search { background-color: var(--paper); }
}

/* The split-test tiles sit on the palest part of the board, so a translucent
   fill plus a hairline border left nine squares you could barely see. They need
   their own weight: a firmer edge and a tinted fill. */
.pcv-ad {
  background-color: rgba(255, 255, 255, 0.82);
  border-color: rgba(0, 161, 199, 0.30);
}
.pcv-ad::after {
  content: ""; position: absolute; inset: 8px 8px 14px;
  border-radius: 6px; background: rgba(0, 161, 199, 0.14);
}
.pcv-ad.is-winner { background-color: #fff; border-color: var(--green); }
.pcv-ad.is-winner::after { background: rgba(0, 255, 170, 0.30); }

/* ---------------------------------------------------------------------------
   Levers board (industry capabilities).

   Replaces a three-across grid where every card carried a thirty-five word
   paragraph. The list holds the headings, the stage holds one detail at a time,
   and the whole thing walks itself through. Every panel is in the DOM; only one
   is visible, so a reader meets one idea at a time instead of six at once.
   --------------------------------------------------------------------------- */
.pc-levers { display: grid; grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr); gap: 26px; align-items: stretch; }
.pcl-list { display: flex; flex-direction: column; gap: 6px; }
.pcl-tab {
  display: grid; grid-template-columns: 30px 1fr; align-items: center; gap: 12px;
  text-align: left; font: inherit; cursor: pointer;
  padding: 11px 15px; border-radius: 12px;
  border: 1px solid var(--line); background-color: rgba(255,255,255,0.55);
  backdrop-filter: blur(6px) saturate(1.15); -webkit-backdrop-filter: blur(6px) saturate(1.15);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.75), 0 3px 8px -4px rgba(0,90,120,.25);
  color: var(--ink-soft); transition: color .25s ease, background-color .25s ease, box-shadow .25s ease;
}
.pcl-tab i {
  font-family: var(--font-mono); font-style: normal; font-size: 11px;
  letter-spacing: .06em; color: var(--cyan-deep);
}
.pcl-tab span { font-size: 15px; font-weight: 500; line-height: 1.35; }
.pcl-tab:hover { color: var(--ink); }
.pcl-tab.is-active {
  color: var(--ink); background-color: #fff; border-color: transparent;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.6), 0 10px 24px -12px rgba(0,161,199,.55);
}
.pcl-tab.is-active i { color: var(--green); }

.pcl-stage {
  position: relative; display: flex; flex-direction: column; justify-content: center;
  min-height: 100%; padding: 34px 36px 38px;
  border-radius: var(--radius); border: 1px solid var(--line);
  background:
    radial-gradient(120% 90% at 50% -10%, rgba(0,255,170,0.13), transparent 58%),
    linear-gradient(158deg, rgba(233,255,247,0.86), rgba(230,246,250,0.86));
  box-shadow: var(--clay-shadow), var(--shadow-brand);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  overflow: hidden;
}
.pcl-stage::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image:
    linear-gradient(to right, rgba(0,161,199,0.09) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(0,161,199,0.09) 1px, transparent 1px);
  background-size: 26px 26px;
  -webkit-mask-image: radial-gradient(110% 80% at 50% 40%, #000 30%, transparent 82%);
  mask-image: radial-gradient(110% 80% at 50% 40%, #000 30%, transparent 82%);
}
/* Every panel stays rendered and stacked. Only the active one is visible, so
   the copy is still there for a crawler and for anyone without scripts. */
.pcl-panel { position: relative; z-index: 1; }
.pcl-panel h3 { font-size: 21px; line-height: 1.25; }
.pcl-panel p { margin-top: 12px; font-size: 16px; line-height: 1.6; color: var(--ink-soft); }
.pcl-progress {
  position: absolute; left: 0; right: 0; bottom: 0; height: 3px;
  background: rgba(0,161,199,.14); z-index: 2; display: none;
}
.pcl-progress i { display: block; height: 100%; width: 0; background: var(--pc-gradient); }

/* With scripts running, the stage shows one panel at a time and the bar tracks
   how long until it moves on. Without them, the panels simply stack and read as
   a normal list, which is the honest fallback. */
.js .pc-levers .pcl-panel { position: absolute; inset: 26px 28px auto; opacity: 0; }
.js .pc-levers .pcl-panel.is-active { position: relative; inset: auto; opacity: 1; }
.js .pc-levers .pcl-progress { display: block; }

@media (max-width: 900px) {
  .pc-levers { grid-template-columns: 1fr; gap: 18px; }
  .pcl-stage { min-height: 190px; }
  .pcl-tab { padding: 12px 14px; }
  .pcl-tab span { font-size: 14px; }
}
@media (prefers-reduced-motion: reduce) {
  .pcl-progress { display: none !important; }
}

/* ---------------------------------------------------------------------------
   Three more conversions on the industry pages, all measured out of the same
   audit: LEAP was 1,861 words, pains 1,633, roadmap 1,390, none with a visual.
   --------------------------------------------------------------------------- */

/* ---- LEAP: a sequence that looks like one ---- */
.pc-steps { position: relative; }
.pcs-rail { position: absolute; left: 0; right: 0; top: 31px; height: 3px;
  background: rgba(0,161,199,.14); border-radius: 2px; }
.pcs-rail-fill { display: block; height: 100%; width: 0; border-radius: 2px;
  background: var(--pc-gradient); }
.pcs-nodes { position: relative; display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.pcs-node { display: flex; flex-direction: column; align-items: center; gap: 10px;
  background: none; border: 0; font: inherit; cursor: pointer; padding: 0; color: var(--ink-soft); }
.pcs-letter {
  width: 64px; height: 64px; border-radius: var(--radius); display: grid; place-items: center;
  font-family: var(--font-display); font-weight: 700; font-size: 30px; line-height: 1;
  color: var(--ink-soft); background-color: rgba(255,255,255,.72);
  border: 1px solid var(--line);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.8), 0 4px 10px -6px rgba(0,90,120,.3);
  transition: transform .3s ease, color .3s ease, background .3s ease, box-shadow .3s ease;
}
.pcs-word { font-size: 15px; font-weight: 600; color: var(--ink-soft); transition: color .3s ease; }
.pcs-node.is-active .pcs-letter {
  color: #fff; background: var(--pc-gradient); border-color: transparent;
  box-shadow: 0 12px 26px -12px rgba(0,161,199,.7);
}
.pcs-node.is-active .pcs-word { color: var(--ink); }
.pcs-stage { position: relative; margin-top: 26px; padding: 26px 28px;
  border-radius: var(--radius); border: 1px solid var(--line);
  background: linear-gradient(158deg, rgba(233,255,247,.86), rgba(230,246,250,.86));
  box-shadow: var(--clay-shadow), var(--shadow-brand);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
.pcs-panel p { font-size: 17px; line-height: 1.6; color: var(--ink-soft); margin: 0; }
.pcs-link { margin-top: 16px; }
.js .pc-steps .pcs-panel { position: absolute; inset: 26px 28px auto; opacity: 0; }
.js .pc-steps .pcs-panel.is-active { position: relative; inset: auto; opacity: 1; }

/* ---- pains: a diagnostic readout ---- */
.pc-diag { display: flex; flex-direction: column; gap: 8px; }
.pcd-row { border-radius: var(--radius); border: 1px solid var(--line);
  background-color: rgba(255,255,255,.6);
  backdrop-filter: blur(6px) saturate(1.15); -webkit-backdrop-filter: blur(6px) saturate(1.15);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.75), 0 3px 8px -4px rgba(0,90,120,.25);
  overflow: hidden; }
.pcd-row summary { display: grid; grid-template-columns: 12px 1fr auto; align-items: center;
  gap: 14px; padding: 16px 20px; cursor: pointer; list-style: none; }
.pcd-row summary::-webkit-details-marker { display: none; }
.pcd-led { width: 10px; height: 10px; border-radius: 50%; background: rgba(27,28,30,.18); }
.pcd-h { font-size: 17px; font-weight: 600; color: var(--ink); line-height: 1.35; }
.pcd-state { font-family: var(--font-mono); font-size: 10px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-soft); }
.pcd-row[open] .pcd-led { background: var(--orange); box-shadow: 0 0 0 4px rgba(255,107,53,.18); }
.pcd-row[open] .pcd-state { color: var(--orange); }
.pcd-row p { margin: 0; padding: 0 20px 18px 46px; color: var(--ink-soft); line-height: 1.55; }

/* ---- roadmap: a track, not four options ---- */
.pc-track { position: relative; display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; }
.pct-line { position: absolute; left: 0; right: 0; top: 9px; height: 3px;
  background: rgba(0,161,199,.14); border-radius: 2px; }
.pct-line i { display: block; height: 100%; width: 0; border-radius: 2px; background: var(--pc-gradient); }
.pct-phase { position: relative; padding-top: 30px; }
.pct-dot { position: absolute; top: 3px; left: 0; width: 15px; height: 15px; border-radius: 50%;
  background: #fff; border: 3px solid var(--cyan-deep); }
.pct-when { font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-soft); }
.pct-phase h3 { font-size: 19px; margin-top: 6px; }
.pct-phase p { margin-top: 8px; font-size: 14.5px; line-height: 1.55; color: var(--ink-soft); }

@media (max-width: 900px) {
  .pcs-nodes { grid-template-columns: repeat(2, 1fr); gap: 18px; }
  .pcs-rail { display: none; }
  .pc-track { grid-template-columns: 1fr; gap: 22px; }
  .pct-line { left: 7px; right: auto; top: 0; bottom: 0; width: 3px; height: auto; }
  .pct-line i { width: 100%; height: 0; }
  .pct-phase { padding-top: 0; padding-left: 34px; }
  .pct-dot { top: 2px; }
}
@media (prefers-reduced-motion: reduce) {
  .pcs-rail-fill, .pct-line i { width: 100% !important; height: 100% !important; }
}

/* ---------------------------------------------------------------------------
   Reveals for the converted text sections.

   These are CSS transitions rather than anime.js tweens on purpose. anime is
   driven by requestAnimationFrame, which does not run while a document is
   hidden or throttled, and a body-copy section that never fades in is a section
   a reader cannot read. CSS transitions run regardless. anime keeps the hero
   concept timelines, where the sequencing is genuinely worth it.

   Gated on .js so none of it can hide anything when scripts do not arrive.
   --------------------------------------------------------------------------- */
.js .pc-track .pct-line i { transition: width 1.1s cubic-bezier(.2,.7,.3,1), height 1.1s cubic-bezier(.2,.7,.3,1); }
.js .pc-track.is-in .pct-line i { width: 100%; }
@media (max-width: 900px) {
  .js .pc-track.is-in .pct-line i { width: 100%; height: 100%; }
}
/* The stepper panel cross-fade, also in CSS so it cannot get stuck part-way. */
.js .pc-steps .pcs-panel { transition: opacity .34s ease; }
.js .pc-steps .pcs-panel.is-active { transition: opacity .34s ease .06s; }
@media (prefers-reduced-motion: reduce) {
  .js .pc-diag .pcd-row,     .js .pc-track .pct-line i { width: 100%; }
}

/* ---- proof (homepage): the results block, showing rather than telling ---- */
.pcp-filters { display: flex; flex-wrap: wrap; gap: 7px; }
.pcp-chip { font-family: var(--font-mono); font-size: 10px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--ink-soft); border: 1px solid var(--line);
  border-radius: 999px; padding: 5px 11px; background-color: rgba(255,255,255,.6); }
.pcp-chip.is-on { color: #fff; background: var(--pc-gradient); border-color: transparent; }
.pcp-rows { display: flex; flex-direction: column; gap: 7px; }
.pcp-row { display: grid; grid-template-columns: 1fr auto auto; align-items: center;
  gap: 12px; padding: 11px 14px; border-radius: 10px; border: 1px solid var(--line);
  background-color: rgba(255,255,255,.6);
  backdrop-filter: blur(6px) saturate(1.15); -webkit-backdrop-filter: blur(6px) saturate(1.15);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.75), 0 3px 8px -4px rgba(0,90,120,.25); }
.pcp-brand { font-size: 14px; font-weight: 600; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pcp-chan { font-family: var(--font-mono); font-size: 9px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--ink-soft); white-space: nowrap; }
.pcp-num { font-family: var(--font-display); font-weight: 700; font-size: 15px;
  color: var(--cyan-deep); white-space: nowrap; }

/* ---- stack (services): three tiers being built ---- */
.pcp-stack { display: flex; flex-direction: column-reverse; gap: 10px; }
.pcp-stack .pcs-layer { display: flex; flex-direction: column; gap: 3px;
  padding: 16px 18px; border-radius: var(--radius); border: 1px solid var(--line);
  background-color: rgba(255,255,255,.62);
  backdrop-filter: blur(6px) saturate(1.15); -webkit-backdrop-filter: blur(6px) saturate(1.15);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.75), 0 6px 16px -8px rgba(0,90,120,.3); }
.pcp-stack .pcs-layer:last-child {
  background: var(--pc-gradient); border-color: transparent;
  box-shadow: 0 14px 30px -14px rgba(0,161,199,.7); }
.pcs-layer-name { font-size: 16px; font-weight: 600; color: var(--ink); }
.pcs-layer-note { font-size: 13px; color: var(--ink-soft); line-height: 1.45; }
.pcp-stack .pcs-layer:last-child .pcs-layer-name,
.pcp-stack .pcs-layer:last-child .pcs-layer-note { color: #fff; }

/* Reveals in CSS, same reasoning as the other converted sections. */
@media (prefers-reduced-motion: reduce) {
  .js .pc-viz--proof .pcp-row, .js .pc-viz--proof .pcp-chip,
  .js .pc-viz--stack .pcs-layer { opacity: 1; transform: none; }
}

/* Direction variants, same principle: a keyframe that ends at the resting state. */
.js [data-anim="rise"].is-in  { animation-name: pc-v-rise; }
.js [data-anim="left"].is-in  { animation-name: pc-v-left; }
.js [data-anim="right"].is-in { animation-name: pc-v-right; }
.js [data-anim="scale"].is-in { animation-name: pc-v-scale; }
.js [data-anim="fade"].is-in  { animation-name: pc-v-fade; }
@keyframes pc-v-rise  { from { opacity: 0; transform: translateY(26px); } to { opacity: 1; transform: none; } }
@keyframes pc-v-left  { from { opacity: 0; transform: translateX(-24px); } to { opacity: 1; transform: none; } }
@keyframes pc-v-right { from { opacity: 0; transform: translateX(24px); } to { opacity: 1; transform: none; } }
@keyframes pc-v-scale { from { opacity: 0; transform: scale(.965); } to { opacity: 1; transform: none; } }
@keyframes pc-v-fade  { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .js [data-anim].is-in, .js .is-in [data-anim-child] { animation: none !important; }
}

/* The converted sections, on the same principle as [data-anim]: the resting
   state is visible, and .is-in plays a keyframe that starts hidden and lands
   exactly where the element already sits. A trigger that never fires costs a
   little motion, never the content. */
.js .pc-diag.is-in .pcd-row {
  animation: pc-slide-in .45s cubic-bezier(.2,.7,.3,1) both;
  animation-delay: calc(var(--i) * 90ms);
}
.js .pc-track.is-in .pct-phase {
  animation: pc-rise .5s cubic-bezier(.2,.7,.3,1) both;
  animation-delay: calc(var(--i) * 150ms + .15s);
}
.js .pc-track.is-in .pct-dot {
  animation: pc-pop .45s cubic-bezier(.3,1.4,.5,1) both;
  animation-delay: calc(var(--i) * 150ms + .2s);
}
.js .pc-viz--proof.is-in .pcp-chip {
  animation: pc-rise .34s ease both; animation-delay: calc(var(--i) * 70ms);
}
.js .pc-viz--proof.is-in .pcp-row {
  animation: pc-rise .45s cubic-bezier(.2,.7,.3,1) both;
  animation-delay: calc(var(--i) * 100ms + .28s);
}
.js .pc-viz--stack.is-in .pcs-layer {
  animation: pc-rise .5s cubic-bezier(.3,1.2,.4,1) both;
  animation-delay: calc(var(--i) * 160ms);
}
@keyframes pc-slide-in { from { opacity: 0; transform: translateX(-12px); } to { opacity: 1; transform: none; } }
@keyframes pc-pop { from { transform: scale(.3); } to { transform: scale(1); } }
@media (prefers-reduced-motion: reduce) {
  .js .pc-diag.is-in .pcd-row, .js .pc-track.is-in .pct-phase,
  .js .pc-track.is-in .pct-dot, .js .pc-viz--proof.is-in .pcp-chip,
  .js .pc-viz--proof.is-in .pcp-row, .js .pc-viz--stack.is-in .pcs-layer { animation: none !important; }
}

/* ---- relay (homepage): four channels into one team ---- */
.pcr-chans { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.pcr-ch { display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--ink); padding: 8px 6px; border-radius: 999px;
  border: 1px solid var(--line); background-color: rgba(255,255,255,.7);
  backdrop-filter: blur(6px) saturate(1.15); -webkit-backdrop-filter: blur(6px) saturate(1.15);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.8), 0 3px 8px -4px rgba(0,90,120,.25); }
.pcr-ch i { width: 6px; height: 6px; border-radius: 50%; background: var(--pcv-accent); flex: none; }
.pcr-lanes { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; height: 46px; }
.pcr-lane { position: relative; justify-self: center; width: 2px; height: 100%;
  background: rgba(0,161,199,.2); border-radius: 2px; overflow: hidden; }
.pcr-pulse { position: absolute; left: 0; right: 0; top: 0; height: 40%;
  border-radius: 2px; background: var(--pc-gradient); }
.pcr-hub { display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 14px 18px; border-radius: var(--radius); color: #fff;
  font-size: 16px; font-weight: 600; background: var(--pc-gradient);
  box-shadow: 0 14px 30px -14px rgba(0,161,199,.7); }
.pcr-hub-dot { width: 9px; height: 9px; border-radius: 50%; background: #fff; }
.pcr-out { display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 12px; }
.pcr-out-lab { font-family: var(--font-mono); font-size: 10px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-soft); }
.pcr-meter { display: grid; grid-template-columns: repeat(4, 1fr); gap: 5px; }
.pcr-step { height: 12px; border-radius: 4px; background: rgba(255,255,255,.6);
  border: 1px solid var(--line); }
.pcr-step.is-on { background: var(--pcv-accent); border-color: transparent; }

/* Reveal, on the same principle as everything else: visible at rest, the
   keyframe starts hidden and lands where the element already is. */
.js .pc-viz--relay.is-in .pcr-ch {
  animation: pc-rise .4s cubic-bezier(.2,.7,.3,1) both; animation-delay: calc(var(--i) * 90ms); }
.js .pc-viz--relay.is-in .pcr-pulse {
  animation: pcr-run 1.5s cubic-bezier(.4,0,.6,1) infinite; animation-delay: calc(var(--i) * 180ms + .4s); }
.js .pc-viz--relay.is-in .pcr-hub {
  animation: pc-pop .55s cubic-bezier(.3,1.3,.5,1) both; animation-delay: .5s; }
.js .pc-viz--relay.is-in .pcr-step {
  animation: pcr-fill .4s ease both; animation-delay: calc(var(--i) * 200ms + .9s); }
@keyframes pcr-run { 0% { top: -45%; opacity: 0; } 20% { opacity: 1; } 100% { top: 105%; opacity: 0; } }
@keyframes pcr-fill { to { background-color: var(--pcv-accent); border-color: transparent; } }
@media (prefers-reduced-motion: reduce) {
  .js .pc-viz--relay.is-in .pcr-ch, .js .pc-viz--relay.is-in .pcr-hub,
  .js .pc-viz--relay.is-in .pcr-pulse { animation: none !important; }
  .js .pc-viz--relay.is-in .pcr-step { animation: none !important;
    background-color: var(--pcv-accent); border-color: transparent; }
}

/* The stage carried a heading and three lines of copy in a box twice that tall,
   so most of it read as empty. The lever's own number now sits behind the copy
   at display size: it fills the space, and it tells you where you are in the
   list without another label. */
.pcl-stage::after {
  content: attr(data-n);
  position: absolute; right: 26px; bottom: 8px; z-index: 0;
  font-family: var(--font-display); font-weight: 700; font-size: 128px; line-height: .8;
  letter-spacing: -.04em; color: rgba(0, 161, 199, .09); pointer-events: none;
}
.pcl-panel { position: relative; z-index: 1; }
.pcl-panel h3 { font-size: 23px; }
.pcl-panel p { max-width: 46ch; }
@media (max-width: 900px) {
  .pcl-stage::after { font-size: 88px; right: 18px; }
  .pcl-stage { min-height: 0; padding: 26px 22px 30px; }
}

/* ===========================================================================
   Web Interface Guidelines pass.
   Seven rules the stylesheet was missing, all of them things a keyboard,
   touch or screen-reader user feels immediately.
   =========================================================================== */

/* Focus. Every interactive element needs a visible ring, and :focus-visible
   rather than :focus so it appears for keyboard users without flashing on
   every mouse click. */
:where(a, button, input, textarea, select, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--cyan-deep);
  outline-offset: 3px;
  border-radius: 6px;
}
/* Compound controls light up as a unit. */
/* :focus-visible, not :focus-within. The latter fires on a mouse click too, so
   clicking a LEAP step drew a hard cyan rectangle round it and left it there.
   A keyboard user still gets the ring; a mouse user gets nothing, which is the
   whole reason :focus-visible exists. */
.pcl-tab:focus-visible,
.pcs-node:focus-visible,
.pcl-tab:has(:focus-visible),
.pcs-node:has(:focus-visible) { outline: 2px solid var(--cyan-deep); outline-offset: 3px; }
/* The sticky header must never sit on top of whatever just took focus. */
:target, [id] { scroll-margin-top: 96px; }

/* Touch. manipulation removes the 300ms double-tap-zoom delay, and the tap
   highlight is set deliberately rather than left as the browser's blue box. */
a, button, summary, [role="button"], .pcl-tab, .pcs-node, .pcd-row summary {
  touch-action: manipulation;
  -webkit-tap-highlight-color: rgba(0, 161, 199, 0.16);
}

/* Scroll containers should not hand the scroll to the page when they hit
   their end. */
.tcar-track, .ind-wall--many, .aeo-table-wrap, .pcl-stage, dialog, .pc-fab-panel {
  overscroll-behavior: contain;
}

/* Headings should not leave a single word stranded on the last line. */
h1, h2, h3, .pcv-cap, .answer-q { text-wrap: balance; }
p, li, .pcv-cap { text-wrap: pretty; }

/* Figures that sit in a column or get compared to each other need to line up,
   which proportional digits will not do. */
.stat-num, .pcv-metric b, .pcp-num, .pcv-ring-num, .rc-num, .st-count,
.pct-when, .pcv-dep-n, .aeo-table td, .cmp-table td {
  font-variant-numeric: tabular-nums;
}

/* The skip link: off-screen until focused, then a proper target. */
.skip-link {
  position: absolute; left: 12px; top: -60px; z-index: 200;
  padding: 11px 18px; border-radius: 0 0 12px 12px;
  background: var(--ink); color: #fff; font-weight: 600; font-size: 15px;
  text-decoration: none;
  transition: top .18s ease;
}
/* :focus as well as :focus-visible. A skip link is the one control that must
   appear whenever it holds focus, including focus moved by a script or by a
   screen reader, and :focus-visible is a browser heuristic that does not fire
   for those. Showing it a little too eagerly costs nothing; hiding it while it
   is focused strands the keyboard user on an invisible link. */
.skip-link:focus,
.skip-link:focus-visible { top: 0; outline-offset: -3px; }

@media (prefers-reduced-motion: reduce) { .skip-link { transition: none; } }

/* ---------- Mobile legibility floor ----------
   Mono labels sit at 9-10px by design, which reads as a deliberate detail on a
   desktop board and as an eye test on a phone. These carry real information,
   the channel and the format, so they get a floor on small screens. */
@media (max-width: 640px) {
  .pcp-chan { font-size: 11px; }
  .pcp-chip, .pcr-out-lab { font-size: 11px; }
}

/* ---------- Logo wall length on a phone ----------
   Two columns made the marks readable and turned 35 logos into 18 rows, which
   is a very long scroll to sit between the process section and the
   testimonials. The wall is proof, not a directory: a dozen recognisable names
   makes the point, and the rest are one tap away. Every logo stays in the DOM,
   so nothing is hidden from a crawler, and the toggle is only wired up on
   small screens. */
/* Hidden by default; the mobile block below turns it on. Declared FIRST so
   source order cannot undo it. */
.logo-more { display: none; }
@media (max-width: 640px) {
  .logo-wall:not(.is-expanded) .logo-cell:nth-child(n+13) { display: none; }
  .logo-more {
    display: block; margin: 26px auto 0; padding: 12px 22px;
    border-radius: var(--radius); border: 1px solid var(--line);
    background-color: rgba(255,255,255,0.7); background-image: var(--glass-sheen);
    box-shadow: var(--clay-shadow-sm);
    font-family: var(--font-mono); font-size: 11px; letter-spacing: .08em;
    text-transform: uppercase; color: var(--ink); cursor: pointer;
  }
}
