/* ============================================================
   Page components
   ============================================================ */

/* -------- hero -------- */
.hero{
  padding:168px 0 100px;
  position:relative;
  overflow:hidden;
}
.hero-grid{
  display:grid;
  grid-template-columns:1.05fr .95fr;
  gap:56px;
  align-items:center;
}
.hero h1{
  font-size:clamp(38px,5.4vw,64px);
  letter-spacing:-.02em;
}
.hero h1 em{
  font-style:normal;
  color:var(--blue-bright);
  background:linear-gradient(90deg,var(--blue-bright),var(--blue));
  -webkit-background-clip:text;
  background-clip:text;
  -webkit-text-fill-color:transparent;
}
.hero p.lead{
  margin-top:22px;
  font-size:18px;
  color:var(--text-muted);
  max-width:480px;
}
.hero-actions{
  display:flex;
  gap:14px;
  margin-top:34px;
  flex-wrap:wrap;
}
.hero-proof{
  display:flex;
  gap:28px;
  margin-top:48px;
  flex-wrap:wrap;
}
.hero-proof div{ font-family:var(--f-mono); }
.hero-proof strong{
  display:block;
  font-size:22px;
  font-family:var(--f-display);
  color:var(--text);
}
.hero-proof span{ font-size:12.5px; color:var(--text-faint); }

/* Hero entrance. CSS-only, so it survives a JS failure — and deliberately
   skips the h1: an element still at opacity:0 is not an LCP candidate, so
   fading the headline in would push Largest Contentful Paint back by the
   whole length of the animation. The headline paints immediately and the
   rest of the hero settles in around it. */
@keyframes hero-rise{
  from{ opacity:0; transform:translateY(16px); }
  to{ opacity:1; transform:none; }
}
.hero p.lead,
.hero .hero-actions,
.hero .hero-proof,
.hero .hero-visual{ animation:hero-rise 600ms var(--ease-out) both; }
.hero p.lead       { animation-delay: 50ms; }
.hero .hero-visual { animation-delay: 90ms; }
.hero .hero-actions{ animation-delay:130ms; }
.hero .hero-proof  { animation-delay:190ms; }

/* -------- hero: the finished-website preview — the signature element --------
   What stood here was a code editor typing itself out. It read well to anyone
   who has seen a terminal and to nobody else, which is the wrong audience for
   the first thing on the page: almost nobody hiring us writes code. This shows
   the thing being bought instead — a real business homepage, the same site on
   a phone, and a customer's enquiry landing on top of it.

   Everything inside is aria-hidden and the wrapper carries one role="img":
   a screen reader has no use for a fake nav bar, it needs the sentence. */
.site-demo{
  --demo-accent:var(--blue);
  position:relative;
  perspective:1500px;
  /* Both floating pieces live in a band BELOW the window and only kiss its
     bottom edge. They started out sitting on top of the card row, which
     buried exactly the prices and product names that make the mockup read as
     a real business — and the enquiry, tried at the top, clipped the URL,
     which is the trust signal the whole browser frame exists to carry. */
  padding:0 0 118px;
}

.demo-window{
  position:relative;
  z-index:1;
  border-radius:var(--radius);
  border:1px solid var(--line);
  background:var(--bg-elev);
  box-shadow:var(--shadow-card), 0 0 0 1px var(--blue-tint);
  overflow:hidden;
  /* Static. The editor this replaced floated on a 7s loop because it was the
     only thing here; three layered pieces already read as depth, and an
     infinite transform loop behind a scrolled-past hero keeps the compositor
     awake for the whole visit to say so twice. */
  transform:rotateY(-4deg) rotateX(1deg);
}
@media (prefers-reduced-motion: reduce){
  .demo-window{ transform:none; }
}

/* ---- browser chrome ---- */
.demo-bar{
  display:flex;
  align-items:center;
  gap:10px;
  padding:9px 12px;
  background:var(--bg-elev-2);
  border-bottom:1px solid var(--line);
}
.demo-bar .dots{ display:flex; gap:5px; flex:none; }
.demo-bar .dots i{ width:8px; height:8px; border-radius:50%; background:var(--line); display:block; }
.demo-url{
  flex:1;
  min-width:0;
  display:flex;
  align-items:center;
  gap:6px;
  padding:5px 11px;
  border-radius:999px;
  background:var(--bg);
  border:1px solid var(--line);
  font-family:var(--f-mono);
  font-size:11px;
  color:var(--text-faint);
}
/* the padlock is doing real work here — "a proper website, not a Facebook
   page" is half of what a small business is buying */
.demo-url svg{ width:11px; height:11px; flex:none; color:var(--green); }
.demo-url-text{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

/* ---- the site inside the window ---- */
.demo-nav{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:12px;
  padding:11px 14px;
  border-bottom:1px solid var(--line-soft);
}
.demo-logo{ display:flex; align-items:center; gap:8px; min-width:0; }
.demo-logo i{ width:18px; height:18px; border-radius:6px; flex:none; background:var(--demo-accent); }
.demo-logo b{
  font-family:var(--f-display);
  font-weight:600;
  font-size:12px;
  color:var(--text);
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
}
.demo-links{ display:flex; gap:8px; flex:none; }
.demo-links i{ width:20px; height:4px; border-radius:999px; background:var(--bg-elev-3); }

.demo-hero{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:5px;
  padding:20px 16px 19px;
  background:var(--bg-elev-2);
  background:linear-gradient(135deg,
    color-mix(in srgb, var(--demo-accent) 26%, var(--bg-elev-2)),
    var(--bg-elev-2) 74%);
}
.demo-kicker{
  font-family:var(--f-mono);
  font-size:9px;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--text-muted);
}
.demo-title{
  font-family:var(--f-display);
  font-weight:600;
  font-size:16px;
  line-height:1.15;
  letter-spacing:-.01em;
  color:var(--text);
}
.demo-sub{ font-size:11px; color:var(--text-muted); }
.demo-btn{
  margin-top:7px;
  padding:7px 15px;
  border-radius:999px;
  background:var(--demo-accent);
  color:#fff;
  font-size:11px;
  font-weight:600;
  box-shadow:0 6px 16px -7px var(--demo-accent);
}

