/* ==========================================================================
   Iron Bell - design system
   Dark navy, squared, editorial. Built from the Iron Bell design canvas.
   ========================================================================== */

:root{
  /* surface */
  --ink:#0B1220;          /* page background            */
  --ink-2:#0E1626;        /* raised surface             */
  --ink-3:#1B2942;        /* device bezels, chips       */
  --on-accent:#07101E;    /* text that sits on accent   */

  /* type */
  --fg:#F2F6FD;
  --fg-muted:#A8B7CE;
  --fg-dim:#8595AF;

  /* accent */
  --accent:#2E8BFF;
  --accent-soft:#7FB4FF;
  --accent-hi:#A9CCFF;

  /* lines */
  --line:rgba(255,255,255,.12);
  --line-soft:rgba(255,255,255,.08);
  --line-strong:rgba(255,255,255,.24);

  /* fonts */
  --display:"Archivo",system-ui,-apple-system,"Segoe UI",sans-serif;
  --body:"Hanken Grotesk",system-ui,-apple-system,"Segoe UI",sans-serif;
  --mono:"JetBrains Mono",ui-monospace,SFMono-Regular,monospace;

  /* metrics */
  --wrap:1280px;
  --gut:40px;
  --nav-h:72px;

  /* rhythm - sections breathe, per the brief */
  --sp-xs:24px;
  --sp-s:48px;
  --sp-m:88px;
  --sp-l:130px;
  --sp-xl:160px;
}

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

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

body{
  margin:0;
  background:var(--ink);
  color:var(--fg);
  font-family:var(--body);
  font-size:17px;
  line-height:1.7;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
}

img,video,svg{display:block;max-width:100%}
a{color:var(--accent-soft);text-decoration:none;transition:color .18s ease}
a:hover{color:var(--accent-hi)}

h1,h2,h3,h4{
  font-family:var(--display);
  font-weight:600;
  letter-spacing:-.022em;
  text-wrap:pretty;
  margin:0;
}

p{margin:0}
ul{margin:0;padding:0;list-style:none}

::selection{background:var(--accent);color:var(--on-accent)}

:focus-visible{
  outline:2px solid var(--accent-soft);
  outline-offset:3px;
}

.skip-link{
  position:absolute;left:-9999px;top:0;z-index:200;
  background:var(--accent);color:var(--on-accent);
  font-family:var(--display);font-size:14px;font-weight:600;
  padding:14px 20px;
}
.skip-link:focus{left:0;color:var(--on-accent)}

/* --------------------------------------------------------------------------
   Layout primitives
   -------------------------------------------------------------------------- */

.wrap{max-width:var(--wrap);margin:0 auto;padding-left:var(--gut);padding-right:var(--gut)}
.narrow{max-width:900px}
.tight{max-width:820px}
.slim{max-width:700px}

.section{padding-top:var(--sp-l);padding-bottom:var(--sp-l)}
.section--tall{padding-top:var(--sp-xl);padding-bottom:var(--sp-xl)}
.section--flush-top{padding-top:0}
.section--flush-bottom{padding-bottom:0}
.centred{text-align:center}

/* --------------------------------------------------------------------------
   Type scale
   -------------------------------------------------------------------------- */

.eyebrow{
  font-family:var(--display);
  font-size:12px;
  font-weight:600;
  letter-spacing:.22em;
  text-transform:uppercase;
  color:var(--accent-soft);
  margin:0 0 22px;
}

.h-hero{font-size:clamp(38px,5.2vw,76px);line-height:1.05;letter-spacing:-.025em}
.h-page{font-size:clamp(34px,4.4vw,60px);line-height:1.12}
.h-sec{font-size:clamp(29px,3.4vw,48px);line-height:1.14}
.h-sub{font-size:clamp(26px,2.8vw,40px);line-height:1.24}
.h-min{font-size:clamp(24px,2.4vw,34px);line-height:1.25}

.lede{
  font-size:clamp(16.5px,1.6vw,18.5px);
  line-height:1.72;
  color:var(--fg-muted);
  margin:26px auto 0;
  max-width:560px;
}
.body-copy{font-size:17px;line-height:1.85;color:var(--fg-muted)}
.body-copy + .body-copy{margin-top:22px}

.chip{
  display:inline-block;
  font-family:var(--display);
  font-size:12px;font-weight:600;
  letter-spacing:.16em;text-transform:uppercase;
  color:var(--on-accent);background:var(--accent-soft);
  padding:6px 12px;
}

/* --------------------------------------------------------------------------
   Buttons - squared, never pills
   -------------------------------------------------------------------------- */

.btn{
  display:inline-flex;align-items:center;justify-content:center;
  font-family:var(--display);
  font-size:15px;font-weight:600;
  letter-spacing:.005em;
  padding:16px 30px;
  border:1px solid transparent;
  border-radius:0;
  cursor:pointer;
  transition:background .18s ease,color .18s ease,border-color .18s ease,transform .18s ease;
}
.btn--primary{background:var(--accent);color:var(--on-accent)}
.btn--primary:hover{background:var(--accent-soft);color:var(--on-accent);transform:translateY(-1px)}
.btn--ghost{border-color:var(--line-strong);color:var(--fg);font-weight:500}
.btn--ghost:hover{border-color:var(--fg);color:var(--fg);background:rgba(255,255,255,.04)}

