/* ============================================================================
   BTPL design system — Bearing Technology Pvt. Ltd.
   Light corporate base + selective dark technical sections.
   Palette derived from the BTPL logo (navy/blue + green).
   ========================================================================== */

:root{
  --navy-950:#0A1E33; --navy-900:#0E2A47; --navy-800:#14365C; --navy-700:#1B4675;
  --blue-600:#2B6CB8; --blue-500:#3A7FCB; --blue-100:#E3EEF9;
  --green-700:#337F2C; --green-800:#2B6E24; --green-600:#3E9C35; --green-500:#4EAE42; --green-100:#E8F5E4;
  --ink-900:#132133; --ink-700:#33455C; --ink-500:#5A6C82; --ink-300:#93A3B5;
  --bg:#FFFFFF; --bg-soft:#F4F7FA; --line:#E2E9F0; --line-dark:#24405E;
  --radius:10px; --radius-lg:14px;
  --shadow-sm:0 1px 2px rgba(14,42,71,.06);
  --shadow-md:0 6px 24px -8px rgba(14,42,71,.16);
  --container:1200px; --container-narrow:820px;
  --font:'Inter','Segoe UI Variable Text','Segoe UI',system-ui,-apple-system,Roboto,Arial,sans-serif;
}

*,*::before,*::after{box-sizing:border-box}
[hidden]{display:none!important}
html{scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{
  margin:0;font-family:var(--font);color:var(--ink-900);background:var(--bg);
  font-size:16px;line-height:1.6;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
}
img,svg,video{max-width:100%;height:auto;display:block}
a{color:var(--blue-600);text-decoration:none}
a:hover{text-decoration:underline}
h1,h2,h3,h4{line-height:1.18;color:var(--navy-800);margin:0 0 .55em;font-weight:700;letter-spacing:-.015em}
h1{font-size:clamp(2rem,4.6vw,3.3rem);font-weight:800}
h2{font-size:clamp(1.5rem,3vw,2.15rem)}
h3{font-size:clamp(1.12rem,2vw,1.3rem)}
h4{font-size:1.02rem}
p{margin:0 0 1em}
ul{margin:0 0 1em;padding-left:1.2em}
.small{font-size:.875rem;color:var(--ink-500)}

/* ------- layout ------- */
.container{max-width:var(--container);margin:0 auto;padding:0 clamp(16px,4vw,32px)}
.container--narrow{max-width:var(--container-narrow)}
.section{padding:clamp(52px,8vw,92px) 0}
.section--soft{background:var(--bg-soft)}
.section--dark{background:var(--navy-950);color:#C9D6E5}
.section--dark h2,.section--dark h3,.section--dark h4{color:#fff}
.section--dark p{color:#AFC1D4}
.section-head{max-width:720px;margin-bottom:clamp(28px,4vw,44px)}
.section-head .kicker{display:block;font-size:.8rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--green-700);margin-bottom:10px}
.section--dark .section-head .kicker{color:var(--green-500)}
.section-head p{color:var(--ink-500);font-size:1.05rem;margin:0}
.section--dark .section-head p{color:#8FA6BE}
.grid{display:grid;gap:clamp(16px,2.5vw,28px)}
.grid-2{grid-template-columns:repeat(2,1fr)}
.grid-3{grid-template-columns:repeat(3,1fr)}
.grid-4{grid-template-columns:repeat(4,1fr)}
@media (max-width:980px){.grid-4{grid-template-columns:repeat(2,1fr)}.grid-3{grid-template-columns:repeat(2,1fr)}}
@media (max-width:640px){.grid-2,.grid-3,.grid-4{grid-template-columns:1fr}}

/* ------- buttons ------- */
.btn{display:inline-flex;align-items:center;gap:9px;font-weight:600;font-size:.98rem;
  padding:13px 26px;border-radius:8px;border:1.5px solid transparent;cursor:pointer;
  transition:background .18s,color .18s,border-color .18s,transform .18s;text-decoration:none!important;line-height:1.2}
.btn svg{width:17px;height:17px;flex:none}
.btn-primary{background:var(--green-700);color:#fff}
.btn-primary:hover{background:var(--green-800);transform:translateY(-1px)}
.btn-ghost{border-color:var(--navy-800);color:var(--navy-800);background:transparent}
.btn-ghost:hover{background:var(--navy-800);color:#fff}
.section--dark .btn-ghost,.hero .btn-ghost{border-color:#5E7CA0;color:#EAF1F8}
.section--dark .btn-ghost:hover,.hero .btn-ghost:hover{background:rgba(255,255,255,.1);border-color:#fff;color:#fff}
.btn-whatsapp{background:#1FAF52;color:#fff}
.btn-whatsapp:hover{background:#188F43}
.btn--sm{padding:9px 18px;font-size:.9rem}

/* ------- header ------- */
.site-header{position:sticky;top:0;z-index:60;background:rgba(255,255,255,.94);backdrop-filter:blur(10px);
  border-bottom:1px solid transparent;transition:border-color .2s, box-shadow .2s}
.site-header.is-stuck{border-bottom-color:var(--line);box-shadow:0 2px 14px rgba(14,42,71,.06)}
.nav-row{display:flex;align-items:center;gap:26px;min-height:72px}
.site-header.is-stuck .nav-row{min-height:62px}
.brand{display:flex;align-items:center;gap:10px;margin-right:auto}
.brand img{height:40px;width:auto}
.primary-nav{display:flex;align-items:center;gap:4px}
.primary-nav>li{list-style:none;position:relative}
.primary-nav{margin:0;padding:0}
.primary-nav a.nav-link{display:block;padding:10px 13px;color:var(--ink-700);font-weight:550;font-size:.96rem;border-radius:7px}
.primary-nav a.nav-link:hover,.primary-nav a.nav-link[aria-current="page"]{color:var(--navy-800);background:var(--bg-soft);text-decoration:none}
.has-menu>button{display:flex;align-items:center;gap:6px;padding:10px 13px;background:none;border:0;font:inherit;
  font-weight:550;font-size:.96rem;color:var(--ink-700);cursor:pointer;border-radius:7px}
.has-menu>button:hover{color:var(--navy-800);background:var(--bg-soft)}
.has-menu>button svg{width:12px;height:12px;transition:transform .18s}
.has-menu.open>button svg{transform:rotate(180deg)}
.dropdown{position:absolute;top:calc(100% + 6px);left:0;min-width:280px;background:#fff;border:1px solid var(--line);
  border-radius:var(--radius);box-shadow:var(--shadow-md);padding:8px;display:none;z-index:70}
.has-menu.open .dropdown{display:block}
.dropdown a{display:block;padding:9px 12px;border-radius:7px;color:var(--ink-700);font-size:.94rem;font-weight:500}
.dropdown a:hover{background:var(--bg-soft);color:var(--navy-800);text-decoration:none}
.dropdown a span{display:block;font-size:.8rem;color:var(--ink-500);font-weight:400}
/* ---- Services mega-menu -----------------------------------------------------
   Grouped three-column panel, replacing a single 280x789px column that
   overflowed an 800px viewport by 53px and wrapped four of its ten labels.
   Numbers below are measured in this site's own Inter subset, not estimated:

   WIDTH  longest row label  "Photogrammetry & Point Cloud"  214.4px @ .9rem/600
          longest sub-label  "Survey control & benchmarks"   167.1px @ .75rem/400
          longest group head "GROUND, WATER & SUBSURFACE"    205.4px @ .7rem/700
          row chrome = 10 pad-l + 18 icon + 10 gap + 10 pad-r = 48px
          => column >= 214.4 + 48 = 262.4. 280px used, leaving 17.6px of label
             slack so a font-synthesis difference cannot wrap a row.
          => panel = 3*280 + 2*20 gap + 2*14 pad + 2 border = 910px.

   HEIGHT row  = 8 + 14.4*1.35 + 12*1.35 + 8            = 51.6px
          head = 11.2*1.3 + 8 pad + 1 rule + 6 margin   = 29.6px
          tallest column (4 rows) = 29.6 + 4*51.6       = 236.1px
          panel = 14 + 236.1 + 14 + 2                   = 266px
          Panel top is y=64, so on an 800px viewport the bottom is 330px with
          470px to spare, against 853px (53px past the fold) before.

   Kept deliberately: display:none/block toggling rather than opacity, because
   opacity would leave ten hidden links in the tab order; and NO overflow:hidden,
   which would clip the 2.5px :focus-visible ring at the panel edges. */
.dropdown--mega{
  --mega-col:280px; --mega-gap:20px; --mega-pad:14px;
  width:calc(3*var(--mega-col) + 2*var(--mega-gap) + 2*var(--mega-pad) + 2px);
  max-width:calc(100vw - 24px);   /* so the panel can never overflow the page */
  padding:var(--mega-pad);
}
.dropdown--mega .mega-grid{
  display:grid;grid-template-columns:repeat(3,minmax(0,var(--mega-col)));
  gap:var(--mega-gap);align-items:stretch;
}
.dropdown--mega .mega-col{display:flex;flex-direction:column;min-width:0}
.dropdown--mega .mega-body{display:flex;flex-direction:column;flex:1;min-width:0}
.dropdown--mega .mega-head{
  margin:0 0 6px;padding:0 10px 8px;border-bottom:1px solid var(--line);
  font-size:.7rem;line-height:1.3;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:var(--green-700);
}
.dropdown--mega .mega-list{list-style:none;margin:0;padding:0}
.dropdown--mega .mega-list>li{list-style:none}
.dropdown--mega .mega-item{
  display:flex;align-items:flex-start;gap:10px;padding:8px 10px;border-radius:7px;
  box-shadow:inset 0 0 0 0 var(--green-600);
  transition:background .16s,box-shadow .16s,color .16s;
}
.dropdown--mega .mega-item .icon{width:18px;height:18px;flex:none;margin-top:1px;
  color:var(--blue-600);transition:color .16s}
.dropdown--mega .mega-txt{display:flex;flex-direction:column;min-width:0}
.dropdown--mega .mega-txt b{font-size:.9rem;line-height:1.35;font-weight:600;color:var(--navy-800)}
.dropdown--mega .mega-txt span{font-size:.75rem;line-height:1.35;font-weight:400;color:var(--ink-500)}
/* Hover and keyboard focus share one affordance, so a keyboard user sees exactly
   what a mouse user sees on top of the global :focus-visible ring. --ink-500 on
   --bg-soft measures 5.0:1, so the sub-label still clears AA when hovered. */
.dropdown--mega .mega-item:hover,
.dropdown--mega .mega-item:focus-visible{
  background:var(--bg-soft);text-decoration:none;
  box-shadow:inset 2px 0 0 0 var(--green-600);
}
.dropdown--mega .mega-item:hover .icon,
.dropdown--mega .mega-item:focus-visible .icon{color:var(--green-700)}
.dropdown--mega .mega-item:hover .mega-txt b,
.dropdown--mega .mega-item:focus-visible .mega-txt b{color:var(--navy-950)}
@media (prefers-reduced-motion:reduce){
  .dropdown--mega .mega-item,.dropdown--mega .mega-item .icon{transition:none}
}
.dropdown--mega .mega-card{
  margin-top:auto;padding:12px;border:1px solid var(--line);border-radius:8px;
  background:var(--bg-soft);
}
.dropdown--mega .mega-card p{margin:0 0 6px;font-size:.8rem;line-height:1.35;color:var(--ink-700)}
.dropdown--mega .mega-card a{display:inline-flex;align-items:center;gap:6px;padding:0;
  font-size:.825rem;font-weight:600;color:var(--blue-600)}
.dropdown--mega .mega-card a:hover{color:var(--navy-800);text-decoration:underline}
.dropdown--mega .mega-card a svg{width:14px;height:14px;flex:none}

.nav-ctas{display:flex;align-items:center;gap:10px;margin-left:6px}
.nav-tool{gap:7px}
.nav-toggle{display:none;background:none;border:0;padding:10px;cursor:pointer;margin-left:auto}
.nav-toggle svg{width:26px;height:26px;color:var(--navy-800)}
/* At <=1200px the Coordinate Converter button is dropped, which SHORTENS the
   right-hand CTA cluster and so pushes the primary nav RIGHT: the Services
   button moves from x=209 at 1201px to x=275 at 1199px. That makes 1081-1200px,
   not the narrowest desktop, the tightest band for a left-anchored panel — a
   910px panel there would end one pixel past the viewport edge. So the same
   breakpoint that drops the button also drops the menu to two columns (610px,
   ending at x=830), with the third group spanning the full width and its card
   beside the list rather than under it. */
@media (max-width:1200px){
  .nav-tool{display:none}
  .dropdown--mega{width:calc(2*var(--mega-col) + var(--mega-gap) + 2*var(--mega-pad) + 2px)}
  .dropdown--mega .mega-grid{grid-template-columns:repeat(2,minmax(0,var(--mega-col)))}
  .dropdown--mega .mega-col:last-child{grid-column:1/-1}
  .dropdown--mega .mega-col:last-child .mega-body{
    display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    gap:0 var(--mega-gap);align-items:start;
  }
  .dropdown--mega .mega-col:last-child .mega-card{margin-top:0}
}
@media (max-width:1080px){
  .primary-nav,.nav-ctas{display:none}
  .nav-toggle{display:block}
  .brand{margin-right:0}
  .nav-row{justify-content:space-between}
  .site-header.menu-open .mobile-nav{display:block}
}
.mobile-nav{display:none;border-top:1px solid var(--line);background:#fff;max-height:calc(100dvh - 62px);overflow:auto;padding:10px clamp(16px,4vw,32px) 26px}
.mobile-nav a{display:block;padding:13px 4px;font-weight:600;color:var(--navy-800);border-bottom:1px solid var(--line)}
.mobile-nav a.sub{font-weight:450;color:var(--ink-700);padding-left:18px;font-size:.94rem}
.mobile-nav .group{font-size:.78rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--green-600);padding:16px 4px 4px}
.mobile-nav .btn{margin-top:18px;width:100%;justify-content:center}

/* ------- hero ------- */
.hero{background:
  radial-gradient(1200px 500px at 85% -10%, rgba(43,108,184,.25), transparent 60%),
  radial-gradient(900px 420px at -10% 110%, rgba(62,156,53,.16), transparent 60%),
  var(--navy-950);
  color:#D7E2EF;position:relative;overflow:hidden}
.hero::before{content:"";position:absolute;inset:0;background:url('../img/brand/contours.svg') center/900px repeat;opacity:.14;pointer-events:none}
.hero-inner{position:relative;display:grid;grid-template-columns:1.05fr .95fr;gap:clamp(28px,4vw,56px);align-items:center;
  padding:clamp(56px,8vw,104px) 0}
.hero h1{color:#fff;margin-bottom:18px}
.hero .lede{font-size:clamp(1rem,1.6vw,1.16rem);color:#AFC3D8;max-width:56ch;margin-bottom:26px}
.tech-strip{display:flex;flex-wrap:wrap;gap:8px 10px;margin:0 0 30px;padding:0;list-style:none}
.tech-strip li{font-size:.82rem;font-weight:600;letter-spacing:.06em;color:#9FE290;
  border:1px solid rgba(78,174,66,.45);border-radius:999px;padding:5px 13px;background:rgba(62,156,53,.12)}
.hero-ctas{display:flex;gap:14px;flex-wrap:wrap}
.hero-tool{margin:18px 0 0}
.hero-tool a{display:inline-flex;align-items:center;gap:8px;font-size:.9rem;font-weight:600;color:#A9E79B;
  border:1px solid rgba(78,174,66,.4);background:rgba(62,156,53,.1);border-radius:999px;padding:8px 16px}
.hero-tool a:hover{background:rgba(62,156,53,.22);border-color:#4EAE42;text-decoration:none}
.hero-tool svg{width:16px;height:16px}
.hero-visual{position:relative;min-width:0}
.hero-visual .frame{border:1px solid var(--line-dark);border-radius:var(--radius-lg);overflow:hidden;
  box-shadow:0 24px 60px -22px rgba(0,0,0,.55);background:#0B2036}
.hero-visual figcaption{font-size:.8rem;color:#7E93AB;margin-top:10px;text-align:center}
@media (max-width:980px){.hero-inner{grid-template-columns:1fr}.hero-visual{max-width:560px}}

/* ------- field→deliverable flow (text columns aligned under the scene) ------- */
/* gap:0 so each column is an exact quarter, centering under the scene stations;
   horizontal padding on the step gives the visual separation instead */
.flow{display:grid;grid-template-columns:repeat(4,1fr);gap:0}
.flow-step{text-align:center;padding:2px clamp(12px,1.6vw,22px) 0}
.flow-step .num{font-size:.78rem;font-weight:800;letter-spacing:.12em;color:var(--green-700);display:block}
.flow-step h3{margin:7px 0 12px;font-size:1.1rem}
.flow-step ul{display:inline-block;text-align:left;margin:0;padding:0;list-style:none;font-size:.92rem;color:var(--ink-500)}
.flow-step ul li{position:relative;padding:3.5px 0 3.5px 18px}
.flow-step ul li::before{content:"";position:absolute;left:0;top:11px;width:6px;height:6px;border-radius:50%;background:var(--green-500)}
@media (max-width:820px){
  .flow{grid-template-columns:1fr 1fr;gap:clamp(18px,4vw,28px)}
}
@media (max-width:560px){
  .flow{grid-template-columns:1fr;gap:0}
  .flow-step{text-align:left;padding:16px 2px;border-top:1px solid var(--line)}
  .flow-step ul{display:block}
}

/* ------- animated workflow scene ------- */
.scene{margin:0 0 clamp(22px,3vw,34px);border-radius:var(--radius-lg);overflow-x:auto;overflow-y:hidden;
  border:1px solid var(--line-dark);background:#081726;box-shadow:0 20px 50px -22px rgba(10,30,51,.4);
  -webkit-overflow-scrolling:touch}
.scene svg{display:block;width:100%;height:auto;min-width:600px}
.scene::-webkit-scrollbar{height:6px}
.scene::-webkit-scrollbar-thumb{background:#2C4E70;border-radius:3px}

/* capabilities grid — balances 10 cards as 5+5 on desktop */
.cap-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(215px,1fr));gap:clamp(14px,1.8vw,20px)}
.cap-grid .card{padding:22px 20px}
.cap-grid .card h3{font-size:1.02rem}
.cap-grid .card p{font-size:.9rem}
@media (max-width:1100px){.cap-grid{grid-template-columns:repeat(3,1fr)}}
@media (max-width:820px){.cap-grid{grid-template-columns:repeat(2,1fr)}}
@media (max-width:520px){.cap-grid{grid-template-columns:1fr}}

/* ------- cards ------- */
.card{background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:26px;
  transition:transform .2s,box-shadow .2s,border-color .2s;position:relative;display:flex;flex-direction:column}
.card:hover{transform:translateY(-3px);box-shadow:var(--shadow-md);border-color:#CBD8E4}
.card .icon{width:38px;height:38px;color:var(--green-600);margin-bottom:14px}
.card h3 a{color:var(--navy-800)}
.card h3 a:hover{text-decoration:none}
.card h3 a::after{content:"";position:absolute;inset:0}
.card p{font-size:.94rem;color:var(--ink-500);margin:0 0 14px}
.card .go{margin-top:auto;font-weight:600;font-size:.92rem;color:var(--green-700);display:inline-flex;align-items:center;gap:6px}
.card:hover .go{color:var(--green-800)}
.card .go svg{width:15px;height:15px;transition:transform .18s}
.card:hover .go svg{transform:translateX(3px)}

/* image-led card */
.card--img{padding:0;overflow:hidden}
.card--img .body{padding:20px 22px 22px}
.card--img img{aspect-ratio:3/2;object-fit:cover;width:100%}


/* reserve space for JSON-rendered project cards so injecting them does not
   shift the content below (Core Web Vitals: CLS) */
[data-projects]{min-height:520px}
[data-projects]:empty::after{content:"";display:block;min-height:420px}
@media (max-width:640px){[data-projects]{min-height:760px}}

/* ------- project cards ------- */
.project-card{background:#fff;border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;
  display:flex;flex-direction:column;transition:transform .25s,box-shadow .25s,border-color .25s;position:relative}
.project-card:hover{transform:translateY(-4px);box-shadow:var(--shadow-md);border-color:#BFD0DF}
.project-card .visual{aspect-ratio:16/9;background:linear-gradient(135deg,var(--navy-800),var(--navy-950));position:relative;overflow:hidden}
/* bias the 16:9 crop slightly above centre so instruments/people stay in frame
   when a portrait field photo is used */
.project-card .visual img{width:100%;height:100%;object-fit:cover;object-position:center 42%;
  transform:scale(1.02);transition:transform 6s cubic-bezier(.2,.6,.3,1)}
.project-card:hover .visual img{transform:scale(1.12)}
/* survey scan-line sweep across the project visual — always running,
   staggered per card so sweeps don't sync; faster while hovered.
   Animated with transform, not `top`: `top` is a layout property, so 20 cards
   sweeping at once re-ran style+layout every frame (measured 4.3s of Style &
   Layout on throttled mobile). `mix-blend-mode` is also gone — it forces the
   compositor to read backdrop pixels each frame, which defeats layer promotion;
   the gradient stops are brightened to keep the same glow without it. */
.project-card .scanline{position:absolute;left:0;right:0;top:0;height:26%;pointer-events:none;opacity:0;
  background:linear-gradient(180deg,transparent,rgba(120,205,105,.26) 62%,rgba(190,240,178,.92) 98%,transparent 100%);
  animation:pscan 4.2s cubic-bezier(.45,.05,.4,.95) infinite;
  animation-delay:calc(var(--stagger,0)*1.4s)}
.project-card:hover .scanline{animation-duration:1.9s;animation-delay:0s}
/* translateY percentages resolve against the element's own height (26% of the
   card), so -108%/400% reproduce the original -28%..104% travel of the card. */
@keyframes pscan{0%{transform:translateY(-108%);opacity:0}10%{opacity:1}55%{opacity:1}
  70%{transform:translateY(400%);opacity:0}100%{transform:translateY(400%);opacity:0}}
/* surveyor's reticle corners */
.project-card .reticle{position:absolute;inset:10px;pointer-events:none;opacity:0;transition:opacity .3s}
.project-card:hover .reticle{opacity:1}
.project-card .reticle i{position:absolute;width:17px;height:17px;border:2px solid rgba(159,226,144,.95);border-radius:1px}
.project-card .reticle i:nth-child(1){top:0;left:0;border-right:0;border-bottom:0}
.project-card .reticle i:nth-child(2){top:0;right:0;border-left:0;border-bottom:0}
.project-card .reticle i:nth-child(3){bottom:0;left:0;border-right:0;border-top:0}
.project-card .reticle i:nth-child(4){bottom:0;right:0;border-left:0;border-top:0}
.project-card .visual .sector{position:absolute;top:12px;left:12px;background:rgba(10,30,51,.82);color:#CFE3F6;
  font-size:.74rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;padding:4px 11px;border-radius:999px;backdrop-filter:blur(4px)}
.project-card .body{padding:20px 22px 22px;display:flex;flex-direction:column;flex:1}
.project-card h3{font-size:1.06rem;margin-bottom:8px}
.project-card h3 a{color:var(--navy-800)}
.project-card h3 a::after{content:"";position:absolute;inset:0}
.project-card .meta{font-size:.86rem;color:var(--ink-500);margin-bottom:12px}
.project-card .meta b{color:var(--ink-700);font-weight:600}
.chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:auto}
.chip{font-size:.76rem;font-weight:600;color:var(--navy-700);background:var(--blue-100);border-radius:999px;padding:3.5px 11px}
.chip--green{background:var(--green-100);color:#2F7526}
.filter-bar{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:28px}
.filter-bar button{border:1px solid var(--line);background:#fff;color:var(--ink-700);font:inherit;font-size:.88rem;
  font-weight:600;padding:7px 16px;border-radius:999px;cursor:pointer;transition:all .15s}
.filter-bar button:hover{border-color:var(--green-600);color:var(--green-700)}
.filter-bar button.active{background:var(--navy-800);border-color:var(--navy-800);color:#fff}

/* ------- tech groups (dark) ------- */
.tech-group{border:1px solid var(--line-dark);border-radius:var(--radius);padding:24px;background:rgba(255,255,255,.03);
  transition:border-color .2s,background .2s}
.tech-group:hover{border-color:#3A5C82;background:rgba(255,255,255,.05)}
.tech-group .icon{width:36px;height:36px;color:var(--green-500);margin-bottom:14px}
.tech-group h3{font-size:1.05rem}
.tech-group p{font-size:.92rem;margin:0}

/* ------- industries: illustrated sector cards ------- */
.ind-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(16px,2vw,24px)}
@media (max-width:980px){.ind-grid{grid-template-columns:repeat(2,1fr)}}
@media (max-width:520px){.ind-grid{grid-template-columns:1fr}}
.ind-card{position:relative;display:block;border-radius:var(--radius-lg);overflow:hidden;border:1px solid var(--line);
  background:#fff;box-shadow:var(--shadow-sm);text-decoration:none;aspect-ratio:4/3;
  transition:transform .22s,box-shadow .22s,border-color .22s}
.ind-card:hover{transform:translateY(-4px);box-shadow:var(--shadow-md);border-color:#BFD0DF;text-decoration:none}
.ind-art{position:absolute;inset:0;width:100%;height:100%;transition:transform .5s cubic-bezier(.2,.6,.3,1)}
.ind-card:hover .ind-art{transform:scale(1.06)}
.ind-card::after{content:"";position:absolute;inset:0;background:linear-gradient(transparent 40%,rgba(255,255,255,.86) 78%,#fff 100%)}
.ind-badge{position:absolute;top:16px;left:16px;z-index:2;width:56px;height:56px;border-radius:50%;background:#fff;
  display:flex;align-items:center;justify-content:center;box-shadow:0 6px 16px -6px rgba(14,42,71,.35)}
.ind-badge svg{width:28px;height:28px;color:var(--navy-800)}
.ind-badge::after{content:"";position:absolute;bottom:11px;width:16px;height:2.5px;border-radius:2px;background:var(--green-600)}
.ind-cap{position:absolute;left:18px;right:16px;bottom:15px;z-index:2}
.ind-cap b{display:block;font-size:1.08rem;font-weight:700;color:var(--navy-800);letter-spacing:-.01em;line-height:1.2}
.ind-cap span{display:block;font-size:.86rem;color:var(--ink-500);margin-top:3px}
.ind-cap::before{content:"";display:block;width:26px;height:3px;border-radius:2px;background:var(--green-600);margin-bottom:9px}

/* ------- industries (legacy tiles, /industries page anchors) ------- */
.industry-tile{position:relative;border-radius:var(--radius);overflow:hidden;aspect-ratio:4/3;display:flex;align-items:flex-end;
  background:linear-gradient(160deg,var(--navy-700),var(--navy-950));transition:transform .2s,box-shadow .2s}
.industry-tile:hover{transform:translateY(-3px);box-shadow:var(--shadow-md)}
.industry-tile .art{position:absolute;inset:0;opacity:.5;transition:opacity .25s,transform .4s}
.industry-tile:hover .art{opacity:.72;transform:scale(1.04)}
.industry-tile .label{position:relative;z-index:1;width:100%;padding:16px 18px;color:#fff;font-weight:700;font-size:1.02rem;
  background:linear-gradient(transparent,rgba(10,30,51,.88) 55%);letter-spacing:-.01em}
.industry-tile .label span{display:block;font-size:.8rem;font-weight:500;color:#A9BFD6;margin-top:2px}

/* ------- deliverables wall ------- */
.deliv{display:flex;align-items:center;gap:13px;border:1px solid var(--line);background:#fff;border-radius:var(--radius);padding:14px 16px;
  transition:transform .18s,border-color .18s,box-shadow .18s}
.deliv:hover{transform:translateY(-2px);border-color:#CBD8E4;box-shadow:var(--shadow-sm)}
.deliv .icon{width:30px;height:30px;flex:none;color:var(--blue-600)}
.deliv b{font-size:.93rem;color:var(--navy-800);display:block;line-height:1.3}
.deliv span{font-size:.8rem;color:var(--ink-500)}

/* ------- comparison slider ------- */
.compare{position:relative;border-radius:var(--radius-lg);overflow:hidden;border:1px solid var(--line-dark);
  aspect-ratio:16/9;user-select:none;touch-action:none;background:#0B2036}
.compare .layer{position:absolute;inset:0}
.compare .layer svg,.compare .layer img{width:100%;height:100%;object-fit:cover;display:block}
.compare .layer--top{clip-path:inset(0 calc(100% - var(--pos,50%)) 0 0)}
.compare .divider{position:absolute;top:0;bottom:0;left:var(--pos,50%);width:2px;background:#fff;box-shadow:0 0 12px rgba(0,0,0,.5);transform:translateX(-1px)}
.compare .handle{position:absolute;top:50%;left:var(--pos,50%);transform:translate(-50%,-50%);width:42px;height:42px;border-radius:50%;
  background:#fff;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 16px rgba(0,0,0,.4);color:var(--navy-800)}
.compare .handle svg{width:20px;height:20px}
.compare .tag{position:absolute;bottom:12px;font-size:.78rem;font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  color:#EAF3FC;background:rgba(10,30,51,.75);padding:4px 12px;border-radius:999px;pointer-events:none}
.compare .tag--a{left:12px}.compare .tag--b{right:12px}
.compare input[type=range]{position:absolute;inset:0;width:100%;height:100%;opacity:0;cursor:ew-resize;margin:0}

/* ------- why list ------- */
.why-item{display:flex;gap:16px;align-items:flex-start}
.why-item .icon{width:30px;height:30px;flex:none;color:var(--green-600);margin-top:3px}
.why-item h3{font-size:1.02rem;margin-bottom:4px}
.why-item p{font-size:.92rem;color:var(--ink-500);margin:0}

/* ------- trust strip ------- */
.trust-strip{display:flex;flex-wrap:wrap;gap:clamp(20px,4vw,48px);align-items:center;justify-content:center;text-align:center}
.trust-strip .fact b{display:block;font-size:clamp(1.5rem,3vw,2rem);color:var(--navy-800);font-weight:800;letter-spacing:-.02em}
.trust-strip .fact span{font-size:.85rem;color:var(--ink-500);font-weight:550}
.client-line{text-align:center;max-width:76ch;margin:26px auto 0;font-size:.95rem;color:var(--ink-500);line-height:1.9}
.client-line b{color:var(--navy-800);font-weight:700}
/* Clients strip. Every cell carries the client NAME; a cell also carries the mark
   where written permission exists. Most clients have no logo file, so the named
   cell is the normal state — that is what keeps the strip full and even instead of
   collapsing to the two logos BTPL is currently cleared to show.
   No grayscale/opacity dimming: it was applied to the whole cell, so once names
   were added it washed out the text as well as the artwork. */
.logo-wall{display:grid;grid-template-columns:repeat(auto-fill,minmax(146px,1fr));
  gap:12px;align-items:stretch}
/* min-height keeps rows even whether or not a cell carries a mark, but stays low
   enough that a name-only cell does not read as an empty box waiting for an image.

   Two fixed rows, not a flex column. Under flex the name sat directly beneath the
   mark, so its baseline moved with the mark's height: seals (42px) pushed it to 82px
   from the cell top and wordmarks (30px) left it at 76px, and the two markless cells
   centred themselves at 57px and 66px. Four different baselines across one row of
   cells, a 25px spread, which is what read as "odd placement". A fixed 42px mark row
   -- the tallest mark -- decouples the name from the artwork above it, so every name
   lands on one baseline no matter what sits over it. */
.logo-wall .logo{display:grid;grid-template-rows:42px auto;align-content:start;
  justify-items:center;gap:9px;min-height:86px;padding:13px 11px;border:1px solid var(--line);
  border-radius:10px;background:#fff;text-align:center;
  transition:border-color .18s,box-shadow .18s}
.logo-wall .logo .cl-logo{grid-row:1;align-self:center}
/* explicit, because a markless cell has nothing in row 1 and auto-placement would
   otherwise promote its name into the mark row and un-align it again */
.logo-wall .cl-name{grid-row:2;align-self:start}
.logo-wall .logo:hover{border-color:#BFD0DF;box-shadow:var(--shadow-sm)}

/* ------- CTA band ------- */
.cta-band{background:
  radial-gradient(700px 300px at 90% 10%, rgba(78,174,66,.18), transparent 60%),
  var(--navy-900);
  border-radius:var(--radius-lg);padding:clamp(34px,5vw,60px);color:#fff;position:relative;overflow:hidden}
.cta-band::before{content:"";position:absolute;inset:0;background:url('../img/brand/contours.svg') center/700px repeat;opacity:.1;pointer-events:none}
.cta-band>*{position:relative}
.cta-band h2{color:#fff}
.cta-band p{color:#B7C9DC;max-width:60ch}
.cta-band .actions{display:flex;gap:14px;flex-wrap:wrap;margin-top:22px}

/* ------- footer ------- */
.site-footer{background:var(--navy-950);color:#93A9C0;font-size:.92rem}
.footer-grid{display:grid;grid-template-columns:1.4fr 1fr 1fr 1fr 1.2fr;gap:clamp(22px,3vw,40px);padding:clamp(40px,6vw,64px) 0 34px}
.site-footer h4{color:#fff;font-size:.86rem;letter-spacing:.1em;text-transform:uppercase;margin-bottom:14px}
.site-footer ul{list-style:none;margin:0;padding:0}
.site-footer li{padding:4px 0}
.site-footer a{color:#93A9C0}
.site-footer a:hover{color:#fff}
.footer-brand img{height:42px;margin-bottom:14px;background:#fff;border-radius:8px;padding:6px 10px}
.footer-brand p{font-size:.9rem;color:#7E93AB;max-width:34ch}
.footer-contact li{display:flex;gap:9px;align-items:flex-start}
.footer-contact svg{width:16px;height:16px;flex:none;margin-top:4px;color:var(--green-500)}
.footer-bottom{border-top:1px solid var(--line-dark);padding:18px 0;display:flex;flex-wrap:wrap;gap:10px;justify-content:space-between;font-size:.84rem;color:#8095AC}
.footer-social{display:flex;gap:10px}
.footer-social a{display:flex;width:34px;height:34px;border:1px solid var(--line-dark);border-radius:8px;align-items:center;justify-content:center;color:#93A9C0}
.footer-social a:hover{border-color:#4E6E92;color:#fff}
.footer-social svg{width:16px;height:16px}
@media (max-width:980px){.footer-grid{grid-template-columns:1fr 1fr}}
@media (max-width:560px){.footer-grid{grid-template-columns:1fr}}

/* ------- page hero (inner pages) ------- */
.page-hero{background:
  radial-gradient(900px 380px at 90% -20%, rgba(43,108,184,.22), transparent 60%),
  var(--navy-950);color:#C9D6E5;padding:clamp(44px,7vw,76px) 0;position:relative;overflow:hidden}
.page-hero::before{content:"";position:absolute;inset:0;background:url('../img/brand/contours.svg') center/900px repeat;opacity:.12;pointer-events:none}
.page-hero>*{position:relative}
.page-hero h1{color:#fff;margin-bottom:10px;font-size:clamp(1.8rem,3.8vw,2.7rem)}
.page-hero .lede{color:#A8BCD2;font-size:1.06rem;max-width:64ch;margin:0}
.breadcrumbs{font-size:.84rem;color:#7E93AB;margin-bottom:16px;display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.breadcrumbs a{color:#A8BCD2}
.breadcrumbs svg{width:12px;height:12px}
.cs-photo{margin:0 0 16px}
.cs-photo img{width:100%;height:auto;aspect-ratio:880/495;border-radius:var(--radius-lg);border:1px solid var(--line);display:block}
.cs-photo figcaption{font-size:.83rem;color:var(--ink-500);margin-top:8px;line-height:1.5}
.cs-photo--ill img{background:#F6FAFD}
.cs-meta{display:flex;flex-wrap:wrap;gap:10px 28px;margin-top:18px}
.cs-meta span{font-size:.94rem;color:#EAF3FC}
.cs-meta b{display:block;font-size:.72rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:#7FD18A;margin-bottom:3px}

/* ------- prose / service pages ------- */
.prose{max-width:70ch;overflow-wrap:break-word}
.prose h2{margin-top:1.6em}
.split{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,.9fr);gap:clamp(24px,4vw,52px);align-items:start}
@media (max-width:900px){.split{grid-template-columns:minmax(0,1fr)}}
.check-list{list-style:none;padding:0}
.check-list li{position:relative;padding:7px 0 7px 32px;font-size:.97rem}
.check-list li::before{content:"";position:absolute;left:0;top:11px;width:19px;height:19px;border-radius:50%;
  background:var(--green-100) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23337F2C' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 13l4 4L19 7'/%3E%3C/svg%3E") center/11px no-repeat}
.info-card{border:1px solid var(--line);border-left:4px solid var(--green-600);background:var(--bg-soft);border-radius:8px;padding:18px 20px;font-size:.95rem}
.faq details{border:1px solid var(--line);border-radius:var(--radius);padding:0;margin-bottom:10px;background:#fff}
.faq summary{cursor:pointer;font-weight:600;color:var(--navy-800);padding:16px 20px;list-style:none;display:flex;justify-content:space-between;align-items:center;gap:12px}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";font-size:1.3rem;color:var(--green-600);font-weight:500;line-height:1}
.faq details[open] summary::after{content:"–"}
.faq details p{padding:0 20px 16px;margin:0;color:var(--ink-500);font-size:.95rem}
.stat-row{display:flex;flex-wrap:wrap;gap:12px}
.stat-pill{border:1px solid var(--line);border-radius:8px;background:#fff;padding:10px 16px;font-size:.9rem}
.stat-pill b{color:var(--navy-800)}

/* ------- tables ------- */
.table-wrap{overflow-x:auto;border:1px solid var(--line);border-radius:var(--radius)}
table.data{border-collapse:collapse;width:100%;font-size:.92rem;background:#fff}
table.data th{background:var(--bg-soft);color:var(--navy-800);text-align:left;font-weight:700;padding:11px 14px;border-bottom:1px solid var(--line);white-space:nowrap}
table.data td{padding:10px 14px;border-bottom:1px solid var(--line)}
table.data tr:last-child td{border-bottom:0}

/* ------- google map (click to load) ------- */

/* Compact live map in the office card. Fixed height with fluid width, NOT
   aspect-ratio + min-height: those two together make the box derive its WIDTH
   from its height (330 * 4/3 = 440px), which overflowed a 393px phone viewport
   by 117px. A fixed height also reserves the box exactly, so the lazy iframe
   adds no CLS, and it keeps the frame tall enough that Google renders its zoom
   controls — they disappear below roughly 300px of height. */
.map-mini{position:relative;width:100%;height:330px;margin:14px 0 12px;border-radius:8px;
  overflow:hidden;border:1px solid var(--line);background:#EAF0F6}
.map-mini iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.map-mini-links{display:flex;flex-wrap:wrap;gap:8px 18px;margin:0}
.map-mini-links a{display:inline-flex;align-items:center;gap:5px;font-size:.9rem;font-weight:600}

/* ------- forms ------- */
fieldset{min-inline-size:0;border:0;padding:0;margin:0}
legend{padding:0}
.field{margin-bottom:16px}
.field label{display:block;font-weight:600;font-size:.9rem;color:var(--navy-800);margin-bottom:6px}
.field .hint{font-weight:400;color:var(--ink-500);font-size:.82rem}
.field input[type=text],.field input[type=email],.field input[type=tel],.field input[type=number],.field input[type=date],
.field select,.field textarea{
  width:100%;padding:11px 13px;border:1.5px solid var(--line);border-radius:8px;font:inherit;font-size:.96rem;color:var(--ink-900);
  background:#fff;transition:border-color .15s, box-shadow .15s}
.field input:focus,.field select:focus,.field textarea:focus{outline:none;border-color:var(--blue-600);box-shadow:0 0 0 3px rgba(43,108,184,.14)}
.field textarea{min-height:110px;resize:vertical}
.choice-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:10px}
.choice{border:1.5px solid var(--line);border-radius:8px;padding:13px 14px;cursor:pointer;display:flex;gap:10px;align-items:center;
  font-size:.92rem;font-weight:550;color:var(--ink-700);transition:all .15s;background:#fff}
.choice:hover{border-color:var(--blue-600)}
.choice input{accent-color:var(--green-600);width:16px;height:16px;margin:0}
.choice.checked{border-color:var(--green-600);background:var(--green-100);color:var(--green-700)}
.form-steps{display:flex;gap:6px;margin-bottom:26px;flex-wrap:wrap}
.form-steps .step{font-size:.8rem;font-weight:600;padding:6px 13px;border-radius:999px;background:var(--bg-soft);color:var(--ink-500);border:1px solid var(--line)}
.form-steps .step.active{background:var(--navy-800);color:#fff;border-color:var(--navy-800)}
.form-steps .step.done{color:var(--green-700);background:var(--green-100);border-color:var(--green-100)}
.form-nav{display:flex;justify-content:space-between;gap:12px;margin-top:26px}

/* ------- reveal animations (staggered inside grids) ------- */
.reveal{opacity:0;transform:translateY(18px);transition:opacity .55s ease,transform .55s ease}
.reveal.in{opacity:1;transform:none}
.grid>.reveal:nth-child(2),.flow>.reveal:nth-child(2){transition-delay:.08s}
.grid>.reveal:nth-child(3){transition-delay:.16s}
.grid>.reveal:nth-child(4){transition-delay:.24s}
.grid>.reveal:nth-child(5){transition-delay:.10s}
.grid>.reveal:nth-child(6){transition-delay:.18s}
.grid>.reveal:nth-child(7){transition-delay:.26s}
.grid>.reveal:nth-child(8){transition-delay:.34s}
/* JSON-rendered project cards arrive with .in already set — animate entry via
   keyframes (with per-card stagger) so hover transitions stay instant */
.project-card.in{animation:riseIn .55s both;animation-delay:calc(var(--stagger,0)*.1s)}

/* hero entrance */
@keyframes riseIn{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
.hero h1{animation:riseIn .6s .05s both}
.hero .lede{animation:riseIn .6s .16s both}
.hero-ctas{animation:riseIn .6s .38s both}
.hero-visual{animation:riseIn .7s .3s both}
.tech-strip li{animation:riseIn .5s both}
.tech-strip li:nth-child(1){animation-delay:.22s}.tech-strip li:nth-child(2){animation-delay:.27s}
.tech-strip li:nth-child(3){animation-delay:.32s}.tech-strip li:nth-child(4){animation-delay:.37s}
.tech-strip li:nth-child(5){animation-delay:.42s}.tech-strip li:nth-child(6){animation-delay:.47s}

/* section kicker underline draw */
.section-head .kicker::after{content:"";display:block;width:44px;height:2.5px;margin-top:8px;
  background:var(--green-600);border-radius:2px;transform-origin:left;transform:scaleX(0);transition:transform .6s .15s ease}
.section-head.reveal.in .kicker::after,.section-head:not(.reveal) .kicker::after{transform:scaleX(1)}

/* icon micro-motion on card hover */
.card .icon,.why-item .icon,.tech-group .icon,.deliv .icon{transition:transform .25s ease,color .25s ease}
.card:hover .icon{transform:translateY(-3px) scale(1.06);color:var(--green-700)}
.deliv:hover .icon{transform:scale(1.1);color:var(--green-600)}
.tech-group:hover .icon{transform:translateY(-3px)}
.industry-tile .label{transition:transform .25s ease}
.industry-tile:hover .label{transform:translateY(-2px)}

/* comparison handle nudge hint until first use */
.compare:not(.used) .handle{animation:nudge 2.6s ease-in-out 1.2s 3}
@keyframes nudge{0%,100%{transform:translate(-50%,-50%)}12%{transform:translate(calc(-50% - 10px),-50%)}24%{transform:translate(calc(-50% + 10px),-50%)}36%{transform:translate(-50%,-50%)}}

/* keyboard focus */
:focus-visible{outline:2.5px solid var(--blue-600);outline-offset:2px;border-radius:4px}
.section--dark :focus-visible,.hero :focus-visible{outline-color:#9FE290}

/* Pause decorative animation while it is scrolled off screen.
   The homepage runs 13 infinite animations, three of which drive stroke-dashoffset
   (not compositable, so every frame repaints the SVG path). Measured while scrolling
   on a 4x-throttled mobile profile: 33.3ms median frame time, 35% late frames, 53
   long tasks. Every other page measured a clean 16.7ms with zero long tasks, which is
   what identified the homepage animations as the cause.
   Pausing off-screen changes nothing the visitor sees — the animation runs whenever
   it is actually in view — but it stops paying for it during the scroll. */
.anim-idle, .anim-idle *{animation-play-state:paused!important}

@media (prefers-reduced-motion:reduce){
  .reveal{opacity:1;transform:none;transition:none}
  .card,.project-card,.industry-tile,.deliv,.btn{transition:none}
  .project-card .visual img{transition:none;transform:none}
  .project-card:hover .visual img{transform:none}
  .project-card:hover .scanline{animation:none;opacity:0}
  *{animation-duration:.001s!important;animation-iteration-count:1!important}
}

/* ------- misc ------- */
.eyebrow-note{display:inline-flex;align-items:center;gap:8px;font-size:.8rem;font-weight:600;color:var(--ink-500);
  border:1px solid var(--line);border-radius:999px;padding:5px 14px;background:#fff}
.skip-link{position:absolute;left:-9999px;top:0;background:var(--navy-800);color:#fff;padding:10px 18px;z-index:100;border-radius:0 0 8px 0}
.skip-link:focus{left:0}
::selection{background:rgba(78,174,66,.3)}
.anchor-offset{scroll-margin-top:90px}
.badge-draft{display:inline-block;font-size:.72rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:#B45309;background:#FEF3C7;border:1px solid #FDE68A;padding:3px 10px;border-radius:999px;vertical-align:middle}

/* ------- enquiry form: real endpoint ------- */
/* Visually hidden but announced. The status region must stay in the accessibility
   tree — display:none would silence it entirely. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* Error summary sits ABOVE the form, outside <form>, so a screen reader is not
   competing with the form's own busy state while it reads. */
.enq-summary{border:2px solid #B91C1C;border-left-width:6px;border-radius:var(--radius);
  background:#FEF2F2;padding:16px 18px;margin:0 0 18px}
.enq-summary h3{margin:0 0 8px;font-size:1.02rem;color:#991B1B}
.enq-summary ul{margin:0;padding-left:20px}
.enq-summary li{margin:4px 0}
.enq-summary a{color:#991B1B;text-decoration:underline;font-weight:600}

.fielderr{display:block;margin-top:5px;font-size:.85rem;font-weight:600;color:#B91C1C}
.fielderr:empty{display:none}
.field input[aria-invalid="true"],.field textarea[aria-invalid="true"]{border-color:#B91C1C;
  background:#FEF2F2}

/* Honeypot. Off-screen rather than aria-hidden: a screen-reader user who lands
   on it via the virtual cursor still hears a usable instruction, and axe does
   not flag a focusable node inside an aria-hidden subtree. */
.hp-field{position:absolute;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden}

.enq-progress{margin-top:14px}
.enq-progress-track{height:8px;border-radius:999px;background:var(--line);overflow:hidden}
.enq-progress-bar{height:100%;width:0;background:var(--green-700);
  transition:width .25s linear}

.consent-note{margin-top:12px;color:var(--ink-500)}

/* These are focus targets with tabindex="-1"; without scroll-margin the sticky
   header covers them, so a keyboard user is scrolled to a heading they cannot see. */
.enq-summary,.fstep-title,#enqDoneTitle{scroll-margin-top:90px}
h3.fstep-title{margin:0 0 14px;font-size:1.05rem;color:var(--navy-800)}
.fstep-title:focus-visible{outline:2.5px solid var(--blue-600);outline-offset:3px;border-radius:4px}

/* ------- client credits ------- */
/* The label uses --ink-500 (5.38:1 on white), NOT --ink-300. --ink-300 is
   #93A3B5 = 2.58:1, which is the exact token the accessibility audit removed
   from text: all 68 original violations were this one rule. At .72rem bold the
   large-text exemption does not apply (that needs >=18.66px bold), so 4.5:1 is
   required. */
/* The client credit is ONE line at the foot of the card, under the deliverable
   chips -- not a stacked "CLIENT / mark+name / ENGAGED THROUGH / mark+name" block
   in the middle of the body. That block ran to 114px, sat between the meta and the
   chips where it broke the reading order, and BTPL called it out as looking wrong.
   Three placements were built against the real cards and compared: on the photo
   (the mark covered the image and read like a watermark), inside the meta lines
   (the mark shrank to ~16px and effectively disappeared), and this one. */
.pc-credit{display:flex;align-items:baseline;gap:10px;margin-top:12px;padding-top:10px;
  border-top:1px solid var(--line);font-size:.86rem;line-height:1.45;color:var(--ink-700)}
.pc-credit .lbl{flex:0 0 auto;font-size:.72rem;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;color:var(--ink-500)}
.pc-credit .cl-text{min-width:0}
.pc-credit .cl-via{color:var(--ink-500)}
/* keeps the mark glued to the name it belongs to, so a line break can never leave
   a mark sitting alone against the other party's name */
.pc-credit .cl-party{white-space:nowrap}
.pc-credit .cl-logo{display:inline-block;width:auto;vertical-align:-5px;margin-right:6px}
.pc-credit .cl-logo--word{height:20px;max-width:82px}
.pc-credit .cl-logo--seal{height:22px;max-width:30px}

/* The mark is always adjacent to the client name, never alone, so it is
   decorative (alt="") and its legibility carries no meaning. That is what makes
   a 28px seal acceptable here. */
.cl-logo{display:block;width:auto;object-fit:contain}
.cl-logo--word{height:22px;max-width:130px}
.cl-logo--seal{height:30px;max-width:44px}

/* logo wall — sizing of the optional mark and the always-present name */
.logo-wall .cl-logo--word{height:30px;max-width:120px}
/* Seals are circular, so they need more height than a wordmark to read as the
   same visual size. Balaji's is a document seal with hairline rim type that is
   illegible at any size this strip can afford — which is precisely why the name
   below it is not optional. */
.logo-wall .cl-logo--seal{height:42px;max-width:58px}
.logo-wall .cl-name{font-size:.85rem;font-weight:600;color:var(--ink-700);line-height:1.3;
  text-wrap:balance}
.client-disclaimer{max-width:800px;margin:24px auto 0;text-align:center;color:var(--ink-500);
  line-height:1.55}

/* Case studies use the same one-line credit as the project cards, so the mark is
   inline with the name rather than a flex sibling that wrap could strand. */
.cs-client{margin-top:8px}
.cs-client p{margin:0}
.cs-client .cl-via{color:var(--ink-500)}
.cs-client .cl-party{white-space:nowrap}
.cs-client .cl-logo{display:inline-block;width:auto;vertical-align:-5px;margin-right:6px}
.cs-client .cl-logo--word{height:20px;max-width:82px}
.cs-client .cl-logo--seal{height:22px;max-width:30px}