.demo-cards{ display:grid; grid-template-columns:repeat(3,1fr); gap:8px; padding:13px 14px 16px; }
.demo-card{
  min-width:0;
  padding:8px 9px 9px;
  border:1px solid var(--line);
  border-radius:9px;
  background:var(--bg-elev);
}
.demo-card i{
  display:block;
  height:28px;
  border-radius:5px;
  margin-bottom:8px;
  background:var(--bg-elev-2);
  background:linear-gradient(135deg,
    color-mix(in srgb, var(--demo-accent) 20%, var(--bg-elev-2)),
    var(--bg-elev-2));
}
.demo-card b{
  display:block;
  font-size:10px;
  font-weight:600;
  color:var(--text);
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
}
.demo-card span{ font-family:var(--f-mono); font-size:9px; color:var(--text-faint); }

/* ---- the same site, on a phone ---- */
.demo-phone{
  position:absolute;
  z-index:2;
  left:6px;
  bottom:0;
  width:100px;
  padding:6px;
  border-radius:16px;
  border:1px solid var(--line);
  background:var(--bg-elev-2);
  box-shadow:var(--shadow-card);
}
.demo-phone-notch{
  display:block;
  width:26px; height:3px;
  margin:1px auto 5px;
  border-radius:999px;
  background:var(--line);
}
.demo-phone-screen{
  border-radius:11px;
  border:1px solid var(--line-soft);
  background:var(--bg-elev);
  overflow:hidden;
}
.demo-phone-top{
  display:flex; align-items:center; gap:5px;
  padding:6px 7px;
  border-bottom:1px solid var(--line-soft);
}
.demo-phone-top i{ width:9px; height:9px; border-radius:3px; background:var(--demo-accent); flex:none; }
.demo-phone-top b{ flex:1; height:3px; border-radius:999px; background:var(--bg-elev-3); }
.demo-phone-hero{
  display:flex; flex-direction:column; gap:5px;
  padding:10px 8px 11px;
  background:linear-gradient(135deg,
    color-mix(in srgb, var(--demo-accent) 26%, var(--bg-elev-2)),
    var(--bg-elev-2));
}
.demo-phone-hero i{ height:4px; width:78%; border-radius:999px; background:var(--text-faint); opacity:.55; }
.demo-phone-hero b{ height:9px; width:42px; border-radius:999px; background:var(--demo-accent); margin-top:2px; }
.demo-phone-list{ display:flex; flex-direction:column; gap:5px; padding:8px; }
.demo-phone-list i{ height:13px; border-radius:4px; background:var(--bg-elev-2); border:1px solid var(--line-soft); }

/* ---- the payoff: somebody is writing to you ---- */
/* Bottom-right, opposite the phone, overlapping the window by a few pixels so
   it reads as floating above it rather than parked underneath. */
.demo-ping{
  position:absolute;
  z-index:3;
  right:-10px;
  bottom:50px;
  display:flex;
  align-items:center;
  gap:11px;
  max-width:min(248px, 62%);
  padding:10px 14px 10px 11px;
  border-radius:13px;
  border:1px solid var(--line);
  background:var(--glass);
  -webkit-backdrop-filter:blur(12px);
  backdrop-filter:blur(12px);
  box-shadow:var(--shadow-pill);
}
.demo-ping-ico{
  width:30px; height:30px;
  flex:none;
  display:flex; align-items:center; justify-content:center;
  border-radius:10px;
  background:var(--blue-tint-2);
  color:var(--green);
}
.demo-ping-ico svg{ width:15px; height:15px; }
.demo-ping-body{ min-width:0; }
.demo-ping-body b{
  display:flex;
  align-items:center;
  gap:7px;
  font-size:11.5px;
  font-weight:600;
  color:var(--text);
}
.demo-ping-body b::before{
  content:"";
  width:6px; height:6px;
  flex:none;
  border-radius:50%;
  background:var(--green);
  box-shadow:0 0 0 3px var(--green-glow);
}
.demo-ping-msg{
  display:block;
  margin-top:2px;
  font-size:11px;
  line-height:1.45;
  color:var(--text-muted);
  display:-webkit-box;
  -webkit-line-clamp:2;
  -webkit-box-orient:vertical;
  overflow:hidden;
}

/* ---- entrance ----
   The hidden state hangs off .demo-anim, which only JS adds. Parking it on
   the elements themselves would mean a script that never loads leaves the
   hero's main visual sitting at opacity:0 — an empty frame where the whole
   pitch should be. */
.site-demo.demo-anim .demo-nav,
.site-demo.demo-anim .demo-hero > *,
.site-demo.demo-anim .demo-card,
.site-demo.demo-anim .demo-phone,
.site-demo.demo-anim .demo-ping{ opacity:0; }

.site-demo.demo-anim.is-live .demo-nav,
.site-demo.demo-anim.is-live .demo-hero > *,
.site-demo.demo-anim.is-live .demo-card{
  animation:demo-in 440ms var(--ease-out) both;
}
@keyframes demo-in{
  from{ opacity:0; transform:translateY(9px); }
  to  { opacity:1; transform:none; }
}
/* the site assembles top-down, the way someone would read it */
.site-demo.demo-anim.is-live .demo-nav             { animation-delay: 40ms; }
.site-demo.demo-anim.is-live .demo-kicker          { animation-delay:120ms; }
.site-demo.demo-anim.is-live .demo-title           { animation-delay:170ms; }
.site-demo.demo-anim.is-live .demo-sub             { animation-delay:220ms; }
.site-demo.demo-anim.is-live .demo-btn             { animation-delay:280ms; }
.site-demo.demo-anim.is-live .demo-card:nth-child(1){ animation-delay:340ms; }
.site-demo.demo-anim.is-live .demo-card:nth-child(2){ animation-delay:390ms; }
.site-demo.demo-anim.is-live .demo-card:nth-child(3){ animation-delay:440ms; }

/* these two arrive after the site has finished building, not alongside it —
   they are the consequence of it, and reading them in that order is the
   entire point of the animation */