.btn-row{display:flex;justify-content:center;gap:12px;margin-top:42px;flex-wrap:wrap}

/* underline link, used in place of extra buttons */
.link-rule{
  display:inline-block;
  font-family:var(--display);
  font-size:14px;font-weight:500;
  letter-spacing:.06em;text-transform:uppercase;
  color:var(--accent-soft);
  border-bottom:2px solid var(--accent);
  padding-bottom:4px;
}
.link-rule:hover{color:var(--accent-hi);border-color:var(--accent-soft)}

.link-quiet{
  display:inline-block;
  font-size:14.5px;
  border-bottom:1px solid rgba(127,180,255,.45);
  padding-bottom:2px;
}
.link-quiet:hover{border-color:var(--accent-hi)}

/* --------------------------------------------------------------------------
   Header / navigation
   -------------------------------------------------------------------------- */

.site-header{
  position:sticky;top:0;z-index:80;
  background:rgba(11,18,32,.72);
  -webkit-backdrop-filter:saturate(150%) blur(14px);
  backdrop-filter:saturate(150%) blur(14px);
  border-bottom:1px solid var(--line);
  transition:background .3s ease,border-color .3s ease;
}
.site-header.is-stuck{background:rgba(9,15,27,.94);border-bottom-color:var(--line-strong)}

/* The bar height never changes. Transitioning height would relayout the whole
   page on every scroll tick, and the drawer's `inset:var(--nav-h)` assumes a
   fixed bar. The stuck state changes material, not geometry. */
.nav-bar{
  max-width:var(--wrap);margin:0 auto;
  height:var(--nav-h);
  display:flex;align-items:center;justify-content:space-between;
  padding-left:var(--gut);
}

.nav-logo{display:flex;align-items:center;gap:16px;flex:none;color:inherit}
.nav-logo img{
  height:28px;width:auto;
  transform-origin:left center;
  transition:transform .3s ease;
}
.site-header.is-stuck .nav-logo img{transform:scale(.9)}
.nav-rule{width:1px;height:22px;background:var(--line);flex:none}

/* --------------------------------------------------------------------------
   Slogan
   Set on Archivo's expanded width axis so it reads as its own wordmark rather
   than another UI label, without pulling in a second family.
   -------------------------------------------------------------------------- */

.slogan{
  display:inline-block;
  font-family:var(--display);
  font-variation-settings:"wdth" 122;
  font-weight:800;
  text-transform:uppercase;
  letter-spacing:.02em;
  line-height:1;
  white-space:nowrap;
  color:var(--fg);
}
.slogan em{font-style:normal;color:var(--accent-soft)}

.slogan--nav{font-size:13.5px;color:var(--fg-muted);transition:color .25s ease}
.nav-logo:hover .slogan--nav{color:var(--fg)}
.slogan--footer{font-size:17px;margin:2px 0 16px}
.slogan--lead{font-size:clamp(15px,1.5vw,19px);margin-bottom:18px}

.nav-links{
  position:relative;
  display:flex;align-items:stretch;align-self:stretch;
  font-family:var(--display);
  font-size:13px;font-weight:500;
  letter-spacing:.09em;text-transform:uppercase;
}

/* One accent bar glides between cells rather than a bar per cell fading in
   and out. It rides a fixed 100px base on translate + scaleX, never an
   animated width, so nothing in the header ever relayouts. */
.nav-ind{
  position:absolute;left:0;top:0;
  width:100px;height:2px;
  background:var(--accent);
  transform:translate3d(var(--nav-x,0),0,0) scaleX(var(--nav-sx,0));
  transform-origin:left center;
  transition:transform .42s cubic-bezier(.6,0,.25,1),opacity .3s ease;
  pointer-events:none;
}
.nav-ind::after{
  content:"";position:absolute;left:0;right:0;top:-1px;height:16px;
  background:radial-gradient(58% 100% at 50% 0,rgba(46,139,255,.5),transparent 72%);
}
.nav-ind.is-idle{opacity:0}

/* tapered hairlines, inset from the bar edges, rather than flat full borders */
.nav-link,.nav-cta{position:relative}
.nav-link::before{
  content:"";position:absolute;left:0;top:15px;bottom:15px;width:1px;
  background:linear-gradient(180deg,transparent,var(--line) 24%,var(--line) 76%,transparent);
}

.nav-link{
  display:flex;align-items:center;
  padding:0 24px;
  color:var(--fg-muted);
  transition:color .25s ease,background .25s ease;
}
.nav-link:hover{color:var(--fg);background:rgba(255,255,255,.045)}
.nav-link[aria-current="page"]{color:var(--fg)}

/* The label rolls up on hover: two copies, the incoming one pre-tinted.
   The line-height is pinned so each copy is exactly one roll-height tall -
   inheriting the body's 1.7 makes the line box taller than the window and
   clips the label. */
.nav-roll{display:block;overflow:hidden;height:1.35em;line-height:1.35}
.nav-roll span{
  display:block;line-height:1.35;
  transition:transform .34s cubic-bezier(.6,0,.25,1);
}
.nav-roll span + span{color:var(--accent-soft)}
.nav-link:hover .nav-roll span{transform:translateY(-1.35em)}

