/* Laperouse — dark editorial studio sheet.
   Motion vocabulary copied from the pinned reference (avcoloristics.ru):
   gradient preloader, inertial wheel scrolling, fixed-attachment parallax,
   flex-expanding gallery, per-character title reveal, hover lift. */

:root{
  --bg:#0a0a0b;
  --bg-2:#121213;
  --bg-3:#191919;
  --ink:#f2efe9;
  --ink-2:#a5a098;
  /* was #6f6b64 — measured 3.73:1 on the page ground, below the 4.5:1 AA needs.
     It carries .price-note, where the whole price justification lives. #8a857c
     measures 5.1:1 and still sits clearly below --ink-2 (7.6:1). */
  --ink-3:#8a857c;
  --line:rgba(242,239,233,.14);
  --line-soft:rgba(242,239,233,.07);
  --metal:#ff7a1a;              /* warm orange — edges, trail, micro-signals */
  --metal-deep:#c2450a;
  --live:#57c98a;
  --display:"Forum",Georgia,serif;
  --sans:"Golos Text",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  --gutter:clamp(18px,4vw,56px);
  --maxw:1320px;
  --ease:cubic-bezier(.22,.61,.24,1);
  --ease-soft:cubic-bezier(.33,.02,.16,1);
}
*{box-sizing:border-box;margin:0}
html{scroll-behavior:smooth;background:var(--bg)}
body{
  background:var(--bg);color:var(--ink);font-family:var(--sans);line-height:1.65;
  -webkit-font-smoothing:antialiased;overflow-x:hidden;
}
img{max-width:100%;height:auto;display:block}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;cursor:pointer;background:none;border:0}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 var(--gutter)}
.mono-num{font-variant-numeric:tabular-nums}

/* ── fluted glass — one section only ─────────────────── */
/* The copy gets its own quiet plate so the ribs never fight the reading. */
.band--fluted .wrap{position:relative;z-index:1}
.band--fluted .wrap::before{
  content:"";position:absolute;inset:-40px -36px;z-index:-1;border-radius:24px;
  background:rgba(7,7,8,.86);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  border:1px solid var(--line-soft);
  /* The plate lags behind the ribs; that speed gap is what reads as depth. */
  transform:translate3d(0,var(--plate-y,0px),0);
}
/* On narrow screens .wrap already spans the viewport, so the plate may not
   reach past it — a negative horizontal inset there scrolls the page sideways. */