.site-demo.demo-anim .demo-phone,
.site-demo.demo-anim .demo-ping{
  transform:translateY(12px);
  transition:opacity var(--t-slow) var(--ease-out), transform var(--t-slow) var(--ease-out);
}
.site-demo.demo-anim .demo-phone.is-in,
.site-demo.demo-anim .demo-ping.is-in{ opacity:1; transform:none; }

/* -------- trust / about -------- */
.trust-grid{
  display:grid;
  grid-template-columns:.9fr 1.1fr;
  gap:64px;
  align-items:start;
}
.trust-points{ display:grid; gap:28px; }
.trust-point{ display:flex; gap:16px; }
.trust-point .num{
  font-family:var(--f-mono);
  font-size:13px;
  color:var(--blue-bright);
  border:1px solid var(--blue-dim);
  background:var(--blue-tint);
  width:30px; height:30px;
  border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  flex-shrink:0;
}
.trust-point h4{ font-size:17px; margin-bottom:6px; }
.trust-point p{ color:var(--text-muted); font-size:14.5px; }

/* -------- cards: services -------- */
.card-grid{
  display:grid;
  grid-template-columns:repeat(3,1fr);
  gap:22px;
}
.service-card{
  background:var(--bg-elev);
  border:1px solid var(--line);
  border-radius:var(--radius);
  padding:30px 26px;
  transition:transform var(--t-base) var(--ease-snap),
             border-color var(--t-fast) linear,
             background var(--t-fast) linear;
}
.service-card:hover{
  transform:translateY(-6px);
  border-color:var(--blue-dim);
  background:var(--bg-elev-2);
}
.service-card .icon{
  width:44px; height:44px;
  border-radius:11px;
  background:var(--blue-tint-2);
  border:1px solid var(--blue-dim);
  display:flex; align-items:center; justify-content:center;
  margin-bottom:20px;
  color:var(--blue-bright);
}
.service-card h3{ font-size:19px; margin-bottom:10px; }
.service-card p{ color:var(--text-muted); font-size:14.5px; margin-bottom:16px; }
.service-card .price{
  font-family:var(--f-mono);
  font-size:13px;
  color:var(--text-faint);
  padding-top:14px;
  border-top:1px solid var(--line);
}
.service-card .price strong{ color:var(--blue-bright); font-size:14.5px; }

/* -------- process -------- */
.process-rail{
  position:relative;
  display:grid;
  grid-template-columns:repeat(5,1fr);
  gap:20px;
}
.process-rail::before{
  content:"";
  position:absolute;
  top:23px; left:0; right:0;
  height:1px;
  background:var(--line);
  z-index:0;
}
.process-step{ position:relative; z-index:1; }
.process-step .step-num{
  width:46px; height:46px;
  border-radius:50%;
  background:var(--bg-elev-2);
  border:1px solid var(--line);
  display:flex; align-items:center; justify-content:center;
  font-family:var(--f-mono);
  font-size:14px;
  color:var(--blue-bright);
  margin-bottom:20px;
  transition:border-color var(--t-fast) linear, background var(--t-fast) linear;
}
.process-step:hover .step-num{
  border-color:var(--blue);
  background:var(--blue-dim);
}
.process-step h4{ font-size:16px; margin-bottom:8px; }
.process-step p{ font-size:13.5px; color:var(--text-muted); }