.nav-cta{
  display:flex;align-items:center;
  padding:0 28px;
  background:var(--accent);color:var(--on-accent);
  overflow:hidden;
  transition:background .2s ease;
}
.nav-cta:hover{background:var(--accent-soft);color:var(--on-accent)}
/* gloss sweep, driven on transform so the header stays layout-stable */
.nav-cta::after{
  content:"";position:absolute;top:0;bottom:0;left:0;width:45%;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.42),transparent);
  transform:translateX(-180%) skewX(-18deg);
  transition:transform .7s cubic-bezier(.4,0,.2,1);
  pointer-events:none;
}
.nav-cta:hover::after{transform:translateX(330%) skewX(-18deg)}

/* reading progress hairline */
.nav-progress{
  position:absolute;left:0;bottom:-1px;height:2px;width:100%;
  background:var(--accent);
  transform:scaleX(0);transform-origin:left;
  opacity:.85;
  pointer-events:none;
}

/* mobile toggle */
/* Burger only, no label. The whole icon counter-rotates while the outer bars
   fold into the cross and the middle bar retracts to nothing, so opening reads
   as one movement rather than three separate ones. */
.nav-toggle{
  display:none;
  align-items:center;justify-content:center;
  height:100%;padding:0 var(--gut);
  background:none;border:none;border-left:1px solid var(--line);
  color:var(--fg);
  cursor:pointer;
}
/* Exponential ease-out, matching the rest of the sheet. The interest here is
   the choreography - the icon turning while the middle bar retracts - not an
   overshoot wobble, which at 26px just reads as a rattle. */
.nav-toggle-bars{
  position:relative;width:26px;height:16px;flex:none;
  transition:transform .42s cubic-bezier(.16,1,.3,1);
}
.nav-toggle-bars span{
  position:absolute;left:0;width:100%;height:2px;
  background:var(--fg);
  transform-origin:center;
  transition:transform .42s cubic-bezier(.16,1,.3,1),
             background-color .3s ease;
}
.nav-toggle-bars span:nth-child(1){top:0}
.nav-toggle-bars span:nth-child(2){top:7px}
.nav-toggle-bars span:nth-child(3){top:14px}

/* resting flourish: the middle bar sits short and grows out on hover */
.nav-toggle-bars span:nth-child(2){transform:scaleX(.58);transform-origin:left center}
.nav-toggle:hover .nav-toggle-bars span:nth-child(2){transform:scaleX(1)}
.nav-toggle:hover .nav-toggle-bars span{background:var(--accent-soft)}

.nav-toggle[aria-expanded="true"] .nav-toggle-bars{transform:rotate(-90deg)}
.nav-toggle[aria-expanded="true"] .nav-toggle-bars span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.nav-toggle[aria-expanded="true"] .nav-toggle-bars span:nth-child(2){transform:scaleX(0)}
.nav-toggle[aria-expanded="true"] .nav-toggle-bars span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

/* --------------------------------------------------------------------------
   Social icons
   -------------------------------------------------------------------------- */

.social{display:flex;gap:10px;align-items:center}
.social a{
  display:flex;align-items:center;justify-content:center;
  width:40px;height:40px;
  border:1px solid var(--line);
  color:var(--fg-muted);
  transition:color .22s ease,border-color .22s ease,background .22s ease,transform .22s ease;
}
.social svg{width:19px;height:19px}
.social a:hover{
  color:var(--on-accent);background:var(--accent-soft);
  border-color:var(--accent-soft);transform:translateY(-2px);
}
.social--drawer{margin-top:6px}

/* mobile drawer */
.nav-drawer{
  position:fixed;inset:var(--nav-h) 0 0;
  z-index:70;
  background:var(--ink);
  border-top:1px solid var(--line);
  display:flex;flex-direction:column;justify-content:space-between;
  padding:8px 0 40px;
  opacity:0;visibility:hidden;
  transform:translateY(-8px);
  transition:opacity .3s ease,transform .3s ease,visibility .3s;
  overflow-y:auto;
}
.nav-drawer.is-open{opacity:1;visibility:visible;transform:none}

.drawer-link{
  display:flex;align-items:baseline;gap:16px;
  padding:22px var(--gut);
  border-bottom:1px solid var(--line-soft);
  font-family:var(--display);
  font-size:26px;font-weight:600;letter-spacing:-.02em;
  color:var(--fg);
  opacity:0;transform:translateY(10px);
}
.nav-drawer.is-open .drawer-link{
  animation:drawerIn .42s cubic-bezier(.2,.7,.3,1) forwards;
}
.drawer-link .idx{
  font-family:var(--mono);font-size:12px;font-weight:400;
  color:var(--accent-soft);letter-spacing:.08em;
}
.drawer-link[aria-current="page"]{color:var(--accent-soft)}

@keyframes drawerIn{to{opacity:1;transform:none}}

.drawer-foot{padding:34px var(--gut) 0;display:flex;flex-direction:column;gap:14px}
.drawer-foot .btn{width:100%}
.drawer-contact{display:flex;flex-direction:column;gap:8px;font-size:15px;color:var(--fg-muted)}

body.nav-open{overflow:hidden}

/* --------------------------------------------------------------------------
   Photo bands - imagery blended into the page, never boxed
   -------------------------------------------------------------------------- */