@media(max-width:700px){.band--fluted .wrap::before{inset:-24px 0;border-radius:16px}}
/* overflow keeps the over-tall rib layer from bleeding into the neighbours */
.band--fluted{position:relative;isolation:isolate;overflow:hidden}
.band--fluted::before{
  content:"";position:absolute;inset:-16% 0;z-index:-1;
  transform:translate3d(0,var(--rib-y,0px),0);will-change:transform;
  background:repeating-linear-gradient(90deg,
    rgba(255,255,255,.16) 0px,
    rgba(255,255,255,.06) 3px,
    rgba(255,255,255,.01) 12px,
    rgba(0,0,0,.5)        26px,
    rgba(255,255,255,.01) 40px,
    rgba(255,255,255,.06) 49px,
    rgba(255,255,255,.16) 52px);
  -webkit-mask-image:radial-gradient(120% 100% at 50% 50%,#000 30%,transparent 82%);
  mask-image:radial-gradient(120% 100% at 50% 50%,#000 30%,transparent 82%);
}


/* ── preloader: slow gradient sweep, then it lifts ───── */
.preloader{
  position:fixed;inset:0;z-index:2000;
  background:linear-gradient(220deg,#000,#1d1d1e,#000);
  background-size:300% 300%;
  animation:move-bg 13s linear infinite;
  display:grid;place-items:center;
  transition:opacity 1s var(--ease),visibility 1s var(--ease);
}
.preloader__mark{font-family:var(--display);font-size:clamp(26px,4vw,40px);letter-spacing:.4em;
  color:var(--ink);opacity:.9;padding-left:.4em}
@keyframes move-bg{0%,100%{background-position:0 50%}50%{background-position:100% 50%}}
.preloader.done{opacity:0;visibility:hidden}

/* ── nav ─────────────────────────────────────────────── */
.nav{position:fixed;top:0;left:0;right:0;z-index:1100;
  transition:background .6s var(--ease),border-color .6s var(--ease);
  border-bottom:1px solid transparent}
.nav.solid{background:rgba(10,10,11,.86);backdrop-filter:blur(14px);border-bottom-color:var(--line-soft)}
.nav .wrap{display:flex;align-items:center;justify-content:space-between;gap:24px;height:78px}
.brand{font-family:var(--display);font-size:22px;letter-spacing:.34em;padding-left:.34em}
.nav-links{display:none;gap:34px}
@media(min-width:900px){.nav-links{display:flex}}

/* ── Mobile menu ──────────────────────────────────────
   Below 900px the links used to simply vanish, leaving no way to reach
   Студия, Кейс, Цены or Контакты from a phone at all. */
.nav-burger{display:none}
@media(max-width:899px){
  .nav-burger{
    display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;
    width:44px;height:44px;flex:none;position:relative;z-index:2;
  }
  .nav-burger span{display:block;width:21px;height:1.5px;background:var(--ink);
    transition:transform .38s var(--ease),opacity .25s var(--ease)}
  .nav-burger[aria-expanded="true"] span:first-child{transform:translateY(3.75px) rotate(45deg)}
  .nav-burger[aria-expanded="true"] span:last-child{transform:translateY(-3.75px) rotate(-45deg)}

  .brand,.nav .pill{position:relative;z-index:2}
  .nav .pill{margin-left:auto}

  /* An element with backdrop-filter becomes the containing block for its
     position:fixed descendants. .nav.solid has one, so the full-screen panel
     was being laid out inside the 78px bar — no backdrop, links spilling out.
     Dropping the filter while the menu is open gives the panel the viewport
     back; the panel's own background covers the bar anyway. */
  body.menu-open .nav{background:transparent;backdrop-filter:none;
    -webkit-backdrop-filter:none;border-bottom-color:transparent}

  .nav-links{
    display:flex;position:fixed;inset:0;z-index:1;
    flex-direction:column;justify-content:center;gap:0;
    padding:0 var(--gutter);background:rgba(10,10,11,.975);
    backdrop-filter:blur(22px);-webkit-backdrop-filter:blur(22px);
    opacity:0;visibility:hidden;transition:opacity .34s var(--ease),visibility .34s;
  }
  body.menu-open .nav-links{opacity:1;visibility:visible}
  /* .nav prefix: the plain .nav-links a rules sit further down the file and
     would otherwise win on source order at equal specificity */
  .nav .nav-links a{
    font-family:var(--display);font-size:clamp(30px,9vw,46px);line-height:1.1;
    text-transform:none;letter-spacing:.01em;color:var(--ink-2);
    padding:18px 0;border-bottom:1px solid var(--line-soft);
    opacity:0;transform:translateY(14px);
  }
  body.menu-open .nav .nav-links a{opacity:1;transform:none;
    transition:opacity .4s var(--ease) calc(var(--n,0) * 55ms + 90ms),
               transform .5s var(--ease) calc(var(--n,0) * 55ms + 90ms),color .3s}
  .nav .nav-links a[aria-current="page"]{color:var(--ink)}
  .nav .nav-links a::after{display:none}
  body.menu-open{overflow:hidden}
}
.nav-links a{font-size:11.5px;text-transform:uppercase;letter-spacing:.2em;color:var(--ink-2);
  transition:color .35s var(--ease);position:relative;padding:4px 0}
.nav-links a::after{content:"";position:absolute;left:0;right:100%;bottom:0;height:1px;
  background:var(--ink);transition:right .5s var(--ease)}
.nav-links a:hover,.nav-links a[aria-current="page"]{color:var(--ink)}
.nav-links a:hover::after,.nav-links a[aria-current="page"]::after{right:0}

.pill{
  display:inline-flex;align-items:center;justify-content:center;gap:10px;
  min-height:44px;border:1px solid var(--line);
  border-radius:999px;padding:12px 26px;font-size:11px;text-transform:uppercase;
  letter-spacing:.2em;color:var(--ink);
  transition:background .45s var(--ease),color .45s var(--ease),border-color .45s var(--ease),transform .12s ease-out;
}
.pill:hover{background:var(--ink);color:var(--bg);border-color:var(--ink)}
.pill:active{transform:scale(.97)}
.pill.solid{background:var(--ink);color:var(--bg);border-color:var(--ink)}
.pill.solid:hover{background:transparent;color:var(--ink)}
/* 2px, not 1: a hairline ring is hard to see against a near-black ground */
a:focus-visible,button:focus-visible{outline:2px solid var(--metal);outline-offset:4px}

/* ── per-character reveal (reference's slide-in) ─────── */
.chars{display:inline-block}
.chars span{display:inline-block;opacity:0;transform:translateY(.42em) rotate(1.5deg);
  animation:char-in .6s var(--ease) both;
  animation-delay:calc(.18s + (26ms * var(--i)))}
@keyframes char-in{to{opacity:1;transform:none}}

/* ── generic reveal on scroll ────────────────────────── */
.rise{opacity:0;transform:translateY(26px);
  transition:opacity .62s var(--ease),transform .62s var(--ease)}
.rise.in{opacity:1;transform:none}
.rise[data-d="1"]{transition-delay:.05s}
.rise[data-d="2"]{transition-delay:.1s}
.rise[data-d="3"]{transition-delay:.15s}

/* ── hero ────────────────────────────────────────────── */
.hero{min-height:100svh;display:flex;align-items:flex-end;padding:120px 0 clamp(40px,7vw,88px);
  position:relative;overflow:hidden}
.hero__bg{position:absolute;inset:0;z-index:-1;
  background:radial-gradient(90% 60% at 78% 22%,rgba(194,160,106,.10),transparent 62%),
             radial-gradient(70% 50% at 12% 88%,rgba(242,239,233,.05),transparent 60%)}
.hero .wrap{width:100%;display:grid;gap:clamp(34px,6vw,56px);align-items:end}
@media(min-width:1000px){.hero .wrap{grid-template-columns:1.15fr .85fr;align-items:center}}
.hero h1{font-family:var(--display);font-size:clamp(54px,11vw,138px);line-height:.94;
  letter-spacing:.02em;font-weight:400}
.hero__sub{margin-top:22px;font-size:clamp(11px,1.3vw,13px);text-transform:uppercase;
  letter-spacing:.42em;color:var(--ink-2)}
.hero__lede{margin-top:26px;max-width:46ch;color:var(--ink-2);font-size:clamp(15px,1.5vw,17px)}
.hero__actions{margin-top:34px;display:flex;flex-wrap:wrap;gap:14px}
.hero__device{justify-self:center;width:min(280px,66vw);border-radius:38px;overflow:hidden;
  background:#000;box-shadow:0 80px 120px -60px rgba(0,0,0,.95),0 0 0 1px rgba(242,239,233,.08)}

/* ── layered hero (reference 1): a bright line over a dim one,
      with the product standing between them ─────────────── */
/* The floor is reserved for the tags, the line of copy and the stats, so the
   figure never lands on top of them. */
/* The figure leads, lit from behind; the name reads underneath it. */
.stage{position:relative;min-height:100svh;display:flex;flex-direction:column;
  align-items:center;justify-content:center;
  padding:104px 0 clamp(132px,17vh,182px);overflow:hidden}
/* Light spilling from behind the figure — wide and soft, never a visible disc. */
.stage__glow{
  position:absolute;top:clamp(70px,13vh,150px);left:50%;transform:translateX(-50%);
  width:min(860px,94vw);height:min(540px,54vh);pointer-events:none;
  background:radial-gradient(closest-side,rgba(255,146,52,.20),rgba(194,69,10,.07) 40%,transparent 70%);
  filter:blur(56px);
}
.stage__type{display:flex;flex-direction:column;width:100%;
  pointer-events:none;gap:clamp(0px,.4vw,6px);margin-top:clamp(-14px,-1.2vw,-4px)}
.stage__line{font-family:var(--display);line-height:.86;letter-spacing:.005em;white-space:nowrap;
  padding:0 var(--gutter)}
.stage__line--front{font-size:clamp(32px,5.8vw,84px);color:var(--ink);position:relative;z-index:3;
  align-self:flex-start}
.stage__line--back{font-size:clamp(25px,4.4vw,64px);color:rgba(242,239,233,.16);position:relative;z-index:1;
  align-self:flex-end}
.stage__rule{display:inline-block;width:clamp(26px,4.5vw,68px);height:2px;background:var(--ink);
  vertical-align:middle;margin:0 .3em;opacity:.7}
/* the authored character */
/* The frames now carry real alpha (baked in from the renders), so there is no
   plate left to hide: no blend mode, no mask, nothing to leave an edge. */
.figure{position:relative;width:min(580px,84vw)}
.figure img{width:100%;height:auto;display:block}
.stage__foot{position:absolute;left:0;right:0;bottom:clamp(30px,6vh,76px);z-index:4;
  display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;
  gap:clamp(20px,4vw,48px);padding:0 var(--gutter)}
.tags{display:flex;gap:12px;flex-wrap:wrap}
.tag{border:1px solid var(--line);border-radius:999px;padding:14px 28px;
  font-size:clamp(13px,1.35vw,16px);letter-spacing:.04em;color:var(--ink);
  transition:border-color .35s var(--ease),background .35s var(--ease)}
.tag:hover{border-color:var(--metal);background:rgba(255,122,26,.08)}
.stage__lede{max-width:30ch;color:var(--ink-2);font-size:14px;text-align:right;margin-left:auto}
.stats{display:flex;gap:14px}
.stat{position:relative;min-width:132px;padding:18px 20px 16px;border:1px solid var(--line-soft);
  border-radius:8px;background:linear-gradient(180deg,rgba(242,239,233,.03),transparent);overflow:hidden}
.stat::before{content:"";position:absolute;left:0;top:0;bottom:0;width:2px;
  background:linear-gradient(180deg,var(--metal),transparent)}
.stat__n{font-family:var(--display);font-size:clamp(26px,3.2vw,38px);line-height:1}
.stat__l{margin-top:8px;font-size:11px;color:var(--ink-3);letter-spacing:.06em;line-height:1.35}
@media(max-width:900px){
  /* In a column flex box align-items is the HORIZONTAL axis: place-items:start
     was pushing the figure hard against the left edge. Vertical placement
     belongs to justify-content. */
  .stage{align-items:center;justify-content:flex-start;padding-top:104px}
  .stage__type{position:static;gap:2px}
  /* keep the page gutter: at padding:0 the wordmark started 9px from the edge
     while every other element respected 18px, which read as a clipping bug */
  .stage__line{padding:0 var(--gutter)}
  .figure{width:min(330px,80vw)}
  .stage__foot{position:static;margin-top:34px;padding:0;
    flex-direction:column;align-items:stretch;gap:22px}
  .stage__lede{text-align:left;margin-left:0;max-width:none}
  .stats{width:100%}
  .stat{flex:1}
}

/* ── section frame ───────────────────────────────────── */
.band{padding:clamp(64px,9vw,130px) 0;border-top:1px solid var(--line-soft)}
.band__head{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;
  gap:18px;margin-bottom:clamp(32px,4.5vw,58px)}
h2{font-family:var(--display);font-size:clamp(32px,5.4vw,68px);line-height:1.02;font-weight:400;letter-spacing:.01em}
h3{font-family:var(--display);font-size:clamp(22px,3vw,34px);font-weight:400;line-height:1.16}
.band__note{max-width:40ch;color:var(--ink-3);font-size:13.5px}
.eyebrow{font-size:11px;text-transform:uppercase;letter-spacing:.28em;color:var(--ink-3)}

/* ── works: flex-expanding gallery (reference mechanic) ─ */
.gallery{display:flex;gap:10px;height:min(66vh,560px)}
@media(max-width:860px){.gallery{flex-direction:column;height:auto;gap:12px}}
.slide{
  position:relative;flex:1;min-width:0;border-radius:14px;overflow:hidden;text-align:left;
  background:var(--bg-2);border:1px solid var(--line-soft);
  transition:flex .55s var(--ease),border-color .6s var(--ease),background .6s var(--ease);
}
/* flex:none, or flex-basis:0 from .slide wins over height in a column flex
   container and every collapsed panel renders 2px tall */
@media(max-width:860px){.slide{flex:none;height:150px;
  transition:height .5s var(--ease),border-color .6s var(--ease)}}
.slide:hover{border-color:var(--line)}
.slide.active{flex:3.4;border-color:var(--line)}
@media(max-width:860px){.slide.active{height:430px;flex:none}}
/* The product sits inside the panel as a lit object, never as a wallpaper the
   copy has to fight. It arrives only once the panel is open. */
/* The screenshot is a full app screen, so it ends on a hard horizontal line;
   feathering the last few percent lets it sink into the panel instead. */
.slide__device{
  -webkit-mask-image:linear-gradient(180deg,#000 84%,transparent 100%);
  mask-image:linear-gradient(180deg,#000 84%,transparent 100%);
  position:absolute;top:50%;right:6%;width:132px;border-radius:18px;overflow:hidden;
  /* Visible even while collapsed: a row of tinted rectangles gave the visitor
     nothing to look at before interacting, which is the wrong trade in the
     one section that has to prove the work exists. */
  transform:translate(14px,-46%) scale(.96);opacity:.34;
  box-shadow:0 46px 70px -40px rgba(0,0,0,.95),0 0 0 1px rgba(242,239,233,.09);
  transition:opacity .5s var(--ease) .05s,transform .62s var(--ease) .05s;
  pointer-events:none;
}
.slide.active .slide__device{opacity:1;transform:translate(0,-50%) scale(1)}
@media(max-width:860px){
  .slide__device{width:104px;right:20px;top:44%}
}
.slide__veil{position:absolute;inset:0;
  background:radial-gradient(120% 90% at 80% 30%,rgba(194,160,106,.10),transparent 60%),
             linear-gradient(180deg,rgba(10,10,11,.35) 0%,rgba(10,10,11,.86) 78%)}
.slide__body{position:absolute;inset:auto 0 0 0;padding:26px;display:flex;align-items:flex-end;
  justify-content:space-between;gap:14px}
.slide.active .slide__body{padding-right:min(30%,190px)}
@media(max-width:860px){
  .slide.active .slide__body{padding-right:26px}
  .slide__body{padding:20px}
}
/* The description, hidden by opacity alone, still took its full height and
   pushed the bottom-anchored body upward — over the badge on mobile, and
   across the device screenshot on desktop. Collapse it out of the flow so the
   name sits on the floor of the panel where it belongs. */
.slide .slide__meta{max-height:0;overflow:hidden;
  transition:max-height .5s var(--ease),opacity .42s var(--ease),transform .42s var(--ease)}
.slide.active .slide__meta{max-height:340px}
.slide__name{font-family:var(--display);font-size:clamp(19px,2vw,26px);line-height:1.15;
  /* 260px silently clipped «Приватка по крипте» to «Приватка по крипт» */
  writing-mode:vertical-rl;transform:rotate(180deg);max-height:340px;
  transition:writing-mode 0s,transform .6s var(--ease)}
@media(max-width:860px){.slide__name{writing-mode:horizontal-tb;transform:none;max-height:none}}
.slide.active .slide__name{writing-mode:horizontal-tb;transform:none;max-height:none}
.slide__meta{opacity:0;transform:translateY(10px);
  transition:opacity .42s var(--ease) .08s,transform .42s var(--ease) .08s;
  max-width:38ch}
.slide.active .slide__meta{opacity:1;transform:none}
.slide__kind{color:var(--ink-2);font-size:13px;margin-top:8px}
.slide__open{display:inline-flex;align-items:center;gap:9px;margin-top:16px;font-size:11px;
  text-transform:uppercase;letter-spacing:.2em;color:var(--ink);border-bottom:1px solid var(--line);
  padding-bottom:5px;transition:border-color .4s var(--ease)}
.slide__open:hover{border-color:var(--ink)}
/* On a collapsed panel the vertical name owns the column, so the badge waits
   until the panel opens rather than colliding with the lettering. */
@media(min-width:861px){
  .slide__state{opacity:0;transition:opacity .5s var(--ease)}
  .slide.active .slide__state{opacity:1}
}
.slide__state{position:absolute;top:20px;left:20px;font-size:9.5px;text-transform:uppercase;
  letter-spacing:.18em;color:var(--ink-2);border:1px solid var(--line);border-radius:999px;
  padding:5px 12px;background:rgba(10,10,11,.5);display:flex;align-items:center;gap:7px}
.slide__state .dot{width:6px;height:6px;border-radius:50%;background:var(--ink-3)}
.slide__state.live{color:var(--ink)}
.slide__state.live .dot{background:var(--live);box-shadow:0 0 0 3px rgba(87,201,138,.18)}

/* ── parallax strip ──────────────────────────────────── */
.parallax{min-height:min(58vh,460px);background-size:cover;background-position:center;
  background-attachment:fixed;display:grid;place-items:center;text-align:center;position:relative}
.parallax::after{content:"";position:absolute;inset:0;background:rgba(10,10,11,.62)}
.parallax .wrap{position:relative;z-index:1}

/* ── prose + lists ───────────────────────────────────── */
.prose{color:var(--ink-2);max-width:64ch;font-size:clamp(15px,1.5vw,16.5px)}
.prose p+p{margin-top:15px}
.prose strong{color:var(--ink);font-weight:600}
.facts{margin-top:34px;border-top:1px solid var(--line-soft)}
.fact{display:flex;gap:18px;padding:14px 0;border-bottom:1px solid var(--line-soft);font-size:14.5px}
.fact dt{width:130px;flex:none;color:var(--ink-3);font-size:11px;text-transform:uppercase;
  letter-spacing:.16em;padding-top:4px}
.fact dd{color:var(--ink-2)}

/* ── shots ───────────────────────────────────────────── */
.shots{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:20px}
.shots figure{transition:transform .4s var(--ease)}
.shots figure:hover{transform:translateY(-10px)}
.shots img{border-radius:14px;box-shadow:0 40px 60px -40px rgba(0,0,0,.9);border:1px solid var(--line-soft)}
.shots figcaption{margin-top:12px;font-size:12.5px;color:var(--ink-3);line-height:1.5}

/* ── open admin ──────────────────────────────────────── */
.open-admin{border:1px solid var(--line);border-radius:16px;padding:clamp(26px,4vw,46px);
  background:linear-gradient(160deg,var(--bg-2),var(--bg));position:relative;overflow:hidden}
.open-admin::after{content:"";position:absolute;width:340px;height:340px;border-radius:50%;
  right:-150px;top:-170px;background:rgba(194,160,106,.09);filter:blur(10px)}
.open-admin > *{position:relative;z-index:1}
.open-admin p{color:var(--ink-2);max-width:56ch;margin-top:12px}
.open-admin .pill{margin-top:26px}

/* ── contact ─────────────────────────────────────────── */
.center{text-align:center}
.center .prose{margin-inline:auto}
.big-link{font-family:var(--display);font-size:clamp(34px,7vw,86px);line-height:1.05;
  display:inline-block;position:relative;padding-bottom:.08em}
.big-link::after{content:"";position:absolute;left:0;right:100%;bottom:0;height:1px;background:var(--ink);
  transition:right .5s var(--ease)}
.big-link:hover::after{right:0}

footer{border-top:1px solid var(--line-soft);padding:34px 0 44px}
footer .wrap{display:flex;flex-wrap:wrap;gap:14px 28px;align-items:center;justify-content:space-between;
  font-size:11px;text-transform:uppercase;letter-spacing:.2em;color:var(--ink-3)}
footer a:hover{color:var(--ink)}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .rise{opacity:1;transform:none;transition:none}
  .chars span{opacity:1;transform:none;animation:none}
  .preloader{animation:none}
  .slide,.slide__img,.slide__meta,.shots figure{transition:none}
  .parallax{background-attachment:scroll}
}

/* ── the running app, embedded in the works panel ─────── */
.live-app{margin-top:26px;display:grid;gap:22px;align-items:center}
@media(min-width:820px){.live-app{grid-template-columns:auto 1fr}}
.live-frame{
  position:relative;width:302px;max-width:78vw;aspect-ratio:390/720;border-radius:34px;
  overflow:hidden;background:#000;justify-self:center;
  box-shadow:0 60px 90px -50px #000,0 0 0 1px rgba(242,239,233,.1),0 0 90px -40px rgba(255,122,26,.35);
}
.live-frame iframe{width:100%;height:100%;border:0;display:block;position:relative;z-index:1}
/* The screenshot sits underneath as the floor. If the origin is slow or down,
   js/app.js drops the iframe and this is what the visitor sees — a real screen
   with an honest caption, never a black rectangle under a live-app promise. */
.live-frame__shot{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0}
.live-frame.fallback iframe{display:none}
.live-frame__hint{position:absolute;inset:auto 0 0 0;padding:10px;font-size:10.5px;text-align:center;
  color:var(--ink-3);background:linear-gradient(180deg,transparent,rgba(10,10,11,.9));pointer-events:none;
  letter-spacing:.08em;text-transform:uppercase}
.live-app__side h3{margin-bottom:10px}
.live-app__side p{color:var(--ink-2);max-width:46ch;font-size:14.5px}
.live-app__actions{display:flex;flex-wrap:wrap;gap:12px;margin-top:20px}
.visually-hidden{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* ── prices ──────────────────────────────────────────── */
/* Three cards in two columns leave one orphan on its own row, which reads as
   a mistake. Below the width that fits all three, they stack in one column. */
.prices{display:grid;gap:18px;margin-top:8px}
@media(max-width:1119px){.prices{max-width:620px;margin-inline:auto}}
@media(min-width:1120px){.prices{grid-template-columns:repeat(3,1fr);gap:20px}}
.price{
  display:flex;flex-direction:column;
  position:relative;border:1px solid var(--line-soft);border-radius:18px;overflow:hidden;
  padding:clamp(26px,3.4vw,40px);background:linear-gradient(165deg,var(--bg-2),var(--bg));
  transition:border-color .4s var(--ease),transform .4s var(--ease);
}
.price:hover{border-color:var(--line);transform:translateY(-6px)}
.price::before{content:"";position:absolute;left:0;right:0;top:0;height:2px;
  background:linear-gradient(90deg,var(--metal),transparent 70%)}
.price__kind{font-size:11px;text-transform:uppercase;letter-spacing:.2em;color:var(--ink-3)}
/* a reserved height keeps the three sums on one baseline: the middle tier's
   name wraps to three lines and used to push its price ~50px below the others */
.price__name{font-family:var(--display);font-size:clamp(23px,2.7vw,32px);line-height:1.15;margin-top:12px}
@media(min-width:1120px){.price__name{min-height:3.45em}}
.price__sum{display:flex;align-items:baseline;gap:10px;margin-top:20px}
.price__n{font-family:var(--display);font-size:clamp(40px,5.4vw,64px);line-height:1;color:var(--ink)}
.price__cur{font-size:15px;color:var(--ink-3)}
.price__list{margin-top:22px;border-top:1px solid var(--line-soft);flex:1}
.price__list div{display:flex;gap:11px;padding:10px 0;border-bottom:1px solid var(--line-soft);
  font-size:14px;color:var(--ink-2);align-items:flex-start}
.price__list div::before{content:"";width:5px;height:5px;border-radius:50%;background:var(--metal);
  flex:none;margin-top:9px}
.price .pill{margin-top:26px}
.price-note{margin-top:26px;color:var(--ink-3);font-size:13.5px;max-width:62ch}
.price-note strong{color:var(--ink-2);font-weight:600}
/* the market figure, stated plainly — brighter than the copy, but no shouting */
.market{color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap;
  border-bottom:1px solid var(--line)}

/* Each demo panel carries its own tint, so the row never reads as one repeated card */
.slide[data-tint="nails"]  .slide__veil{background:radial-gradient(120% 90% at 70% 25%,rgba(168,85,111,.30),transparent 62%),linear-gradient(180deg,rgba(10,10,11,.30),rgba(10,10,11,.90) 78%)}
.slide[data-tint="barber"] .slide__veil{background:radial-gradient(120% 90% at 70% 25%,rgba(200,16,46,.26),transparent 62%),linear-gradient(180deg,rgba(10,10,11,.30),rgba(10,10,11,.90) 78%)}
.slide[data-tint="coffee"] .slide__veil{background:radial-gradient(120% 90% at 70% 25%,rgba(190,140,70,.30),transparent 62%),linear-gradient(180deg,rgba(10,10,11,.30),rgba(10,10,11,.90) 78%)}
.slide[data-tint="shop"]   .slide__veil{background:radial-gradient(120% 90% at 70% 25%,rgba(210,210,215,.22),transparent 62%),linear-gradient(180deg,rgba(10,10,11,.30),rgba(10,10,11,.90) 78%)}

/* ── The figure breathes: stacked frames, one visible at a time ───────── */
.figure{aspect-ratio:620/500}
.figure img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:contain;
  opacity:0;transition:opacity .85s var(--ease-soft);
}
.figure img.on{opacity:1}
.figure{animation:breathe 9s var(--ease-soft) infinite}
@keyframes breathe{0%,100%{transform:translateY(0)}50%{transform:translateY(-9px)}}
@media (prefers-reduced-motion:reduce){
  .figure{animation:none}
  .figure img{transition:none}
}

/* ── Sections slide under one another — sticky stack, kept gentle ─────── */
/* NB: must out-specify the plain .band/.stage position rules above. */
/* Only the home page stacks. On the reading pages — контакты, студия, кейс,
   оферта — sections sliding over one another read as an unwanted parallax. */
body.home main > section.stage, body.home main > section.band{position:sticky;top:0;background:var(--bg)}
body.home main > section.band:last-child{position:relative}
/* A section taller than the viewport can never be read while it is pinned: its
   lower half stays parked under the next card in the deck for good — that is
   where the live mini app and the price notes live. js/app.js measures every
   section and hands this class to the ones that do not fit; #works carries it
   in the markup too, since it is always tall. */
body.home main > section.band--flow{position:relative}
/* a hairline + soft shadow makes the overlap read as depth, not a seam */
body.home main > .band{
  border-top:1px solid var(--line-soft);
  box-shadow:0 -30px 60px -30px rgba(0,0,0,.9);
  border-radius:26px 26px 0 0;
}
@media(max-width:700px){
  body.home main > section.stage, body.home main > section.band{position:relative}
  body.home main > .band{border-radius:18px 18px 0 0}
}

/* ── Richer surfaces: quiet inner light, nothing loud ─────────────────── */
.price, .open-admin, .live-frame, .stat{
  box-shadow:inset 0 1px 0 rgba(242,239,233,.06), 0 30px 60px -50px #000;
}
.price::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:radial-gradient(140% 90% at 50% -10%,rgba(242,239,233,.05),transparent 60%);
}
.band__head h2{position:relative}
.stat{background:linear-gradient(180deg,rgba(242,239,233,.045),transparent 70%)}
.tag{background:linear-gradient(180deg,rgba(242,239,233,.05),transparent)}

/* ── The conversion moment ────────────────────────────────────────────
   A real button under the wordmark link, plus the one sentence that removes
   the risk of writing to a stranger. Both were missing; the page's whole
   purpose rested on a serif line with a hover-only underline. */
.cta{margin-top:30px;display:flex;flex-direction:column;align-items:center;gap:18px}
.cta__btn{min-height:58px;padding:18px 40px;font-size:12.5px}
.cta__note{max-width:46ch;color:var(--ink-2);font-size:14px;line-height:1.6}
/* the display link keeps a permanent rule — hover is not available on a phone */
.big-link{border-bottom:1px solid var(--line)}
.big-link:hover{border-bottom-color:var(--ink)}

/* ═══ Blueprint: the product taken apart ═══════════════════════════════
   A phone drawn in hairlines, tilted like an exploded assembly drawing.
   Scroll pulls the layers apart and each one names a deliverable, so the
   ornament says the same thing the price list does. Desktop only: it needs
   real estate, and on a phone the page has better uses for the corner. */
.bp{display:none}
@media(min-width:1200px){
  .bp{
    /* the right offset leaves room for the labels, which fan out past the
       drawing — at a tighter margin «Домен и HTTPS» ran off the viewport */
    display:block;position:fixed;top:186px;right:clamp(142px,10.5vw,196px);
    width:212px;height:370px;pointer-events:none;z-index:900;
    perspective:1100px;opacity:0;
    transform:translateY(var(--bp-y,0px));
  }
  .bp__scene{
    position:absolute;inset:0;transform-style:preserve-3d;
    transform:rotateX(58deg) rotateZ(calc(-38deg + var(--spin,0) * 1deg));
  }
  .bp__l{
    position:absolute;left:50%;top:50%;width:128px;height:262px;margin:-131px 0 0 -64px;
    border:1px solid rgba(242,239,233,.32);border-radius:16px;
    transform:translateZ(calc(var(--sep,0) * var(--i) * 1px));
    transform-style:preserve-3d;
  }
  /* — each layer carries the drawing of the part it stands for — */
  .bp--glass{border-color:rgba(255,122,26,.34)}
  .bp--glass::before{content:"";position:absolute;inset:9px;border-radius:10px;
    border:1px solid rgba(242,239,233,.14)}
  .bp--ui::before{content:"";position:absolute;inset:14px 12px auto;height:22px;border-radius:5px;
    background:rgba(242,239,233,.16)}
  .bp--ui::after{content:"";position:absolute;inset:46px 12px 40px;border-radius:6px;
    background:repeating-linear-gradient(180deg,
      rgba(242,239,233,.13) 0 7px,transparent 7px 20px)}
  .bp--board::before{content:"";position:absolute;inset:12px;border-radius:8px;
    background:repeating-linear-gradient(90deg,rgba(242,239,233,.13) 0 1px,transparent 1px 15px),
               repeating-linear-gradient(180deg,rgba(242,239,233,.13) 0 1px,transparent 1px 15px)}
  .bp--board::after{content:"";position:absolute;left:26px;top:74px;width:52px;height:52px;
    border:1px solid rgba(255,122,26,.4);border-radius:4px}
  .bp--bot::before{content:"";position:absolute;inset:30px 18px 46px;border-radius:9px;
    border:1px solid rgba(242,239,233,.2)}
  .bp--bot::after{content:"";position:absolute;left:50%;top:50%;width:34px;height:34px;
    margin:-17px 0 0 -17px;border:1px solid rgba(242,239,233,.24);border-radius:50%}
  .bp--back::before{content:"";position:absolute;left:16px;top:16px;width:44px;height:44px;
    border:1px solid rgba(242,239,233,.24);border-radius:12px}
  .bp--back::after{content:"";position:absolute;left:27px;top:27px;width:22px;height:22px;
    border:1px solid rgba(255,122,26,.34);border-radius:50%}

  /* — labels face the reader: undo the scene rotation from the inside — */
  .bp__tag{
    position:absolute;left:calc(100% + 26px);top:26%;transform-origin:left center;
    transform:rotateZ(calc(38deg - var(--spin,0) * 1deg)) rotateX(-58deg) translateY(-50%);
    white-space:nowrap;font-size:9px;letter-spacing:.15em;text-transform:uppercase;
    color:var(--ink-2);font-style:normal;
    opacity:clamp(0,calc((var(--sep,0) - 10) / 20),1);
  }
  .bp__tag::before{content:"";position:absolute;right:calc(100% + 7px);top:50%;
    width:17px;height:1px;background:currentColor;opacity:.5}
}
@media (prefers-reduced-motion:reduce){
  .bp__scene{transition:none}
}

/* ═══ Phones ═══════════════════════════════════════════════════════════
   Measured on 320 / 390 / 430. Three things a phone needs that a desktop
   does not: a header that fits the narrowest screen, targets a thumb can
   actually hit (44px is the floor), and no type under ~12px. */
@media(max-width:900px){
  /* — header — */
  .nav .wrap{gap:12px;height:66px}
  .brand{font-size:18px;letter-spacing:.26em;padding-left:.26em}
  .nav .pill{padding:12px 18px;font-size:11.5px;letter-spacing:.1em;white-space:nowrap;flex:none}

  /* — targets: anything tappable gets a thumb-sized box — */
  .slide__open{display:inline-flex;align-items:center;min-height:44px;font-size:13px;letter-spacing:.12em}
  footer a{display:inline-flex;align-items:center;min-height:44px}
  .big-link{display:inline-flex;align-items:center;min-height:56px}
  .fact dd a{display:inline-block;padding:9px 0}
  .price .pill,.live-app__actions .pill,.open-admin{min-height:48px}

  /* — type: nothing below 12px, nothing set in whisper-grey on a small screen — */
  .pill{font-size:12px}
  .eyebrow{font-size:12px;letter-spacing:.18em}
  .stat__l{font-size:12px}
  .slide__state{font-size:12px}
  .band__note,.price-note{font-size:14px}
  .live-frame__hint{font-size:12px;letter-spacing:.06em}
  .fact dt{font-size:12px}
  .fact{font-size:15px}
  .price__kind{font-size:12px;letter-spacing:.16em}
  footer .wrap{font-size:12px;letter-spacing:.16em}
  .brand{display:inline-flex;align-items:center;min-height:44px}
  /* Inline links in running text get a thumb-sized hit box. Padding on an
     inline box does not grow the line, so the text keeps its rhythm. */
  .price-note a,.doc a,.prose a,.req a{padding:11px 3px;margin:-11px -3px}
}
@media(max-width:420px){
  /* the verb is noise on a phone — the button is obviously a button */
  .pill__long{display:none}
  .brand{font-size:16px;letter-spacing:.2em;padding-left:.2em}
  .nav .pill{padding:11px 15px}
  .fact{flex-direction:column;gap:4px}
  .fact dt{width:auto}
}

/* ── Parallax: JS only writes --par-y, the transform lives here ──────────
   Going through a custom property lets a layer that already needs a
   transform (the hero glow is centred with translateX) compose the drift
   into its own rule instead of having it overwritten. */
/* A page marked .plain holds completely still: no deck, no scroll reveal.
   Контакты — страница для чтения, любое движение там читается как лишнее. */
body.plain .rise{opacity:1 !important;transform:none !important;transition:none !important}

/* One frame with the stack unpinned, so the anchors can be measured honestly. */
html.measuring body.home main > section.stage,
html.measuring body.home main > section.band{position:relative}
[data-par]{transform:translate3d(0,var(--par-y,0px),0);will-change:transform}
.stage__glow[data-par]{transform:translate(-50%,var(--par-y,0px))}
@media (prefers-reduced-motion:reduce){
  [data-par]{transform:none;will-change:auto}
}