/* -------- testimonials -------- */
.testi-track{
  display:grid;
  grid-template-columns:repeat(3,1fr);
  gap:22px;
}
.testi-card{
  background:var(--bg-elev);
  border:1px solid var(--line);
  border-radius:var(--radius);
  padding:28px 26px;
}
.testi-card .stars{ color:var(--blue-bright); font-size:13px; letter-spacing:2px; margin-bottom:16px; }
.testi-card p.quote{ font-size:15px; color:var(--text); line-height:1.7; margin-bottom:22px; }
.testi-person{ display:flex; align-items:center; gap:12px; }
.testi-avatar{
  width:38px; height:38px; border-radius:50%;
  background:linear-gradient(135deg,var(--blue),#7CA6FF);
  display:flex; align-items:center; justify-content:center;
  font-family:var(--f-display); font-size:14px; color:#fff; font-weight:600;
}
.testi-person strong{ display:block; font-size:14px; }
.testi-person span{ font-size:12.5px; color:var(--text-faint); }
.testi-note{
  margin-top:20px;
  font-family:var(--f-mono);
  font-size:12px;
  color:var(--text-faint);
}

/* -------- pricing -------- */
.pricing-grid{
  display:grid;
  grid-template-columns:repeat(3,1fr);
  gap:22px;
  align-items:stretch;
}
.price-card{
  background:var(--bg-elev);
  border:1px solid var(--line);
  border-radius:var(--radius);
  padding:32px 28px;
  display:flex;
  flex-direction:column;
  transition:transform var(--t-base) var(--ease-snap), border-color var(--t-fast) linear;
}
.price-card:hover{ transform:translateY(-6px); }
.price-card.featured{
  border-color:var(--blue);
  background:linear-gradient(180deg,var(--blue-tint),var(--bg-elev) 40%);
  position:relative;
}
.price-card.featured::before{
  content:"Most picked";
  position:absolute; top:-13px; left:28px;
  font-family:var(--f-mono);
  font-size:11px;
  background:var(--blue);
  color:#fff;
  padding:5px 12px;
  border-radius:999px;
}
.price-card h3{ font-size:18px; margin-bottom:6px; }
.price-card .tagline{ color:var(--text-muted); font-size:13.5px; margin-bottom:22px; }
.price-card .amount{
  font-family:var(--f-display);
  font-size:38px;
  color:var(--text);
  margin-bottom:4px;
}
.price-card .amount span{ font-size:14px; color:var(--text-faint); font-family:var(--f-mono); }
/* 38px was sized for "NPR 18,000". Prices are quoted per project rather than
   published now, so this line carries a phrase, and a phrase at 38px wraps to
   three lines in a 340px card. */
.price-card .amount--text{ font-size:22px; letter-spacing:-.005em; }
.price-card .amount-note{ font-size:12.5px; color:var(--text-faint); margin-bottom:26px; font-family:var(--f-mono); }
.price-card ul{ display:grid; gap:12px; margin-bottom:28px; flex:1; }
.price-card li{
  display:flex; gap:10px; align-items:flex-start;
  font-size:14px; color:var(--text-muted);
}
.price-card li svg{ flex-shrink:0; margin-top:3px; color:var(--green); }

/* -------- portfolio -------- */
.portfolio-filters{
  display:flex; gap:10px; margin-bottom:36px; flex-wrap:wrap;
}
.filter-btn{
  font-family:var(--f-mono);
  font-size:12.5px;
  padding:8px 16px;
  border-radius:999px;
  border:1px solid var(--line);
  background:transparent;
  color:var(--text-muted);
  cursor:pointer;
  transition:color var(--t-fast) linear,
             border-color var(--t-fast) linear,
             background var(--t-fast) linear;
}
.filter-btn:hover{ color:var(--text); border-color:var(--blue-dim); }
.filter-btn.active{ background:var(--blue); border-color:var(--blue); color:#fff; }

.portfolio-grid{
  display:grid;
  grid-template-columns:repeat(2,1fr);
  gap:24px;
}
.portfolio-item{
  border-radius:var(--radius);
  overflow:hidden;
  border:1px solid var(--line);
  background:var(--bg-elev);
  transition:transform var(--t-base) var(--ease-snap), border-color var(--t-fast) linear;
}
.portfolio-item:hover{ transform:translateY(-6px); border-color:var(--blue-dim); }
.portfolio-thumb{
  aspect-ratio:16/10;
  position:relative;
  overflow:hidden;
  background:
    linear-gradient(135deg, var(--bg-elev-2), var(--bg-elev-3));
}
.portfolio-thumb::before{
  content:"";
  position:absolute; inset:0;
  background-image:
    linear-gradient(var(--line) 1px, transparent 1px),
    linear-gradient(90deg, var(--line) 1px, transparent 1px);
  background-size:24px 24px;
  opacity:.35;
}
.portfolio-thumb .mono-tag{
  position:absolute; top:14px; left:14px;
  font-family:var(--f-mono); font-size:11px;
  background:var(--glass-strong);
  border:1px solid var(--line);
  padding:5px 10px; border-radius:999px;
  color:var(--text-muted);
}
.portfolio-thumb .glyph{
  position:absolute; inset:0;
  display:flex; align-items:center; justify-content:center;
  font-family:var(--f-display); font-weight:600;
  font-size:15px; color:var(--text-faint);
  letter-spacing:.04em;
}
.portfolio-body{ padding:20px 22px 24px; }
.portfolio-body h3{ font-size:17px; margin-bottom:6px; }
.portfolio-body p{ font-size:13.5px; color:var(--text-muted); margin-bottom:14px; }
.portfolio-tags{ display:flex; gap:8px; flex-wrap:wrap; }
.portfolio-tags span{
  font-family:var(--f-mono); font-size:11px;
  color:var(--text-faint);
  border:1px solid var(--line);
  padding:3px 9px; border-radius:999px;
}

/* -------- contact -------- */
.contact-grid{
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:56px;
  align-items:start;
}
.contact-form{
  display:grid;
  gap:18px;
}
.field{ display:grid; gap:8px; }
.field label{
  font-family:var(--f-mono);
  font-size:12px;
  color:var(--text-faint);
}
.field input, .field textarea, .field select{
  background:var(--bg-elev);
  border:1px solid var(--line);
  border-radius:var(--radius-sm);
  padding:13px 15px;
  color:var(--text);
  font-family:var(--f-body);
  font-size:14.5px;
  transition:border-color var(--t-fast) linear, box-shadow var(--t-fast) linear;
  width:100%;
}
.field textarea{ resize:vertical; min-height:120px; }
.field input:focus, .field textarea:focus, .field select:focus{
  outline:none;
  border-color:var(--blue);
  box-shadow:0 0 0 3px var(--blue-glow);
}
.field-row{ display:grid; grid-template-columns:1fr 1fr; gap:18px; }

.contact-direct{
  background:var(--bg-elev);
  border:1px solid var(--line);
  border-radius:var(--radius);
  padding:30px;
}
.contact-direct .pill{ margin-bottom:20px; }
.contact-direct h3{ font-size:22px; margin-bottom:10px; }
.contact-direct p{ color:var(--text-muted); font-size:14.5px; margin-bottom:26px; }
.contact-channels{ display:grid; gap:12px; }
.channel{
  display:flex; align-items:center; gap:14px;
  padding:14px 16px;
  border:1px solid var(--line);
  border-radius:var(--radius-sm);
  transition:border-color var(--t-fast) linear,
             transform var(--t-base) var(--ease-snap),
             background var(--t-fast) linear;
}
.channel:hover{ border-color:var(--blue-dim); transform:translateX(4px); background:var(--bg-elev-2); }
.channel .ico{
  width:38px; height:38px; border-radius:10px;
  background:var(--blue-tint-2);
  display:flex; align-items:center; justify-content:center;
  color:var(--blue-bright);
  flex-shrink:0;
}
.channel strong{ display:block; font-size:14.5px; }
.channel span{ font-size:12.5px; color:var(--text-faint); }

.form-status{
  font-family:var(--f-mono);
  font-size:13px;
  color:var(--green);
  display:none;
  align-items:center;
  gap:8px;
}
.form-status.is-shown{ display:flex; }

/* -------- generic CTA band -------- */
.cta-band{
  border:1px solid var(--line);
  background:linear-gradient(135deg, var(--blue-tint-2), var(--bg-elev));
  border-radius:20px;
  padding:56px var(--pad);
  text-align:center;
  position:relative;
  overflow:hidden;
}
.cta-band h2{ font-size:clamp(26px,3.6vw,38px); margin-bottom:14px; }
.cta-band p{ color:var(--text-muted); margin-bottom:30px; }
.cta-band .actions{ display:flex; gap:14px; justify-content:center; flex-wrap:wrap; }

/* -------- page hero (inner pages) -------- */
.page-hero{
  padding:160px 0 70px;
}
.page-hero h1{ font-size:clamp(32px,5vw,50px); max-width:680px; }
.page-hero p.lead{ margin-top:18px; color:var(--text-muted); font-size:17px; max-width:560px; }

/* ================= RESPONSIVE ================= */
@media (max-width:1000px){
  .hero-grid{ grid-template-columns:1fr; }
  .hero-visual{ order:-1; }
  .trust-grid{ grid-template-columns:1fr; gap:40px; }
  .card-grid{ grid-template-columns:repeat(2,1fr); }
  .process-rail{ grid-template-columns:repeat(3,1fr); row-gap:36px; }
  .process-rail::before{ display:none; }
  .testi-track{ grid-template-columns:1fr; }
  .pricing-grid{ grid-template-columns:1fr; max-width:420px; margin:0 auto; }
  .portfolio-grid{ grid-template-columns:1fr; }
  .contact-grid{ grid-template-columns:1fr; }
  .footer-top{ flex-direction:column; }
}
@media (max-width:640px){
  .card-grid{ grid-template-columns:1fr; }
  .process-rail{ grid-template-columns:1fr 1fr; }
  .field-row{ grid-template-columns:1fr; }
  .hero{ padding:140px 0 70px; }
  .section{ padding:72px 0; }
  /* the phone is the first thing to go: on an actual phone it is both the
     most cramped element and the least informative one, while the enquiry
     card is the half that still lands */
  .site-demo{ padding:0 0 64px; }
  .demo-phone{ display:none; }
  .demo-ping{ right:0; bottom:12px; max-width:none; }
  .demo-title{ font-size:15px; }
  .demo-cards{ gap:6px; padding:12px 12px 14px; }
}

/* ============================================================
   Added components & fixes
   ============================================================ */

/* -------- portfolio: filter behaviour -------- */
.filter-btn{ display:inline-flex; align-items:center; gap:8px; }
.filter-btn:disabled{ opacity:.4; cursor:not-allowed; }
.filter-count{
  font-size:10.5px;
  line-height:1;
  padding:3px 6px;
  border-radius:999px;
  background:var(--bg-elev-2);
  color:var(--text-faint);
  transition:background var(--t-fast) linear, color var(--t-fast) linear;
}
.filter-btn.active .filter-count{ background:rgba(255,255,255,.18); color:#fff; }

.portfolio-item.is-filtered{ display:none; }
.portfolio-grid.is-refiltered > .portfolio-item:not(.is-filtered){
  animation:card-in 320ms var(--ease-out) both;
}
@keyframes card-in{
  from{ opacity:0; transform:translateY(14px) scale(.985); }
  to{ opacity:1; transform:none; }
}
.portfolio-empty{
  border:1px dashed var(--line);
  border-radius:var(--radius);
  padding:44px 24px;
  text-align:center;
  color:var(--text-muted);
  font-size:14.5px;
}

/* -------- portfolio: browser-mockup thumbnail -------- */
.portfolio-item{ --accent:var(--blue); position:relative; display:flex; flex-direction:column; }
.portfolio-thumb .mock{
  position:absolute;
  inset:14px 14px 0;
  top:44px;
  border-radius:9px 9px 0 0;
  background:var(--bg-elev);
  border:1px solid var(--line);
  border-bottom:none;
  overflow:hidden;
  transition:transform var(--t-base) var(--ease-snap);
}
.portfolio-item:hover .mock{ transform:translateY(-5px); }
.mock-bar{
  display:flex; align-items:center; gap:5px;
  padding:8px 10px;
  background:var(--bg-elev-2);
  border-bottom:1px solid var(--line);
}
.mock-bar i{ width:6px; height:6px; border-radius:50%; background:var(--line); }
.mock-bar span{
  flex:1; height:8px; margin-left:8px;
  border-radius:999px; background:var(--bg-elev-3);
}
.mock-body{ padding:14px 14px 0; }
.mock-hero{
  border-radius:6px;
  background:var(--bg-elev-3);
  background:linear-gradient(135deg, color-mix(in srgb, var(--accent) 34%, var(--bg-elev-3)), var(--bg-elev-3));
  padding:14px 12px;
  display:flex; flex-direction:column; gap:8px;
  margin-bottom:10px;
}
.mock-title{
  font-family:var(--f-display);
  font-size:11px;
  font-weight:600;
  letter-spacing:.08em;
  color:var(--text);
}
.mock-btn{ width:46px; height:11px; border-radius:999px; background:var(--accent); }
.mock-row{ display:flex; gap:7px; margin-bottom:10px; }
.mock-row i{ flex:1; height:22px; border-radius:5px; background:var(--bg-elev-2); border:1px solid var(--line); }
.mock-lines{ display:flex; flex-direction:column; gap:5px; }
.mock-lines b{ display:block; height:5px; border-radius:999px; background:var(--bg-elev-3); }

/* the "view details" affordance */
.portfolio-open{
  position:absolute;
  inset:0;
  width:100%;
  border:none;
  background:linear-gradient(180deg, var(--scrim-0) 45%, var(--scrim));
  color:var(--text);
  font-family:var(--f-mono);
  font-size:12.5px;
  display:flex;
  align-items:flex-end;
  justify-content:center;
  padding-bottom:18px;
  cursor:pointer;
  opacity:0;
  transition:opacity var(--t-fast) linear;
  z-index:2;
}
.portfolio-item:hover .portfolio-open,
.portfolio-open:focus-visible{ opacity:1; }
@media (hover:none){ .portfolio-open{ opacity:1; } }

/* -------- modal -------- */
.modal{
  position:fixed; inset:0;
  z-index:150;
  display:flex;
  align-items:center;
  justify-content:center;
  padding:24px;
  opacity:0;
  visibility:hidden;
  transition:opacity var(--t-base) var(--ease), visibility 0s linear var(--t-base);
}
.modal.is-open{
  opacity:1; visibility:visible;
  transition:opacity var(--t-base) var(--ease), visibility 0s linear 0s;
}
.modal-backdrop{
  position:absolute; inset:0;
  background:var(--backdrop);
  -webkit-backdrop-filter:blur(4px);
  backdrop-filter:blur(4px);
  border:none;
  cursor:pointer;
}
.modal-dialog{
  position:relative;
  width:min(640px,100%);
  max-height:min(86vh,760px);
  overflow-y:auto;
  background:var(--bg-elev);
  border:1px solid var(--line);
  border-radius:18px;
  box-shadow:var(--shadow-modal);
  transform:translateY(16px) scale(.98);
  will-change:transform;
  transition:transform var(--t-slow) var(--ease-out);
}
.modal.is-open .modal-dialog{ transform:none; }
.modal-close{
  position:absolute; top:14px; right:14px;
  width:36px; height:36px;
  display:flex; align-items:center; justify-content:center;
  border-radius:50%;
  background:var(--glass-strong);
  border:1px solid var(--line);
  color:var(--text-muted);
  cursor:pointer;
  z-index:3;
  transition:color var(--t-fast) linear, border-color var(--t-fast) linear;
}
.modal-close:hover{ color:var(--text); border-color:var(--blue-dim); }
.modal-thumb{
  height:132px;
  border-radius:18px 18px 0 0;
  background:linear-gradient(135deg,var(--bg-elev-2),var(--bg-elev-3));
  border-bottom:1px solid var(--line);
  display:flex; align-items:center; justify-content:center;
  position:relative;
  overflow:hidden;
}
.modal-thumb::before{
  content:"";
  position:absolute; inset:0;
  background-image:
    linear-gradient(var(--line) 1px, transparent 1px),
    linear-gradient(90deg, var(--line) 1px, transparent 1px);
  background-size:24px 24px;
  opacity:.35;
}
.modal-thumb .glyph{
  position:relative;
  font-family:var(--f-display); font-weight:600;
  font-size:16px; letter-spacing:.06em;
  color:var(--text-muted);
}
.modal-content{ padding:26px 30px 30px; }
.modal-title{ font-size:24px; margin:6px 0 12px; }
.modal-summary{ color:var(--text-muted); font-size:15px; }
.modal-facts{
  display:grid;
  grid-template-columns:auto 1fr;
  gap:10px 20px;
  margin:24px 0;
  padding:20px 0;
  border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);
  font-size:14px;
}
.modal-facts dt{ font-family:var(--f-mono); font-size:12px; color:var(--text-faint); }
.modal-facts dd{ margin:0; color:var(--text); }
.modal-content h4{
  font-family:var(--f-mono);
  font-size:12px;
  font-weight:500;
  color:var(--text-faint);
  letter-spacing:.02em;
  margin-bottom:14px;
}
.modal-features{ display:grid; gap:10px; margin-bottom:28px; }
.modal-features li{
  position:relative;
  padding-left:22px;
  font-size:14px;
  color:var(--text-muted);
}
.modal-features li::before{
  content:"";
  position:absolute; left:0; top:7px;
  width:9px; height:9px;
  border-radius:2px;
  background:var(--blue-dim);
  border:1px solid var(--blue);
}
@media (max-width:640px){
  .modal{ padding:0; align-items:flex-end; }
  .modal-dialog{ max-height:92vh; border-radius:18px 18px 0 0; }
  .modal-thumb{ border-radius:18px 18px 0 0; height:104px; }
  .modal-content{ padding:22px 22px 28px; }
}

/* -------- quote estimator -------- */
.estimator{
  display:grid;
  grid-template-columns:1.15fr .85fr;
  gap:28px;
  align-items:start;
}
.est-panel{
  background:var(--bg-elev);
  border:1px solid var(--line);
  border-radius:var(--radius);
  padding:30px 28px;
}
.est-group{ margin:0 0 28px; border:none; padding:0; }
.est-group:last-child{ margin-bottom:0; }
.est-group > legend, .est-label{
  font-family:var(--f-mono);
  font-size:12px;
  color:var(--text-faint);
  margin-bottom:14px;
  padding:0;
  display:block;
}

.est-options{ display:grid; grid-template-columns:repeat(2,1fr); gap:10px; }
.est-option{ position:relative; display:block; }
.est-option input{
  position:absolute;
  opacity:0;
  inset:0;
  width:100%; height:100%;
  margin:0;
  cursor:pointer;
}
.est-option span{
  display:flex;
  flex-direction:column;
  gap:3px;
  padding:13px 15px;
  border:1px solid var(--line);
  border-radius:var(--radius-sm);
  font-size:14px;
  color:var(--text-muted);
  transition:border-color var(--t-fast) linear,
             background var(--t-fast) linear,
             color var(--t-fast) linear;
  pointer-events:none;
}
.est-option span em{
  font-style:normal;
  font-family:var(--f-mono);
  font-size:11.5px;
  color:var(--text-faint);
}
.est-option input:hover + span{ border-color:var(--blue-dim); }
.est-option input:checked + span{
  border-color:var(--blue);
  background:var(--blue-tint-2);
  color:var(--text);
}
.est-option input:checked + span em{ color:var(--blue-bright); }
.est-option input:focus-visible + span{ outline:2px solid var(--blue-bright); outline-offset:3px; }

.est-range{ display:flex; align-items:center; gap:14px; }
.est-range input[type="range"]{
  flex:1;
  -webkit-appearance:none;
  appearance:none;
  height:4px;
  border-radius:999px;
  background:var(--bg-elev-3);
  cursor:pointer;
}
.est-range input[type="range"]::-webkit-slider-thumb{
  -webkit-appearance:none;
  appearance:none;
  width:18px; height:18px;
  border-radius:50%;
  background:var(--blue);
  border:2px solid var(--bg-elev);
  box-shadow:0 0 0 3px var(--blue-glow);
}
.est-range input[type="range"]::-moz-range-thumb{
  width:16px; height:16px;
  border-radius:50%;
  background:var(--blue);
  border:2px solid var(--bg-elev);
}
.est-range output{
  font-family:var(--f-mono);
  font-size:13px;
  color:var(--blue-bright);
  min-width:74px;
  text-align:right;
}

.est-checks{ display:grid; grid-template-columns:repeat(2,1fr); gap:10px; }
.est-check{ display:flex; align-items:flex-start; gap:10px; cursor:pointer; font-size:14px; color:var(--text-muted); }
.est-check input{
  appearance:none;
  -webkit-appearance:none;
  width:18px; height:18px;
  flex-shrink:0;
  margin:2px 0 0;
  border:1px solid var(--line);
  border-radius:5px;
  background:var(--bg-elev-2);
  cursor:pointer;
  position:relative;
  transition:background var(--t-fast) linear, border-color var(--t-fast) linear;
}
.est-check input:checked{ background:var(--blue); border-color:var(--blue); }
.est-check input:checked::after{
  content:"";
  position:absolute;
  left:5px; top:1px;
  width:5px; height:10px;
  border:solid #fff;
  border-width:0 2px 2px 0;
  transform:rotate(42deg);
}
.est-check em{ display:block; font-style:normal; font-family:var(--f-mono); font-size:11.5px; color:var(--text-faint); }

.est-summary{
  background:linear-gradient(180deg,var(--blue-tint-2),var(--bg-elev) 42%);
  border:1px solid var(--blue-dim);
  border-radius:var(--radius);
  padding:28px 26px;
  position:sticky;
  top:110px;
}
/* Sized for a price, this was 38px. It carries the project name now —
   "E-commerce store" at 38px runs past the panel. */
.est-summary .est-amount{
  font-family:var(--f-display);
  font-size:clamp(22px,3vw,28px);
  line-height:1.1;
  margin-bottom:6px;
}
.est-summary .est-time{
  font-family:var(--f-mono);
  font-size:12.5px;
  color:var(--blue-bright);
  margin-bottom:22px;
}
.est-lines{
  display:grid; gap:9px;
  padding:18px 0;
  border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);
  margin-bottom:18px;
}
.est-lines li{ display:flex; justify-content:space-between; gap:14px; font-size:13px; color:var(--text-muted); }
.est-lines li em{ font-style:normal; font-family:var(--f-mono); color:var(--text); white-space:nowrap; }
.est-note{ font-size:12.5px; color:var(--text-faint); line-height:1.6; margin-bottom:20px; }
@media (max-width:1000px){
  .estimator{ grid-template-columns:1fr; }
  .est-summary{ position:static; }
}
@media (max-width:560px){
  .est-options, .est-checks{ grid-template-columns:1fr; }
}

/* -------- FAQ -------- */
.faq-list{ display:grid; gap:12px; max-width:780px; }
.faq-item{
  background:var(--bg-elev);
  border:1px solid var(--line);
  border-radius:var(--radius-sm);
  transition:border-color var(--t-fast) linear;
}
.faq-item[open]{ border-color:var(--blue-dim); }
.faq-item summary{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:16px;
  padding:18px 22px;
  cursor:pointer;
  font-family:var(--f-display);
  font-size:16px;
  font-weight:600;
  list-style:none;
}
.faq-item summary::-webkit-details-marker{ display:none; }
.faq-item summary::after{
  content:"";
  width:9px; height:9px;
  flex-shrink:0;
  border-right:2px solid var(--blue-bright);
  border-bottom:2px solid var(--blue-bright);
  transform:rotate(45deg) translateY(-2px);
  transition:transform var(--t-base) var(--ease-snap);
}
.faq-item[open] summary::after{ transform:rotate(-135deg) translateY(2px); }
.faq-item p{
  padding:0 22px 20px;
  color:var(--text-muted);
  font-size:14.5px;
}

/* -------- form: validation, status, honeypot -------- */
.field-error{
  font-family:var(--f-mono);
  font-size:12px;
  color:var(--red-text);
  margin:0;
}
.field.has-error input, .field.has-error textarea, .field.has-error select{
  border-color:var(--red);
}
.field.has-error input:focus, .field.has-error textarea:focus{
  box-shadow:0 0 0 3px var(--red-glow);
}
.field-hint{ font-family:var(--f-mono); font-size:11.5px; color:var(--text-faint); }
.hp-field{
  position:absolute !important;
  left:-9999px;
  width:1px; height:1px;
  overflow:hidden;
}

.form-status{
  display:none;
  flex-direction:column;
  align-items:flex-start;
  gap:10px;
  font-size:13.5px;
  line-height:1.6;
  padding:14px 16px;
  border-radius:var(--radius-sm);
  border:1px solid var(--line);
  border-left-width:3px;
  background:var(--bg-elev);
  color:var(--text-muted);
  font-family:var(--f-body);
}
.form-status.is-shown{ display:flex; }
.form-status--ok{ border-left-color:var(--green); color:var(--text); }
.form-status--error{ border-left-color:var(--red); color:var(--text); }
.form-status--pending{ border-left-color:var(--blue); }
.form-status-actions{ display:flex; gap:18px; flex-wrap:wrap; }

.btn.is-busy{ opacity:.75; cursor:progress; }
.btn.is-busy::after{
  content:"";
  width:14px; height:14px;
  border-radius:50%;
  border:2px solid rgba(255,255,255,.35);
  border-top-color:#fff;
  animation:spin .7s linear infinite;
}
@keyframes spin{ to{ transform:rotate(360deg); } }
.btn:disabled{ cursor:not-allowed; }

/* -------- copy button on contact channels -------- */
.channel{ position:relative; }
.copy-btn{
  margin-left:auto;
  flex-shrink:0;
  width:34px; height:34px;
  display:flex; align-items:center; justify-content:center;
  border-radius:8px;
  border:1px solid var(--line);
  background:var(--bg-elev-2);
  color:var(--text-faint);
  cursor:pointer;
  transition:color var(--t-fast) linear, border-color var(--t-fast) linear;
}
.copy-btn:hover{ color:var(--blue-bright); border-color:var(--blue-dim); }
.copy-btn.is-copied{ color:var(--green); border-color:var(--green); }

/* -------- contact meta strip -------- */
/* Two facts to a row, and the studio list across the top of both. A third of
   this card is ~130px, which is narrower than "Bhaktapur, Kathmandu Valley"
   and broke each studio over three lines. */
.contact-meta{
  display:grid;
  grid-template-columns:repeat(2,1fr);
  gap:18px;
  margin-top:26px;
  padding-top:24px;
  border-top:1px solid var(--line);
}
.contact-meta div{ font-family:var(--f-mono); font-size:12.5px; color:var(--text-faint); }
.contact-meta strong{ display:block; font-family:var(--f-body); font-size:14px; color:var(--text); margin-bottom:3px; }
.contact-meta .meta-studios{ grid-column:1 / -1; }
/* One studio per line. js writes these rows from config.locations; the markup
   ships a single comma-separated fallback line, which this leaves alone. */
.contact-meta .studio{ display:block; }
.contact-meta .studio + .studio{ margin-top:2px; }
.contact-meta .studio-area{ margin-top:6px; color:var(--text-muted); }
@media (max-width:560px){ .contact-meta{ grid-template-columns:1fr; gap:14px; } }

/* -------- 404 -------- */
.error-page{ padding:180px 0 120px; text-align:center; }
.error-code{
  font-family:var(--f-mono);
  font-size:clamp(64px,14vw,132px);
  line-height:1;
  color:var(--blue-dim);
  margin-bottom:8px;
}
.error-page h1{ font-size:clamp(26px,4vw,38px); margin-bottom:14px; }
.error-page p{ color:var(--text-muted); max-width:460px; margin:0 auto 30px; }
.error-page .hero-actions{ justify-content:center; }

/* ============================================================
   PAGE SWIPE — sideways navigation across the four pages
   Home -> Services -> Portfolio -> Contact. Swipe right-to-left
   moves forward, left-to-right moves back. js/script.js writes
   [data-nav-dir] onto <html> before the navigation, and the head
   snippet on every page re-applies it before first paint so the
   incoming half of the slide starts in the right place.
   ============================================================ */

/* Where cross-document view transitions exist the browser snapshots both
   documents, so the two halves of the slide meet with no unload gap. Nothing
   else on the page has to know it happened. */
@view-transition{ navigation:auto; }

/* A two-finger horizontal flick is the desktop half of this gesture, and
   Chromium reads that same flick as its own back/forward swipe. Containing
   the overscroll keeps the page from being navigated twice. */
html{ overscroll-behavior-x:contain; }

::view-transition-old(root),
::view-transition-new(root){
  animation-duration:var(--t-page);
  animation-timing-function:var(--ease-out);
  /* the cross-fade default is plus-lighter — two dark navy pages stacked
     under it wash out to grey mid-slide. these pages travel, they do not
     blend, so the layers stay opaque. */
  mix-blend-mode:normal;
}

/* The outgoing page drifts a fraction of the distance the incoming one
   covers. That parallax is what makes the new page read as arriving on top
   rather than the two sliding as one strip. */
html[data-nav-dir="fwd"]::view-transition-old(root){ animation-name:pt-out-left; }
html[data-nav-dir="fwd"]::view-transition-new(root){ animation-name:pt-in-right; }
html[data-nav-dir="back"]::view-transition-old(root){ animation-name:pt-out-right; }
html[data-nav-dir="back"]::view-transition-new(root){ animation-name:pt-in-left; }

@keyframes pt-out-left { to  { transform:translateX(-24%); opacity:.35; } }
@keyframes pt-in-right { from{ transform:translateX(100%); } }
@keyframes pt-out-right{ to  { transform:translateX(24%);  opacity:.35; } }
@keyframes pt-in-left  { from{ transform:translateX(-100%); } }

/* ---- fallback for engines without cross-document view transitions ----
   Same shape, done by hand: the page animates out, the navigation fires on
   the animation's end, and the next document animates in from the far side.
   body carries the transform so the fixed navbar travels with the page. */
html.pt-exit body,
html.pt-enter body{
  animation-duration:var(--t-page);
  animation-fill-mode:both;
  animation-timing-function:var(--ease-out);
}
html.pt-exit[data-nav-dir="fwd"]  body{ animation-name:pt-out-left;  }
html.pt-exit[data-nav-dir="back"] body{ animation-name:pt-out-right; }
html.pt-enter[data-nav-dir="fwd"] body{ animation-name:pt-in-right;  }
html.pt-enter[data-nav-dir="back"]body{ animation-name:pt-in-left;   }

/* ---- swipe hint ----
   Rides in from the edge as the drag builds so the gesture answers back
   before it commits, and lights up once it is past the point of no return. */
.swipe-hint{
  --swipe-p:0;
  position:fixed;
  top:50%;
  z-index:100;
  display:flex;
  align-items:center;
  gap:10px;
  padding:11px 16px;
  border:1px solid var(--line);
  border-radius:999px;
  background:var(--glass);
  -webkit-backdrop-filter:blur(12px);
  backdrop-filter:blur(12px);
  box-shadow:var(--shadow-pill);
  font-family:var(--f-mono);
  font-size:12.5px;
  letter-spacing:.02em;
  color:var(--text-muted);
  white-space:nowrap;
  pointer-events:none;
  opacity:0;
  transition:border-color var(--t-fast) linear,
             color var(--t-fast) linear,
             box-shadow var(--t-fast) linear;
}
.swipe-hint[hidden]{ display:none; }
.swipe-hint .glyph{
  color:var(--blue-bright);
  font-size:15px;
  line-height:1;
  transition:transform var(--t-base) var(--ease-snap);
}

/* opacity outruns the drag slightly so the pill is legible well before the
   threshold, while the slide-in tracks the finger 1:1 */
.swipe-hint.is-right{
  right:16px;
  opacity:calc(var(--swipe-p) * 1.6);
  transform:translate(calc((1 - var(--swipe-p)) * 130%), -50%);
}
.swipe-hint.is-left{
  left:16px;
  opacity:calc(var(--swipe-p) * 1.6);
  transform:translate(calc((var(--swipe-p) - 1) * 130%), -50%);
}
.swipe-hint.is-armed{
  border-color:var(--blue);
  color:var(--text);
  box-shadow:var(--shadow-pill), 0 0 0 4px var(--blue-glow);
}
.swipe-hint.is-armed.is-right .glyph{ transform:translateX(3px); }
.swipe-hint.is-armed.is-left  .glyph{ transform:translateX(-3px); }

@media (prefers-reduced-motion: reduce){
  .swipe-hint{ transform:translateY(-50%) !important; }
}