.photo-bg{
  position:absolute;inset:0;
  overflow:hidden;
  pointer-events:none;
}
.photo-bg img,.photo-bg video{
  width:100%;height:100%;
  object-fit:cover;
  /* pull warm stock towards the navy palette so nothing reads as a pasted-in box */
  filter:saturate(.28) contrast(1.04) brightness(.62);
}
/* navy wash sits on top of the photo and blends it into the page colour */
.photo-bg::after{
  content:"";position:absolute;inset:0;
  background:var(--ink);
  mix-blend-mode:color;
  opacity:.72;
}

/* Some source photos are already shot dark. Darkening those again buries them,
   so they get lifted instead and the veil alone does the blending. Declared
   after the base rules because the specificity is identical. */
.photo-bg--lift img{filter:saturate(.5) contrast(1.08) brightness(1.55)}
.photo-bg--lift::after{opacity:.45}
/* the fade: page colour at the edges, photo visible through the middle */
.photo-veil{
  position:absolute;inset:0;pointer-events:none;
  background:
    linear-gradient(180deg,rgba(11,18,32,.62) 0%,rgba(11,18,32,.5) 38%,rgba(11,18,32,.88) 82%,var(--ink) 100%),
    radial-gradient(120% 78% at 50% 46%,rgba(11,18,32,0) 0%,rgba(11,18,32,.5) 68%,rgba(11,18,32,.9) 100%);
}
/* stronger wash where copy sits directly over the photo */
.photo-veil--deep{
  background:
    linear-gradient(180deg,rgba(11,18,32,.78) 0%,rgba(11,18,32,.68) 42%,rgba(11,18,32,.93) 84%,var(--ink) 100%),
    radial-gradient(115% 76% at 50% 48%,rgba(11,18,32,.12) 0%,rgba(11,18,32,.62) 66%,rgba(11,18,32,.94) 100%);
}
/* top edge kept clear so the sticky nav has something to sit against */
.photo-veil--top{
  background:
    linear-gradient(180deg,rgba(11,18,32,.55) 0%,rgba(11,18,32,.46) 30%,rgba(11,18,32,.86) 78%,var(--ink) 100%),
    radial-gradient(125% 80% at 50% 40%,rgba(11,18,32,0) 0%,rgba(11,18,32,.46) 64%,rgba(11,18,32,.9) 100%);
}

.has-photo{position:relative;overflow:hidden;isolation:isolate}
.has-photo > .wrap,.has-photo > .photo-content{position:relative;z-index:1}

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

.hero{position:relative;overflow:hidden;isolation:isolate}
.hero .photo-bg img,.hero .photo-bg video{filter:saturate(.4) contrast(1.02) brightness(.72)}
.hero .photo-bg::after{opacity:.55}
.hero-inner{position:relative;z-index:1;max-width:var(--wrap);margin:0 auto;padding:118px var(--gut) 104px;text-align:center}
.hero h1{margin:0 auto;max-width:860px}
.hero .lede{max-width:520px;color:#C0CEE3}

/* the three-up strip under the hero */
.strip{
  max-width:var(--wrap);margin:0 auto;
  display:grid;grid-template-columns:repeat(3,1fr);
  border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);
  font-family:var(--display);
  font-size:13px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--fg-muted);
}
.strip span{padding:20px;text-align:center}
.strip span + span{border-left:1px solid var(--line)}

/* --------------------------------------------------------------------------
   Client logo used as a heading
   The heading element stays, so the document outline is unchanged; the alt
   text carries the name for anything that cannot see the artwork.
   -------------------------------------------------------------------------- */

.client-logo{display:block;margin:0 auto}
.client-logo img{
  width:auto;height:clamp(38px,4.4vw,62px);
  margin:0 auto;
  /* the supplied lockup is white artwork, so it needs no recolouring */
  filter:drop-shadow(0 6px 22px rgba(0,0,0,.45));
}
.client-logo--lg img{height:clamp(44px,5vw,74px)}
.client-place{
  margin:20px 0 0;
  font-family:var(--display);
  font-size:13px;font-weight:500;
  letter-spacing:.18em;text-transform:uppercase;
  color:var(--fg-dim);
}

/* --------------------------------------------------------------------------
   Device showcase
   -------------------------------------------------------------------------- */

.devices{
  max-width:var(--wrap);margin:0 auto;
  display:flex;align-items:flex-end;justify-content:center;
  padding:96px var(--gut) 0;
  perspective:1800px;
}
.dev-phone{
  width:200px;flex:none;margin-right:-26px;z-index:2;
  transform:rotateY(26deg) rotateZ(-5deg) translateY(-14px);
  transform-origin:right bottom;
}
.dev-phone .screen{
  border:9px solid var(--ink-3);border-radius:30px;overflow:hidden;
  background:var(--ink-3);box-shadow:0 30px 70px rgba(0,0,0,.55);
}
.dev-phone img{width:100%;height:350px;object-fit:cover;object-position:top}

.dev-mac{width:660px;flex:none;z-index:3}
.dev-mac .screen{
  background:var(--ink-3);padding:11px 11px 0;border-radius:9px 9px 0 0;
  box-shadow:0 50px 90px rgba(0,0,0,.6);
}
.dev-mac img{width:100%;height:392px;object-fit:cover;object-position:top}
.dev-mac .chin{height:40px;background:var(--ink-3);border-radius:0 0 9px 9px}
.dev-mac .neck{
  width:150px;height:52px;margin:0 auto;
  background:linear-gradient(180deg,#4A5B75,#2A3A54);
  clip-path:polygon(20% 0,80% 0,100% 100%,0 100%);
}
.dev-mac .foot{width:232px;height:9px;margin:0 auto;background:#33445E;border-radius:2px}

.dev-tablet{
  width:330px;flex:none;margin-left:-26px;z-index:2;
  transform:rotateY(-26deg) rotateZ(5deg) translateY(-10px);
  transform-origin:left bottom;
}
.dev-tablet .screen{
  border:9px solid var(--ink-3);border-radius:16px;overflow:hidden;
  background:var(--ink-3);box-shadow:0 30px 70px rgba(0,0,0,.55);
}
.dev-tablet img{width:100%;height:250px;object-fit:cover;object-position:top}

.dev-caption{text-align:center;margin:14px 0 0;font-size:13px;color:var(--fg-dim)}

/* larger variant used on the projects page */
.devices--case .dev-phone{width:220px;margin-right:-30px;transform:rotateY(28deg) rotateZ(-6deg) translateY(-16px)}
.devices--case .dev-phone img{height:390px}
.devices--case .dev-mac{width:700px}
.devices--case .dev-mac img{height:420px}
.devices--case .dev-mac .chin{height:42px}
.devices--case .dev-mac .neck{width:160px;height:54px}
.devices--case .dev-mac .foot{width:246px}
.devices--case .dev-tablet{width:360px;margin-left:-30px;transform:rotateY(-28deg) rotateZ(6deg) translateY(-12px)}
.devices--case .dev-tablet img{height:270px}

/* --------------------------------------------------------------------------
   Service trio (home)
   -------------------------------------------------------------------------- */

.trio{display:grid;grid-template-columns:repeat(3,1fr);gap:48px;text-align:left}
.trio h3{font-size:22px;margin:0 0 12px}
.trio p{font-size:16px;line-height:1.75;color:var(--fg-muted)}
.trio svg{width:100%;height:auto;margin-bottom:26px}

/* hairline grid - a shared border rather than four floating cards */
.rule-grid{display:grid;gap:1px;background:rgba(255,255,255,.1)}
.rule-grid--4{grid-template-columns:repeat(4,1fr)}
.rule-grid--3{grid-template-columns:repeat(3,1fr)}
.rule-grid > div{background:var(--ink);padding:32px 28px}
.rule-grid h3{font-size:18px;margin:0 0 10px}
.rule-grid p{font-size:15px;line-height:1.7;color:var(--fg-muted)}

/* on a photo band the cells need to let the image through */
.has-photo .rule-grid{background:var(--line)}
.has-photo .rule-grid > div{background:rgba(11,18,32,.55);-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}

/* stat cells */
.stats{text-align:center}
.stats .fig{
  font-family:var(--display);font-size:clamp(28px,3.4vw,34px);font-weight:600;
  color:var(--accent-soft);margin:0 0 8px;line-height:1;
}
.stats .cap{font-size:14.5px;color:var(--fg-muted);margin:0}
.stats > div{padding:44px 30px}

/* --------------------------------------------------------------------------
   Split rows (services page)
   -------------------------------------------------------------------------- */

/* Each service is a full-bleed split: the photo runs off the outer edge of the
   screen while the copy stays on the text measure. The named grid lines do the
   work, so the photo never needs to escape its container with negative margins. */
.svc{position:relative;overflow:hidden;padding-block:clamp(44px,6vh,96px)}
.svc-grid{
  display:grid;
  align-items:center;
  grid-template-columns:
    [full-start] minmax(var(--gut),1fr)
    [content-start] minmax(0,calc((var(--wrap) - var(--gut) * 2) / 2))
    [mid] minmax(0,calc((var(--wrap) - var(--gut) * 2) / 2))
    [content-end] minmax(var(--gut),1fr)
    [full-end];
}
/* Both cells are pinned to row 1. On a flipped row the media's column starts
   before the copy's, and grid auto-placement never backtracks, so without
   this the photo drops to a second row underneath. */
.svc-copy,.svc-media{grid-row:1}
.svc-copy{grid-column:content-start/mid;padding-right:clamp(32px,4vw,80px)}
.svc-media{grid-column:mid/full-end}
.svc-grid--flip .svc-copy{grid-column:mid/content-end;padding-right:0;padding-left:clamp(32px,4vw,80px)}
.svc-grid--flip .svc-media{grid-column:full-start/mid}

.svc-copy h2{margin:0 0 24px}
.svc-copy .body-copy{margin:0 0 30px;font-size:16.5px;line-height:1.8}
.svc-copy .eyebrow{margin-bottom:16px}

/* the shadow behind the panel: a wide accent bloom bleeding off the same edge */
.svc::before{
  content:"";position:absolute;z-index:0;
  top:50%;right:-14%;width:62%;height:130%;
  transform:translateY(-50%);
  background:radial-gradient(50% 50% at 50% 50%,rgba(46,139,255,.17),rgba(46,139,255,.05) 55%,transparent 72%);
  pointer-events:none;
}
.svc--flip::before{right:auto;left:-14%}

.svc-media{
  position:relative;z-index:1;margin:0;
  min-height:min(76vh,720px);
  overflow:hidden;
}
.svc-media img{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;
  filter:saturate(.26) contrast(1.08) brightness(.68);
}
/* feathered inner edge, so the panel dissolves into the page rather than
   sitting on it as a hard rectangle */
.svc-media::after{
  content:"";position:absolute;inset:0;
  background:
    linear-gradient(90deg,var(--ink) 0%,rgba(11,18,32,.72) 10%,rgba(11,18,32,.22) 30%,transparent 58%),
    linear-gradient(180deg,rgba(11,18,32,.55),transparent 20%,transparent 80%,rgba(11,18,32,.55));
}
.svc-grid--flip .svc-media::after{
  background:
    linear-gradient(270deg,var(--ink) 0%,rgba(11,18,32,.72) 10%,rgba(11,18,32,.22) 30%,transparent 58%),
    linear-gradient(180deg,rgba(11,18,32,.55),transparent 20%,transparent 80%,rgba(11,18,32,.55));
}

/* an outlined numeral sunk into the feathered edge, closer to a watermark
   than a label - the eyebrow already names the step */
.svc-numeral{
  position:absolute;z-index:2;top:6%;left:3%;
  font-family:var(--display);font-weight:700;
  font-size:clamp(120px,15vw,260px);line-height:.8;
  letter-spacing:-.04em;
  color:transparent;
  -webkit-text-stroke:1px rgba(255,255,255,.10);
  pointer-events:none;
}
.svc-grid--flip .svc-numeral{left:auto;right:3%}

.tick-list{display:flex;flex-direction:column;gap:14px;font-size:15.5px;color:var(--fg)}
.tick-list li{padding-left:22px;position:relative}
/* a drawn rule rather than a dash character, since the brand copy avoids long dashes */
.tick-list li::before{content:"";position:absolute;left:0;top:.72em;width:10px;height:1.5px;background:var(--accent-soft)}

/* --------------------------------------------------------------------------
   Forms - open, underlined, never a giant rounded card
   -------------------------------------------------------------------------- */

.form{display:grid;grid-template-columns:1fr 1fr;gap:24px;text-align:left}
.form .full{grid-column:1/-1}
.field{display:flex;flex-direction:column;gap:8px;font-size:13px;color:var(--fg-muted)}
.field input,.field textarea,.field select{
  background:transparent;
  border:none;border-bottom:1px solid var(--line-strong);
  border-radius:0;
  color:var(--fg);
  font-family:inherit;font-size:15px;
  padding:9px 0;
  transition:border-color .2s ease;
}
.field textarea{
  border:1px solid var(--line-strong);
  padding:12px;resize:vertical;
}
.field input:focus,.field textarea:focus,.field select:focus{
  outline:none;border-color:var(--accent-soft);
}
.field input::placeholder,.field textarea::placeholder{color:#6B7B98}
.form-actions{grid-column:1/-1;display:flex;justify-content:center;margin-top:10px}

.form-note{
  grid-column:1/-1;text-align:center;
  font-size:13.5px;color:var(--fg-dim);margin-top:2px;
}

.form-status{
  grid-column:1/-1;text-align:center;
  font-size:14.5px;color:var(--accent-soft);
  min-height:1.2em;
}

.inline-contact{
  display:flex;justify-content:center;gap:36px;flex-wrap:wrap;
  font-size:15px;color:var(--fg-muted);
}

/* honeypot - visually gone, still reachable by bots */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.site-footer{border-top:1px solid var(--line)}
.footer-top{
  max-width:var(--wrap);margin:0 auto;
  padding:64px var(--gut);
  display:grid;grid-template-columns:2fr 1fr 1fr;gap:40px;
}
.site-footer img{height:26px;width:auto;margin-bottom:16px}
.site-footer p{font-size:14.5px;line-height:1.7;color:var(--fg-dim);max-width:320px}
.site-footer h3{
  font-family:var(--display);font-size:13px;font-weight:600;
  letter-spacing:.1em;text-transform:uppercase;color:var(--fg);
  margin:0 0 14px;
}
.site-footer ul{display:flex;flex-direction:column;gap:10px;font-size:14.5px}
.footer-base{
  border-top:1px solid rgba(255,255,255,.1);
  max-width:var(--wrap);margin:0 auto;
  padding:22px var(--gut);
  display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;
  font-size:13px;color:var(--fg-dim);
}
.footer-base p{margin:0;max-width:none}
.footer-base div{display:flex;gap:16px}

/* --------------------------------------------------------------------------
   Pricing
   -------------------------------------------------------------------------- */

.price-grid{display:grid;grid-template-columns:1.35fr 1fr;gap:1px;background:rgba(255,255,255,.1);text-align:left}
.price-cell{background:var(--ink);padding:44px 40px;display:flex;flex-direction:column}
.price-stack{display:grid;gap:1px;background:rgba(255,255,255,.1)}
.price-stack > div{background:var(--ink);padding:40px}
.price-figure{
  font-family:var(--display);font-size:clamp(30px,3.4vw,38px);font-weight:600;
  color:var(--fg);margin:14px 0 6px;line-height:1.1;letter-spacing:-.02em;
}
.price-unit{font-size:14px;color:var(--fg-dim);margin:0 0 22px}
.price-cell h3,.price-stack h3{font-size:20px;margin:0}
.price-cell .body-copy,.price-stack .body-copy{font-size:15.5px;line-height:1.75}
.price-cell .tick-list{margin-top:26px;font-size:15px}
.price-cell .btn{margin-top:32px;align-self:flex-start}

.faq{display:grid;gap:1px;background:rgba(255,255,255,.1);text-align:left}
.faq > div{background:var(--ink);padding:32px 34px}
.faq h3{font-size:18px;margin:0 0 10px}
.faq p{font-size:15.5px;line-height:1.75;color:var(--fg-muted)}

/* --------------------------------------------------------------------------
   Mobile call button
   Phone-only. The mascot sits on top of the button as though it is holding it,
   so the artwork has to overlap the pill rather than sit inside it.
   -------------------------------------------------------------------------- */

.call-fab{
  position:fixed;right:16px;bottom:18px;z-index:60;
  display:none;
  flex-direction:column;align-items:center;
  text-decoration:none;
  /* The entrance is a CSS animation rather than a JS-applied class. This is
     the main call-to-action on a phone: it must never depend on a script
     having run to become visible. */
  animation:fabIn .55s .45s cubic-bezier(.2,.8,.3,1) both;
}
@keyframes fabIn{
  from{opacity:0;transform:translateY(130%)}
  to{opacity:1;transform:none}
}
/* It must never sit over the open menu. Hidden via visibility, not opacity or
   transform, because the filled animation above would win over those. */
body.nav-open .call-fab{visibility:hidden;pointer-events:none}

.call-fab-avatar{
  display:block;width:76px;
  margin-bottom:-16px;
  filter:drop-shadow(0 10px 18px rgba(0,0,0,.55));
  animation:fabBob 3.6s ease-in-out infinite;
  pointer-events:none;
}
.call-fab-avatar img{width:100%;height:auto;display:block}

.call-fab-btn{
  display:flex;align-items:center;gap:9px;
  padding:13px 20px;
  background:var(--accent);color:var(--on-accent);
  font-family:var(--display);font-size:14.5px;font-weight:700;
  letter-spacing:.03em;
  box-shadow:0 12px 26px rgba(0,0,0,.5),0 0 0 1px rgba(255,255,255,.08) inset;
}
.call-fab-btn svg{width:17px;height:17px}
.call-fab:active .call-fab-btn{background:var(--accent-soft)}

@keyframes fabBob{0%,100%{transform:translateY(0) rotate(-3deg)}50%{transform:translateY(-7px) rotate(3deg)}}

@media (max-width:900px){
  .call-fab{display:flex}
  /* keep the footer clear of the button */
  .site-footer{padding-bottom:104px}
}

/* --------------------------------------------------------------------------
   Counting figures
   -------------------------------------------------------------------------- */

.tally{
  display:inline-block;
  font-variant-numeric:tabular-nums;
  /* the box is reserved before the count runs so nothing reflows as digits
     are added - the width is the settled value, not the starting one */
  min-width:1ch;
}

/* Cells lift and sharpen as the group arrives. Shared by the About stats and
   the pricing grid so both read as the same gesture. */
.count-in > *{
  position:relative;overflow:hidden;
  opacity:0;
  transform:translateY(26px) scale(.97);
  filter:blur(6px);
}
.js .count-in > *{
  transition:opacity .7s ease,transform .8s cubic-bezier(.2,.8,.3,1),filter .7s ease;
}
.count-in.is-in > *{opacity:1;transform:none;filter:none}
.count-in.is-in > *:nth-child(2){transition-delay:.13s}
.count-in.is-in > *:nth-child(3){transition-delay:.26s}
html:not(.js) .count-in > *{opacity:1;transform:none;filter:none}

/* a hairline sweeps across each cell as it lands */
.count-in > *::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:2px;
  background:linear-gradient(90deg,transparent,var(--accent),transparent);
  transform:scaleX(0);transform-origin:center;
}
.js .count-in.is-in > *::after{
  animation:statSweep 1.1s cubic-bezier(.5,0,.3,1) forwards;
}
.count-in.is-in > *:nth-child(2)::after{animation-delay:.13s}
.count-in.is-in > *:nth-child(3)::after{animation-delay:.26s}
@keyframes statSweep{
  0%{transform:scaleX(0);opacity:0}
  45%{transform:scaleX(1);opacity:1}
  100%{transform:scaleX(1);opacity:.25}
}

/* --------------------------------------------------------------------------
   Reveal on scroll
   -------------------------------------------------------------------------- */

.reveal{opacity:0;transform:translateY(18px)}
.js .reveal{transition:opacity .7s cubic-bezier(.2,.7,.3,1),transform .7s cubic-bezier(.2,.7,.3,1)}
.reveal.is-in{opacity:1;transform:none}
html:not(.js) .reveal{opacity:1;transform:none}

/* --------------------------------------------------------------------------
   Inline SVG diagram animation (home service trio)
   -------------------------------------------------------------------------- */

@keyframes ibDraw{to{stroke-dashoffset:0}}
@keyframes ibFlow{to{stroke-dashoffset:-40}}
@keyframes ibFloat{0%,100%{transform:translateY(0)}50%{transform:translateY(-7px)}}
@keyframes ibPulse{0%,100%{opacity:.3}50%{opacity:1}}
@keyframes ibFade{0%,15%{opacity:0}45%,100%{opacity:1}}
@keyframes ibRise{0%,100%{transform:scaleY(.4)}50%{transform:scaleY(1)}}

/* --------------------------------------------------------------------------
   Responsive
   -------------------------------------------------------------------------- */

/* Large desktops. At 1280 the content left ~320px dead either side of a 1920
   screen, so the measure widens in two steps rather than one big jump. */
@media (min-width:1500px){
  :root{--wrap:1400px;--gut:52px;--sp-l:150px;--sp-xl:184px}
  .lede{max-width:620px}
  .devices{padding-top:110px}
  .dev-mac{width:740px}
  .dev-mac img{height:440px}
  .dev-phone{width:224px}
  .dev-phone img{height:392px}
  .dev-tablet{width:370px}
  .dev-tablet img{height:280px}
  .devices--case .dev-mac{width:780px}
  .devices--case .dev-mac img{height:468px}
  .devices--case .dev-phone{width:246px}
  .devices--case .dev-phone img{height:436px}
  .devices--case .dev-tablet{width:402px}
  .devices--case .dev-tablet img{height:302px}
}

@media (min-width:1800px){
  :root{--wrap:1600px;--gut:64px}
  body{font-size:18px}
  .rule-grid > div{padding:40px 34px}
  .price-cell{padding:56px 48px}
  .price-stack > div{padding:48px}
}

@media (max-width:1080px){
  :root{--sp-l:104px;--sp-xl:120px;--gut:32px}
  .svc-media{min-height:min(64vh,560px)}
  .trio{gap:36px}
  /* The three devices sit side by side down to 901px, so they have to fit
     the narrowest case: 901 - 64 gutters, less the two 26px overlaps. */
  .devices{padding-top:72px}
  .dev-mac{width:460px}
  .dev-mac img{height:284px}
  .dev-phone{width:150px}
  .dev-phone img{height:262px}
  .dev-tablet{width:240px}
  .dev-tablet img{height:182px}
  .devices--case .dev-mac{width:470px}
  .devices--case .dev-mac img{height:288px}
  .devices--case .dev-phone{width:160px}
  .devices--case .dev-phone img{height:278px}
  .devices--case .dev-tablet{width:250px}
  .devices--case .dev-tablet img{height:188px}
  .rule-grid--4{grid-template-columns:repeat(2,1fr)}
}

@media (max-width:900px){
  .nav-links{display:none}
  .nav-toggle{display:flex}
  /* Stacked, the photo always leads and stays full-bleed; the flip only ever
     applied to the two-column arrangement. */
  .svc-grid,.svc-grid--flip{
    grid-template-columns:[full-start] var(--gut) [content-start] 1fr [content-end] var(--gut) [full-end];
    row-gap:clamp(34px,6vw,56px);
  }
  .svc-media,.svc-grid--flip .svc-media{grid-column:full-start/full-end;grid-row:1;min-height:0;aspect-ratio:16/10}
  .svc-copy,.svc-grid--flip .svc-copy{grid-column:content-start/content-end;grid-row:2;padding:0}
  .svc-media::after,.svc-grid--flip .svc-media::after{
    background:linear-gradient(180deg,rgba(11,18,32,.5),transparent 26%,transparent 66%,var(--ink));
  }
  .svc-numeral,.svc-grid--flip .svc-numeral{left:var(--gut);right:auto;top:4%;font-size:clamp(96px,22vw,180px)}
  .svc::before,.svc--flip::before{width:100%;right:-25%;left:auto;height:70%}
  .footer-top{grid-template-columns:1fr 1fr;gap:44px}
  .footer-top > div:first-child{grid-column:1/-1}
  .price-grid{grid-template-columns:1fr}
  .hero-inner{padding:88px var(--gut) 80px}

  /* Below the side-by-side threshold the devices stack rather than shrink
     into illegibility. The Mac leads, since it carries the main screen. */
  .devices{flex-direction:column;align-items:center;gap:48px;padding-top:56px}
  .dev-phone,.dev-tablet,
  .devices--case .dev-phone,.devices--case .dev-tablet{transform:none;margin:0}
  .dev-phone,.devices--case .dev-phone{width:min(230px,72vw)}
  .dev-tablet,.devices--case .dev-tablet{width:min(330px,86vw)}
  .dev-mac,.devices--case .dev-mac{width:100%;max-width:520px;order:-1}
  .dev-mac img,.devices--case .dev-mac img{height:auto;aspect-ratio:16/10}
  .dev-phone img,.devices--case .dev-phone img{height:auto;aspect-ratio:9/17}
  .dev-tablet img,.devices--case .dev-tablet img{height:auto;aspect-ratio:4/3}

  /* comfortable thumb targets - the phone number is the point of the site */
  .inline-contact a,.link-quiet,.link-rule,.drawer-contact a{
    display:inline-flex;align-items:center;min-height:44px;
  }
}

@media (max-width:760px){
  :root{--sp-m:64px;--sp-l:80px;--sp-xl:96px;--gut:24px}
  body{font-size:16px}
  .trio{grid-template-columns:1fr;gap:52px}
  .strip{grid-template-columns:1fr}
  .strip span + span{border-left:none;border-top:1px solid var(--line)}
  .rule-grid--4,.rule-grid--3{grid-template-columns:1fr}
  .form{grid-template-columns:1fr}
  .footer-top{grid-template-columns:1fr;gap:36px}
  .footer-base{flex-direction:column;gap:12px}
  .inline-contact{flex-direction:column;gap:12px;align-items:center}
  .price-cell{padding:36px 28px}
  .price-stack > div{padding:32px 28px}
  .faq > div{padding:28px 26px}
}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
  .reveal{opacity:1;transform:none}
}
