/* ==========================================================================
   PW SERVICES — dark / silver, Apple-grade motion system
   ========================================================================== */

:root{
  --black:        #030304;
  --black-soft:   #0a0a0c;
  --charcoal:     #131316;
  --charcoal-2:   #1b1b1f;
  --line:         rgba(255,255,255,.09);
  --line-soft:    rgba(255,255,255,.05);

  --silver-100:   #f4f5f7;
  --silver-200:   #e3e5e9;
  --silver-300:   #c9cdd3;
  --silver-400:   #9aa0a8;
  --silver-500:   #6b7078;

  --ice:          #8fd9e8;
  --ice-dim:      rgba(143,217,232,.35);
  --ice-deep:     #0f8fa6;

  --text:         var(--silver-200);
  --text-dim:     var(--silver-500);

  --paper:        #ffffff;
  --paper-line:   rgba(10,10,15,.1);
  --ink:          #101114;
  --ink-dim:      #5c5f66;
  --star-gold:    #f0ab2c;
  --quote-mark:   #ccd2d8;

  --grad-metal:   linear-gradient(135deg,#f4f5f7 0%,#c9cdd3 28%,#8a8f97 52%,#dadde1 76%,#f4f5f7 100%);
  --grad-metal-2: linear-gradient(180deg, rgba(255,255,255,.14), rgba(255,255,255,0) 60%);

  /* Type system - the "Dlaczego warto nas wybrac?" pairing, now site-wide.
     Playfair Display carries every display line (headings, menu, ticker,
     unit names); Poppins carries body, UI and numerals. A serif display face
     wants near-neutral tracking - the old -0.045em was cut for Space Grotesk
     and collapses Playfair's thin/thick joins, so display rules track ~-.01em. */
  --font-display: 'Playfair Display', Georgia, 'Times New Roman', serif;
  --font-body:    'Poppins', -apple-system, BlinkMacSystemFont, sans-serif;

  --ease-out:     cubic-bezier(.16,1,.3,1);
  --ease-in-out:  cubic-bezier(.65,0,.35,1);

  --fs-hero: clamp(2.6rem, 7.2vw, 6.4rem);
  --fs-h2:   clamp(2rem, 4.2vw, 3.4rem);
  --container: min(1280px, 92vw);
}

*,*::before,*::after{ box-sizing:border-box; margin:0; padding:0; }
html{ background:var(--black); scroll-behavior:auto; }
html,body{ height:100%; }

body{
  background:var(--black);
  color:var(--text);
  font-family:var(--font-body);
  font-weight:400;
  line-height:1.6;
  overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
  cursor:none;
}
@media (pointer:coarse){ body{ cursor:auto; } }

a{ color:inherit; text-decoration:none; }
ul{ list-style:none; }
button{ font-family:inherit; background:none; border:none; color:inherit; cursor:none; }
@media (pointer:coarse){ button{ cursor:pointer; } }
img,canvas,svg{ display:block; max-width:100%; }
h1,h2,h3,h4{ font-family:var(--font-display); font-weight:500; letter-spacing:-0.01em; color:var(--silver-100); }
em{ font-style:normal; background:var(--grad-metal); -webkit-background-clip:text; background-clip:text; color:transparent; }

::selection{ background:var(--silver-300); color:var(--black); }

::-webkit-scrollbar{ width:10px; }
::-webkit-scrollbar-track{ background:var(--black); }
::-webkit-scrollbar-thumb{ background:var(--charcoal-2); border-radius:10px; border:2px solid var(--black); }

/* ==========================================================================
   SECTION SCAFFOLDING
   ========================================================================== */
.section-tag{
  display:inline-block;
  font-family:var(--font-body);
  font-size:.75rem; font-weight:500;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--ice);
  margin-bottom:1rem;
}
.section-title{ font-size:var(--fs-h2); line-height:1.08; color:var(--silver-100); }
.section-lead{
  max-width:620px; margin-top:1.4rem; color:var(--text-dim);
  font-weight:300; font-size:1.02rem; line-height:1.65;
}
.section-head{ width:var(--container); margin:0 auto; padding:0 0 3.5rem; }


/* split-text primitive — one mask per word, JS fills it.
   The mask clips with overflow:hidden, so it needs slack below the baseline
   or descenders (g, j, y) get shaved off. */
.word-mask{
  display:inline-block; overflow:hidden; vertical-align:top;
  padding-bottom:.14em; margin-bottom:-.14em;
}
.word-inner{ display:inline-block; will-change:transform; }

/* ==========================================================================
   PRELOADER
   ========================================================================== */
/* One frozen plate: the studio photograph full-bleed, the emblem parked just
   above centre, the service line and a hairline load bar beneath it. No dial,
   no rings — the photograph carries all the light there is, so everything
   else is positioned against the plate's own geometry (measured at
   1791x878: emblem centre 50.2% / 43.0%, line at 67.5%, bar at 74.6%). */
.preloader{
  position:fixed; inset:0; z-index:9999;
  background:var(--black);
  display:flex; align-items:center; justify-content:center;
  overflow:hidden;
  transition:opacity .8s var(--ease-out), visibility .8s;
}
.preloader.is-done{ opacity:0; visibility:hidden; pointer-events:none; }

/* cover-cropped: the plate is 2.04:1 and near-black at both edges, so a
   narrow viewport loses only darkness. */
.preloader__plate{
  position:absolute; inset:0;
  background:#04060a url(../img/preloader-bg.jpg) center / cover no-repeat;
  animation:plPlateIn 1.1s var(--ease-out) both;
}
@keyframes plPlateIn{ from{ opacity:0; } to{ opacity:1; } }

.preloader__stage{
  position:relative; top:4vh;          /* drops the stack onto the plate's centre */
  display:flex; flex-direction:column; align-items:center;
  transition:transform .8s var(--ease-out), opacity .5s var(--ease-out), filter .8s var(--ease-out);
}
.preloader.is-done .preloader__stage{ transform:scale(1.07); opacity:0; filter:blur(8px); }

/* ---- logo ---------------------------------------------------------- */
/* logo.png is dark art on a transparent ground, so invert() turns it
   silver — the same treatment the nav uses. Only the emblem belongs here:
   the file's own "SERVICES / MONTAŻ KLIMATYZACJI" lockup sits below it and
   would double the service line, so the crop box clips it off. Measured
   from the source alpha (1254px square): emblem spans x 196–1013,
   y 220–921, centred at 48.21% / 45.49%. */
.preloader__logo{
  position:relative; width:clamp(152px, 19vh, 205px); aspect-ratio:818/702;
  overflow:hidden;
  animation:plLogoIn 1.4s var(--ease-out) .2s both;
}
@keyframes plLogoIn{ from{ opacity:0; transform:scale(.96); } to{ opacity:1; transform:scale(1); } }
.preloader__logo-art{
  position:relative; width:100%; aspect-ratio:1;
  transform-origin:48.21% 45.49%;
  transform:translate(1.79%, -2.58%) scale(1.5);
}
.preloader__logo-art img{ width:100%; height:auto; filter:invert(1) brightness(.86); }

/* The sheen wears the logo's own alpha as a mask, so the highlight travels
   across the artwork and never over the empty ground around it. */
.preloader__sheen{
  position:absolute; inset:0; pointer-events:none;
  background:linear-gradient(100deg,
    transparent 33%, rgba(255,255,255,.22) 43%, rgba(255,255,255,.8) 50%,
    rgba(255,255,255,.22) 57%, transparent 67%);
  background-size:300% 100%;
  -webkit-mask:url(../logo.png) center / 100% 100% no-repeat;
  mask:url(../logo.png) center / 100% 100% no-repeat;
  animation:plSheen 3.8s var(--ease-in-out) infinite;
}
@keyframes plSheen{ 0%{ background-position:195% 0; } 58%,100%{ background-position:-95% 0; } }

/* ---- service line -------------------------------------------------- */
.preloader__sub{
  margin-top:clamp(3.4rem, 13vh, 8rem);
  padding-left:.34em;                  /* offsets the trailing tracking */
  font-family:'Manrope',-apple-system,BlinkMacSystemFont,sans-serif;
  font-weight:400; font-size:clamp(.6rem, 1.45vh, .78rem);
  letter-spacing:.34em; text-transform:uppercase;
  color:rgba(255,255,255,.72);
  animation:plFadeUp .9s var(--ease-out) .75s both;
}
.preloader__sub i{
  font-style:normal; margin:0 1.15em;
  color:rgba(255,255,255,.3);
}
@keyframes plFadeUp{ from{ opacity:0; transform:translateY(8px); } to{ opacity:1; transform:translateY(0); } }

/* ---- load bar ------------------------------------------------------ */
.preloader__bar{
  position:relative;
  margin-top:clamp(1.9rem, 5.6vh, 3.4rem);
  width:clamp(132px, 19vh, 172px); height:1px;
  background:rgba(255,255,255,.13);
  animation:plFadeUp .9s var(--ease-out) .9s both;
}
.preloader__bar i{
  position:absolute; left:0; top:-1px; height:3px; width:0;
  background:linear-gradient(90deg,
    rgba(255,255,255,.75) 0%, #fff 55%, rgba(255,255,255,.4) 100%);
  box-shadow:0 0 10px rgba(255,255,255,.45);
  transition:width .18s linear;
}

@media (prefers-reduced-motion: reduce){
  .preloader__sheen{ animation:none; }
  .preloader__plate, .preloader__logo,
  .preloader__sub, .preloader__bar{ animation-duration:.01ms; animation-delay:0s; }
}

/* ==========================================================================
   CURSOR / GRAIN / SCROLL PROGRESS
   ========================================================================== */
.cursor{ position:fixed; top:0; left:0; z-index:9998; pointer-events:none; mix-blend-mode:difference; }
@media (pointer:coarse){ .cursor{ display:none; } }
.cursor__dot{
  position:fixed; width:6px; height:6px; margin:-3px 0 0 -3px;
  background:var(--silver-100); border-radius:50%;
  transition:transform .15s var(--ease-out), opacity .2s;
}
.cursor__ring{
  position:fixed; width:38px; height:38px; margin:-19px 0 0 -19px;
  border:1px solid var(--silver-300); border-radius:50%;
  transition:width .3s var(--ease-out), height .3s var(--ease-out), margin .3s var(--ease-out), border-color .3s, background .3s, opacity .3s;
}
.cursor.is-hover .cursor__ring{ width:64px; height:64px; margin:-32px 0 0 -32px; background:rgba(255,255,255,.06); border-color:var(--ice); }
.cursor.is-hover .cursor__dot{ transform:scale(0); opacity:0; }
.cursor.is-hidden{ opacity:0; }

.grain{
  position:fixed; inset:-100px; z-index:9997; pointer-events:none; opacity:.035; mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

.scroll-progress{
  position:fixed; top:0; left:0; right:0; height:2px; z-index:9996; pointer-events:none;
  background:transparent;
}
.scroll-progress i{
  display:block; height:100%; width:100%; transform:scaleX(0); transform-origin:left;
  background:linear-gradient(90deg, var(--ice), var(--silver-100));
  box-shadow:0 0 12px var(--ice-dim);
}

/* ==========================================================================
   PAGE VEIL — the cut between index.html and realizacje.html
   Leaving: main.js raises it (.is-on) and navigates once the page is black.
   Arriving at realizacje.html: the page starts under it and it lifts by
   itself in CSS (.page-veil--enter), so a script that never ran cannot leave
   the page covered. The home page arrives under its preloader instead.
   Under the cursor, the grain and the progress hairline, over everything else.
   ========================================================================== */
.page-veil{
  position:fixed; inset:0; z-index:9990; pointer-events:none;
  background:var(--black);
  opacity:0; visibility:hidden;
  transition:opacity .42s var(--ease-in-out), visibility 0s linear .42s;
}
.page-veil.is-on{
  opacity:1; visibility:visible; pointer-events:auto;
  transition:opacity .42s var(--ease-in-out), visibility 0s;
}
.page-veil--enter{ animation:veilLift .75s var(--ease-out) .06s both; }
@keyframes veilLift{
  from{ opacity:1; visibility:visible; }
  to  { opacity:0; visibility:hidden; }
}

/* ==========================================================================
   BUTTONS
   ========================================================================== */
.btn{
  position:relative; display:inline-flex; align-items:center; justify-content:center;
  padding:1rem 2.2rem; border-radius:100px; font-size:.95rem; font-weight:600;
  letter-spacing:-0.01em; overflow:hidden; isolation:isolate;
  transition:transform .5s var(--ease-out), box-shadow .5s var(--ease-out), border-color .4s, background .4s;
}
.btn span{ position:relative; z-index:2; }
.btn--fill{ background:var(--grad-metal); color:#0a0a0a; box-shadow:0 1px 0 rgba(255,255,255,.6) inset, 0 12px 30px -12px rgba(0,0,0,.6); }
.btn--fill:hover{ transform:translateY(-2px); box-shadow:0 1px 0 rgba(255,255,255,.7) inset, 0 18px 40px -12px var(--ice-dim); }
.btn--fill:hover .btn__arrow{ transform:translateX(3px); }
.btn--outline{ border:1px solid var(--line); color:var(--silver-200); backdrop-filter:blur(6px); }
.btn--outline:hover{ border-color:var(--silver-300); background:rgba(255,255,255,.04); transform:translateY(-2px); }
.btn--ghost{ border:1px solid var(--line); color:var(--silver-200); font-size:.82rem; padding:.7rem 1.4rem; }
.btn--ghost:hover{ background:rgba(255,255,255,.06); border-color:var(--silver-300); }
.btn--sm{ padding:.7rem 1.5rem; }
.btn--lg{ padding:1.3rem 3rem; font-size:1.05rem; }
.btn--block{ width:100%; }
.magnetic{ will-change:transform; }

/* ==========================================================================
   NAV
   ========================================================================== */
.nav{
  position:fixed; top:0; left:0; right:0; z-index:500;
  transition:transform .6s var(--ease-in-out), background .5s, border-color .5s, padding .4s;
  padding:1.6rem 0;
  border-bottom:1px solid transparent;
}
.nav.is-scrolled{
  background:rgba(5,5,6,.72); backdrop-filter:blur(16px) saturate(140%);
  border-bottom-color:var(--line); padding:1rem 0;
}
.nav.is-hidden{ transform:translateY(-110%); }
.nav__inner{
  width:var(--container); margin:0 auto;
  display:flex; align-items:center; justify-content:space-between; gap:2rem;
}
.nav__logo{ display:flex; align-items:center; gap:.6rem; }
.nav__logo-img{
  height:40px; width:auto; display:block;
  filter:invert(1) brightness(1.15);
  transition:transform .4s var(--ease-out);
}
.nav__logo:hover .nav__logo-img{ transform:scale(1.04); }
.nav__links{ display:flex; align-items:center; gap:2rem; }
.nav__link{
  position:relative; padding:.3rem 0;
  font-size:.85rem; font-weight:500; letter-spacing:.015em;
  color:rgba(255,255,255,.72); transition:color .3s;
}
.nav__link span{ position:relative; }
.nav__link::after{
  content:''; position:absolute; left:0; bottom:-2px; width:100%; height:1px;
  background:var(--silver-100); transform:scaleX(0); transform-origin:right;
  transition:transform .45s var(--ease-out);
}
.nav__link:hover{ color:#fff; }
.nav__link:focus-visible{ outline:2px solid var(--ice); outline-offset:6px; border-radius:3px; }
.nav__link:hover::after{ transform:scaleX(1); transform-origin:left; }
.nav__link.is-current{ color:var(--silver-100); }
.nav__link.is-current::after{ transform:scaleX(1); background:var(--ice); }
.nav__cta{ display:inline-flex; }
.nav__burger{ display:none; flex-direction:column; gap:5px; width:26px; z-index:410; }
.nav__burger span{ height:1.5px; background:var(--silver-200); transition:transform .3s var(--ease-in-out), opacity .3s; transform-origin:center; }
.nav__burger.is-active span:nth-child(1){ transform:translateY(6.5px) rotate(45deg); }
.nav__burger.is-active span:nth-child(2){ opacity:0; }
.nav__burger.is-active span:nth-child(3){ transform:translateY(-6.5px) rotate(-45deg); }

.mobile-menu{
  position:fixed; inset:0; z-index:400; background:var(--black-soft);
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:1.4rem;
  transform:translateY(-100%); transition:transform .55s var(--ease-in-out);
}
.mobile-menu.is-open{ transform:translateY(0); }
.mobile-menu a{ font-size:1.6rem; color:var(--silver-200); font-family:var(--font-display); font-weight:500; }
.mobile-menu a.btn{ margin-top:1rem; font-size:1rem; }

/* ==========================================================================
   HERO
   ==========================================================================
   One photograph with the product standing in it. img/hero/hero-scene.webp
   is the night terrace (img/hero-bg.png) with the outdoor unit path-traced
   INTO it in Blender Cycles — camera solved from the plate's own lines, lit
   and reflected by the plate's own lights, its feet cut into the plate's
   gravel, its shadow multiplied into the plate. The only moving part is the
   fan behind the grille: pre-rendered frames on a canvas (js/hero-fan.js).
   The pipeline that makes both lives in Documents/agregat-3d/hero.

   Nothing else in .hero__bg is a picture: what is left is a top falloff for
   the nav and a left falloff for the headline.

   Copy holds the left column, the unit the right one — 48/52 from the split
   up to 1300px, 44/56 above it. .hero__stage carries no content: it reserves
   the unit's half of the grid so the copy cannot run under it.
   ========================================================================== */
.hero{
  /* scoped so the rest of the site keeps its own, warmer-black palette */
  --h-bg:      #050607;
  --h-ink:     #f5f5f5;
  --h-ink-2:   rgba(255,255,255,.55);
  --h-line:    rgba(255,255,255,.10);
  --h-accent:  #8ed8ff;

  position:relative; isolation:isolate;
  min-height:100vh;
  min-height:100svh;
  display:flex; align-items:center;
  overflow:hidden;
  padding:clamp(6.5rem,12vh,9rem) 0 clamp(2.5rem,6vh,4.5rem);
  background:var(--h-bg);
}

/* --- lighting rig ------------------------------------------------------- */
.hero__bg{ position:absolute; inset:0; z-index:0; pointer-events:none; }
.hero__bg > div{ position:absolute; inset:0; }

/* THE PHOTOGRAPH IS THE HERO. hero-scene is 3594x1750 (the 1797x875 plate at
   2x, aspect 2.0537) and runs full bleed, native colour, no mask — the job of
   protecting the type belongs to .hero__scrim.

   It is an <img> in a box that REPRODUCES `background-size:cover` (.hero__plate)
   rather than a CSS background, because the fan canvas paints into that same
   box. The box is sized in container units of .hero__photo (the vw/svh line
   before each is only the fallback for browsers without them) and centred —
   except that it never lets the cabinet out of frame: the unit's right edge
   is 86.17% of the image, so the box shifts left just far enough to keep
   89% of it in view. At 16:9 that is a no-op; at 4:3 it is what keeps the
   valve cover on screen. */
.hero__photo{ container-type:size; overflow:hidden; }
.hero__plate{
  position:absolute; top:50%;
  aspect-ratio:3594 / 1750;
  width:max(100vw, 205.37svh);
  left:calc((100vw - max(100vw, 205.37svh)) / 2);
  width:max(100cqw, 205.371cqh);
  left:min(calc((100cqw - max(100cqw, 205.371cqh)) / 2),
           calc(100cqw - 0.89 * max(100cqw, 205.371cqh)));
  transform:translateY(-50%);
}
/* A desktop-width window that is taller than it is wide (iPad Pro upright,
   a narrow browser window): `cover` would blow the cabinet up to most of the
   screen and under the copy. Size it to the right-hand column instead and
   stand it on the bottom of the hero, top faded into the black. */
@media (min-width:960px) and (max-aspect-ratio:1247/1000){
  .hero__plate{
    top:auto; bottom:0; transform:none;
    width:164.7vw; left:calc(100vw - 0.89 * 164.7vw);
    width:164.7cqw; left:calc(100cqw - 0.89 * 164.7cqw);
    -webkit-mask-image:linear-gradient(to bottom, transparent 0, #000 24%);
            mask-image:linear-gradient(to bottom, transparent 0, #000 24%);
  }
}
.hero__plate img{
  position:absolute; inset:0; display:block;
  width:100%; height:100%;
}
/* The fan: a canvas over the whole photo box that repaints the still itself
   and then the frames over the grille (js/hero-fan.js — one raster path, so
   the moving part cannot drift off the photo by a device pixel). It stays
   transparent until it has painted, then fades in over an identical image. */
.hero__fan{
  position:absolute; inset:0; width:100%; height:100%;
  opacity:0; transition:opacity .6s linear;
}
.hero__fan.is-live{ opacity:1; }

/* What is left of the old rig: a slow, almost invisible breath of warmth over
   the plate, plus the top falloff the nav sits in. The cool key and the
   blue-grey wash are gone — the photograph's own light is warm tungsten, and
   layering 142,216,255 over it was fighting the picture instead of lighting
   it. Everything here is under .07 alpha; it is a grade, not a gradient. */
.hero__ambient{
  background:
    radial-gradient(52% 46% at 62% 30%, rgba(255,214,164,.055) 0%, transparent 70%),
    linear-gradient(180deg, rgba(6,8,10,.55) 0%, rgba(6,8,10,.16) 26%, transparent 52%);
  animation:heroAmbient 24s var(--ease-in-out) infinite;
  will-change:transform;
}
@keyframes heroAmbient{
  0%,100%{ transform:translate3d(0,0,0) scale(1);          opacity:.88; }
  50%    { transform:translate3d(-1.2%,1%,0) scale(1.04);  opacity:1;   }
}

/* The only layer between the photograph and the headline, so it carries the
   whole legibility budget on its own — and it has to spend it without
   flattening the left of the frame, where the plate has a lit tree, a hedge
   and a row of uplights worth keeping.

   Two gradients, because the problem is two problems. Almost everything the
   copy sits on is already black: swept block by block, the plate never gets
   past L=30 behind the headline, the subhead or the CTAs. A flat wash heavy
   enough for the exceptions was costing two thirds of the picture everywhere
   else — at .70 the tree went from 19 to 7 and read as a dead silhouette,
   which is paying for contrast with the only thing on that side worth
   looking at.

   The exceptions are two path uplights, at 23%/72% (L=181) and 36%/71%
   (L=174), and they fire straight up through the trust row. They get their
   own pool rather than a heavier wash. Under both layers together they land
   at 55 and 58, which holds 12px rgba(255,255,255,.7) above 4.5:1 on the
   brightest thing under the copy — while the wash alone, at a third of its
   old weight, leaves the tree and the grass clumps two thirds of their own
   light instead of a third. Re-sweep both if the plate ever changes. */
.hero__scrim{
  background:
    radial-gradient(30% 15% at 29.5% 71%, rgba(4,6,8,.66) 0%, rgba(4,6,8,.40) 55%, transparent 82%),
    linear-gradient(90deg,
      rgba(4,6,8,.34) 0%, rgba(4,6,8,.31) 26%, rgba(4,6,8,.19) 44%, rgba(4,6,8,.055) 56%, transparent 64%);
}

/* A LENS treatment, not a plate one: the corners of the frame falling off.
   It sits over the whole picture — unit and fan canvas included — so the
   product never keeps its own brightness right up to an edge the rest of
   the photograph is dropping away at. A child of .hero rather than .hero__bg,
   above it and under .hero__inner at z-index 2. */
.hero__vignette{
  position:absolute; inset:0; z-index:1; pointer-events:none;
  background:radial-gradient(126% 96% at 52% 46%, transparent 46%, rgba(3,4,5,.52) 100%);
}

/* Below the split the rig turns through 90°: the product sits under the copy
   instead of beside it, so the scrim runs top-to-bottom. `cover` at phone
   aspect would crop the 2.054 frame down to a slice of the unit, so the plate
   is framed on the UNIT instead: sized so the cabinet with its valve cover
   (30.36% of the image width, centred at 70.99% — measured off the render's
   alpha) spans ~84% of a phone and ~58% of a tablet, centred, standing at
   the bottom of the hero with its top faded into the black behind the copy. */
@media (max-width:959px){
  .hero__plate{
    top:auto; transform:none;
    width:277vw; left:calc(50vw - 0.7099 * 277vw); bottom:-5vw;
    width:277cqw; left:calc(50cqw - 0.7099 * 277cqw); bottom:-5cqw;
    -webkit-mask-image:linear-gradient(to bottom, transparent 0, #000 24%);
            mask-image:linear-gradient(to bottom, transparent 0, #000 24%);
  }
  .hero__ambient{
    background:
      radial-gradient(64% 36% at 50% 58%, rgba(255,214,164,.05) 0%, transparent 72%),
      linear-gradient(180deg, rgba(6,8,10,.7) 0%, rgba(6,8,10,.2) 30%, transparent 56%);
  }
  .hero__scrim{
    background:linear-gradient(180deg,
      rgba(4,6,8,.90) 0%, rgba(4,6,8,.72) 30%, rgba(4,6,8,.22) 56%, transparent 74%);
  }
}

@media (min-width:600px) and (max-width:959px){
  .hero__plate{
    width:191vw; left:calc(50vw - 0.7099 * 191vw);
    width:191cqw; left:calc(50cqw - 0.7099 * 191cqw);
  }
}

/* --- layout ------------------------------------------------------------- */
.hero__inner{
  position:relative; z-index:2;
  width:var(--container); margin:0 auto;
  display:grid; grid-template-columns:1fr;
  gap:clamp(1.5rem,4vh,3rem);
}
.hero__copy{ min-width:0; }
/* Single column: the reserve under the copy is where the unit stands (the
   plate is anchored to the bottom of the hero below the split), so it has to
   be deep enough that the cabinet's top clears the trust row. */
.hero__stage{ min-height:clamp(330px,98vw,470px); }

@media (min-width:960px){
  .hero__inner{ grid-template-columns:48% 52%; gap:0; align-items:center; }
  .hero__copy{ padding-right:0; }
  .hero__stage{ min-height:min(68svh,620px); }
}
/* 44/56 only once 44% is wide enough for the trust row to hold one line —
   measured at 507px, which the container reaches around 1300px of viewport */
@media (min-width:1300px){
  .hero__inner{ grid-template-columns:44% 56%; }
}

/* --- headline ----------------------------------------------------------- */
/* Two measurements drive every number here. Set in Inter at the tracking
   below, the three lines run 6.09em, 7.28em and 8.46em wide; .line-mask clips
   horizontally as well as vertically for the reveal, so anything the browser
   decides to wrap gets shaved off at the column edge.
   Desktop keeps all three lines whole — 8.46em has to fit the 44% column, and
   4.0rem is the largest cap that does at the 1280px container.
   Below the split the mask is allowed to wrap instead: holding three lines
   there would cost ~7px of type, and a four-line headline at 46px reads far
   better on a phone than a three-line one at 39px. */
.hero__title{
  font-size:clamp(2rem,11.2vw,3.45rem);
  font-weight:500;
  line-height:1.04;
  letter-spacing:-0.015em;
  color:var(--h-ink);
}
@media (min-width:960px){
  .hero__title{ font-size:clamp(2.8rem,4.3vw,3.9rem); line-height:1.02; }
}
.line-mask{
  display:block; width:auto; max-width:100%;
  overflow:hidden; padding-bottom:.06em; margin-bottom:-.06em;
}
@media (min-width:960px){ .line-mask{ width:max-content; } }
.line-inner{ display:inline-block; transform:translateY(115%); will-change:transform; }
.line-inner.is-soft{ color:rgba(245,245,245,.72); }

/* --- description -------------------------------------------------------- */
.hero__subtitle{
  max-width:520px;
  margin-top:clamp(1.3rem,2.6vh,1.75rem);
  font-size:1rem; line-height:1.6; font-weight:400;
  color:var(--h-ink-2);
}

/* --- calls to action ---------------------------------------------------- */
.hero__actions{
  display:flex; flex-wrap:wrap; gap:.75rem;
  margin-top:clamp(1.8rem,3.4vh,2.4rem);
}
.hero__cta{
  position:relative; display:inline-flex; align-items:center; gap:.6rem;
  padding:1rem 1.5rem; border-radius:999px;
  font-size:.925rem; font-weight:600; letter-spacing:-.004em;
  white-space:nowrap; will-change:transform;
  transition:transform .3s var(--ease-out), background .3s var(--ease-out),
             border-color .3s var(--ease-out), box-shadow .3s var(--ease-out), color .3s;
}
.hero__cta--primary{
  background:#fff; color:#07090b;
  box-shadow:0 1px 0 rgba(255,255,255,.85) inset, 0 14px 34px -16px rgba(0,0,0,.95);
}
.hero__cta--primary:hover{
  transform:translateY(-1px);
  box-shadow:0 1px 0 #fff inset, 0 20px 44px -18px rgba(142,216,255,.4);
}
.hero__cta--ghost{
  border:1px solid rgba(255,255,255,.18);
  background:rgba(255,255,255,.012);
  color:rgba(255,255,255,.88);
  backdrop-filter:blur(8px);
}
.hero__cta--ghost:hover{
  transform:translateY(-1px);
  border-color:rgba(255,255,255,.3);
  background:rgba(255,255,255,.05);
  color:#fff;
}
.hero__cta-arrow,
.hero__cta-glyph{ width:15px; height:15px; flex:none; }
.hero__cta-arrow{ transition:transform .3s var(--ease-out); }
.hero__cta--primary:hover .hero__cta-arrow{ transform:translateX(3px); }
.hero__cta-glyph{ color:rgba(255,255,255,.55); transition:color .3s; }
.hero__cta--ghost:hover .hero__cta-glyph{ color:var(--h-accent); }
.hero__cta:focus-visible{ outline:2px solid var(--h-accent); outline-offset:3px; }
@media (min-width:960px) and (max-width:1219px){
  .hero__actions{ flex-direction:column; align-items:flex-start; gap:.65rem; }
  .hero__cta{ width:100%; max-width:290px; justify-content:center; }
}

/* --- trust signals ------------------------------------------------------ */
.hero__trust{
  display:flex; flex-wrap:wrap; align-items:center;
  margin-top:clamp(1.5rem,3vh,2.1rem);
  font-size:.845rem; color:rgba(255,255,255,.65);
}
.hero__trust li{
  position:relative; display:inline-flex; align-items:center; gap:.5rem;
  padding:.25rem 1.05rem; white-space:nowrap;
}
.hero__trust li:first-child{ padding-left:0; }
.hero__trust li + li::before{
  content:''; position:absolute; left:0; top:50%; transform:translateY(-50%);
  width:1px; height:12px; background:rgba(255,255,255,.14);
}
.hero__trust svg{ width:15px; height:15px; flex:none; color:rgba(255,255,255,.7); }
@media (max-width:1299px){
  .hero__trust{ gap:.55rem 1.4rem; }
  .hero__trust li{ padding:.25rem 0; }
  .hero__trust li + li::before{ display:none; }
}

/* --- narrow viewports --------------------------------------------------- */
@media (max-width:959px){
  .hero{ padding:clamp(6rem,15vh,7.5rem) 0 0; }
  .hero__inner{ width:100%; padding:0 24px; }
  .hero__subtitle{ max-width:46ch; }
}
@media (max-width:600px){
  .hero__trust{ gap:.55rem 1.5rem; }
  .hero__trust li{ padding:0; }
  .hero__trust li + li::before{ display:none; }
  .hero__cta{ flex:1 1 100%; justify-content:center; }
}

@media (prefers-reduced-motion:reduce){
  .hero__ambient{ animation:none; }
  .hero__cta{ transition:background .2s, border-color .2s, color .2s; }
  .hero__cta:hover{ transform:none; }
  .hero__cta--primary:hover .hero__cta-arrow{ transform:none; }
}

/* ==========================================================================
   TICKER
   ========================================================================== */
.ticker{
  border-top:1px solid var(--line); border-bottom:1px solid var(--line);
  background:var(--black); overflow:hidden; padding:1.4rem 0;
  display:flex; flex-direction:column; gap:.9rem;
}
.ticker__row{ display:flex; width:max-content; will-change:transform; }
.ticker__set{ display:flex; align-items:center; }
.ticker__set span{
  font-family:var(--font-display); font-size:1.3rem; font-weight:400; letter-spacing:0;
  color:var(--silver-400); padding:0 2.2rem; white-space:nowrap; position:relative;
  opacity:.5; transition:opacity .35s, color .35s;
}
.ticker__set span::after{ content:'◆'; position:absolute; right:-.35rem; top:50%; transform:translateY(-50%); font-size:.45rem; color:var(--silver-500); }
.ticker__row:hover .ticker__set span{ opacity:.85; }

/* ==========================================================================
   WHY US
   The one light section on an otherwise dark site — a deliberate white
   breather right under the hero. Serif heading (Playfair) in a fixed left
   column, six short items in Poppins to its right — set on open whitespace,
   no rules between them: the cell borders read as boxes, so separation is
   done with gap alone. No cards, no boxed icon chips — just a bespoke stroke
   icon per item (draws in via .draw) sitting directly on the page.
   ========================================================================== */
.why{ background:var(--paper); padding:9rem 0; }

.why__inner{ width:var(--container); margin:0 auto; }

/* kicker rule spans the full width first, so heading + grid below read as
   one ruled unit hanging off it, rather than two blocks placed side by side */
.why__top{
  padding-bottom:1.5rem;
  margin-bottom:clamp(3rem, 6vw, 4.75rem);
  border-bottom:1px solid var(--paper-line);
}
.why__tag{
  display:inline-block;
  font-family:var(--font-body); font-size:.75rem; font-weight:500;
  letter-spacing:.16em; text-transform:uppercase; color:var(--ice-deep);
}

.why__body{
  display:grid; grid-template-columns:minmax(240px,360px) 1fr;
  gap:clamp(2.6rem, 6vw, 5rem);
}

/* head stretches to the grid's full height (grid default align-items) so the
   heading can center against it */
.why__head{
  display:flex; align-items:center;
  padding-right:clamp(1.6rem, 3vw, 2.5rem);
}
.why__title{
  font-family:var(--font-display);
  font-size:clamp(2.05rem, 2.9vw, 2.9rem); font-weight:400;
  line-height:1.14; letter-spacing:-.005em;
  color:var(--ink);
}

.why__grid{
  display:grid; grid-template-columns:repeat(3,1fr);
  column-gap:clamp(2rem,3.4vw,3.2rem); row-gap:clamp(2.6rem,4vw,3.6rem);
}

.why__item{ padding:0; }

.why__icon{
  width:28px; height:28px; margin-bottom:1.2rem;
  color:var(--ink); transition:color .5s var(--ease-out);
}
.why__item:hover .why__icon,
.why__item:focus-within .why__icon{ color:var(--ice-deep); }

.why__item-title{
  font-family:var(--font-body);
  font-size:1.05rem; font-weight:500; letter-spacing:0;
  color:var(--ink); margin-bottom:.6rem;
}
.why__item-desc{
  font-family:var(--font-body);
  font-size:.88rem; line-height:1.7; font-weight:300;
  color:var(--ink-dim); max-width:32ch;
}


/* SVG stroke draw-in (JS sets the dash values on scroll) */
.draw path, .draw rect, .draw circle{ transition:stroke-dashoffset 1.2s var(--ease-out); }

/* ==========================================================================
   KALKULATOR
   --------------------------------------------------------------------------
   Two halves with deliberately different materials. On the left the questions
   sit straight on the page ground — no panel, no rules — and get their
   structure from full-width segmented tracks stacked in a rhythm, the way a
   mixing desk reads. On the right, one single milled console: the same
   material language as the (approved) service panels — a case lit along its
   top bevel, a hairline edge that fades at the ends, and a specular pool that
   tracks the pointer — carrying the answer.

   Deliberate choices, having been through both failure modes once each:
   * one panel in the whole section, never a grid of them, so it reads as an
     instrument rather than as cards;
   * the drawing of the recommended unit is bespoke line art, drawn to the
     count the calculation returns — not a stock icon, and not a gauge;
   * no blueprint grid, no reticle, no scanning beam. The only light that
     moves is the specular pool under the cursor and the unit's own airflow.

   overflow:clip, not hidden — `hidden` would make this a scroll container
   and silently kill position:sticky on the console inside.
   ========================================================================== */
.calc{ position:relative; padding:9rem 0; border-top:1px solid var(--line); background:var(--black); overflow:clip; }
.calc__aurora{
  position:absolute; left:50%; top:6%; width:1200px; height:700px; transform:translateX(-50%);
  pointer-events:none; opacity:.15; filter:blur(80px);
  background:
    radial-gradient(closest-side, rgba(143,217,232,.45), transparent 70%) 18% 42%/58% 70% no-repeat,
    radial-gradient(closest-side, rgba(201,205,211,.32), transparent 70%) 82% 28%/55% 60% no-repeat;
  animation:auroraDrift 20s ease-in-out infinite alternate;
}
@keyframes auroraDrift{
  0%{ transform:translateX(-50%) translateY(0) scale(1); }
  100%{ transform:translateX(-46%) translateY(-30px) scale(1.07); }
}

/* The head carries only the kicker and the heading. The lead moved down
   into the questions column, which is what lets the console's top edge line
   up with the heading's last line instead of starting a paragraph lower —
   the gap below is the only thing between them, so keep it small. */
.calc__intro{
  position:relative; z-index:2; width:var(--container); margin:0 auto;
  padding-bottom:clamp(.8rem, 1.1vw, 1.15rem);
}
.calc__lead{
  max-width:600px; margin-bottom:.7rem;
  color:var(--text-dim); font-weight:300; font-size:1.02rem; line-height:1.65;
}

.calc__shell{
  position:relative; z-index:2; width:var(--container); margin:0 auto;
  display:grid; grid-template-columns:1fr minmax(380px, .72fr);
  gap:clamp(2.5rem, 4vw, 4rem);
  align-items:start;
}

/* ==========================  L E F T  ==================================== */
.calc__form{ display:flex; flex-direction:column; gap:clamp(1.9rem, 2.6vw, 2.5rem); }

.q__top{ display:flex; align-items:baseline; justify-content:space-between; gap:1rem; }
.q__label{
  display:block; font-size:1.02rem; font-weight:450; color:var(--silver-100);
  letter-spacing:-.01em; margin-bottom:1rem;
}
.q__top .q__label{ margin-bottom:0; }

/* the value is the loud element of the row — scale, not decoration */
.q__val{
  font-family:var(--font-body); font-size:1.7rem; font-weight:500;
  letter-spacing:-.02em; line-height:1; font-variant-numeric:tabular-nums;
  background:var(--grad-metal); -webkit-background-clip:text; background-clip:text; color:transparent;
}
.q__val em{
  font-size:.82rem; font-style:normal; font-weight:400; margin-left:.35rem;
  color:var(--silver-500); -webkit-text-fill-color:var(--silver-500);
}

/* ---- slider ---- */
.q__range{
  -webkit-appearance:none; appearance:none; width:100%; margin-top:1.15rem;
  height:6px; border-radius:100px; outline:none; cursor:none;
  background:
    linear-gradient(90deg, rgba(143,217,232,.85) 0%, var(--silver-100) var(--fill,20%), rgba(255,255,255,0) var(--fill,20%)),
    rgba(255,255,255,.07);
  box-shadow:0 1px 0 rgba(255,255,255,.05) inset;
}
@media (pointer:coarse){ .q__range{ cursor:pointer; height:8px; } }
.q__range::-webkit-slider-thumb{
  -webkit-appearance:none; appearance:none; width:26px; height:26px; border-radius:50%;
  background:var(--grad-metal);
  box-shadow:
    0 1px 0 rgba(255,255,255,.8) inset,
    0 0 0 1px rgba(0,0,0,.55),
    0 6px 16px -4px rgba(0,0,0,.95);
  transition:transform .3s var(--ease-out), box-shadow .3s;
}
.q__range:hover::-webkit-slider-thumb,
.q__range:focus-visible::-webkit-slider-thumb{
  transform:scale(1.1);
  box-shadow:
    0 1px 0 rgba(255,255,255,.9) inset,
    0 0 0 1px rgba(0,0,0,.55),
    0 0 22px -2px var(--ice-dim);
}
.q__range::-moz-range-thumb{
  width:22px; height:22px; border-radius:50%; background:#e8eaee; border:none;
  box-shadow:0 0 0 1px rgba(0,0,0,.5), 0 6px 16px -4px rgba(0,0,0,.95);
}
.q__range::-moz-range-track{ height:6px; border-radius:100px; background:rgba(255,255,255,.07); }

/* ---- segmented control: one recessed track, one metal pill that slides ---- */
.seg{
  position:relative; display:flex; padding:.3rem;
  border-radius:100px; background:rgba(255,255,255,.04);
  box-shadow:0 1px 0 rgba(255,255,255,.045) inset, 0 -1px 0 rgba(0,0,0,.4) inset;
}
.seg__pill{
  position:absolute; top:.3rem; bottom:.3rem; left:.3rem; width:0;
  border-radius:100px; background:var(--grad-metal);
  box-shadow:0 1px 0 rgba(255,255,255,.7) inset, 0 8px 22px -12px rgba(0,0,0,.95);
  pointer-events:none;
}
.seg__opt{
  position:relative; z-index:2; flex:1 1 0; min-width:0;
  padding:.82rem .6rem; border-radius:100px;
  font-size:.86rem; font-weight:400; color:var(--silver-400); white-space:nowrap;
  transition:color .32s var(--ease-out);
}
.seg:hover{ background:rgba(255,255,255,.055); }
.seg__opt:hover{ color:var(--silver-100); }
.seg__opt:focus-visible,
.q__range:focus-visible,
.stepper__btn:focus-visible,
.toggle:focus-visible{ outline:1px solid var(--ice); outline-offset:3px; }
.seg__opt.is-active{ color:#0a0a0c; font-weight:500; }

/* ---- stepper / toggles pair ---- */
.q--pair{ display:grid; grid-template-columns:auto 1fr; gap:1.4rem 2.6rem; }
.stepper{
  display:inline-flex; align-items:center; gap:.3rem; padding:.3rem;
  border-radius:100px; background:rgba(255,255,255,.04);
  box-shadow:0 1px 0 rgba(255,255,255,.045) inset, 0 -1px 0 rgba(0,0,0,.4) inset;
}
.stepper__btn{
  width:38px; height:38px; border-radius:50%; font-size:1.15rem; color:var(--silver-300);
  display:flex; align-items:center; justify-content:center;
  transition:background .3s, color .3s;
}
.stepper__btn:hover{ background:rgba(255,255,255,.09); color:var(--silver-100); }
.stepper__val{
  min-width:2.8rem; text-align:center; font-family:var(--font-body);
  font-size:1.25rem; font-weight:500; color:var(--silver-100); font-variant-numeric:tabular-nums;
}

.toggles{ display:flex; flex-direction:column; gap:.35rem; }
.toggle{
  display:flex; align-items:center; gap:.85rem; text-align:left;
  font-size:.9rem; font-weight:300; color:var(--silver-400); padding:.3rem 0;
  transition:color .3s;
}
.toggle:hover{ color:var(--silver-100); }
.toggle__box{
  flex:none; width:40px; height:22px; border-radius:100px; position:relative;
  background:rgba(255,255,255,.07);
  box-shadow:0 1px 0 rgba(255,255,255,.05) inset, 0 -1px 0 rgba(0,0,0,.4) inset;
  transition:background .35s;
}
.toggle__box::after{
  content:''; position:absolute; top:3px; left:3px; width:16px; height:16px; border-radius:50%;
  background:var(--silver-400);
  box-shadow:0 2px 5px -2px rgba(0,0,0,.9);
  transition:transform .38s var(--ease-out), background .35s;
}
.toggle.is-on{ color:var(--silver-100); }
.toggle.is-on .toggle__box{ background:rgba(143,217,232,.3); }
.toggle.is-on .toggle__box::after{ transform:translateX(18px); background:var(--silver-100); }

.calc__reset{
  align-self:flex-start; margin-top:.4rem;
  font-size:.8rem; color:var(--silver-500); transition:color .3s;
}
.calc__reset:hover{ color:var(--silver-200); }

/* ==========================  R I G H T  ================================== */
.calc__console{ position:sticky; top:6.5rem; }

/* the milled case: lit top bevel, hairline edge, specular pool under the
   cursor (--mx/--my come from main.js). Depth is built from light; the one
   drop shadow is there to lift the case off the page, not to make it. */
.console{
  position:relative; overflow:hidden; border-radius:26px;
  padding:clamp(1.9rem, 2.4vw, 2.5rem);
  /* the case is translucent, so the aurora behind the section shows through
     it as real depth instead of being painted on */
  backdrop-filter:blur(26px) saturate(1.2);
  -webkit-backdrop-filter:blur(26px) saturate(1.2);
  background:
    radial-gradient(460px 340px at var(--mx,72%) var(--my,4%), rgba(255,255,255,.075), transparent 68%),
    linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,.014) 20%, rgba(255,255,255,0) 52%),
    linear-gradient(168deg, rgba(27,28,33,.84) 0%, rgba(16,17,21,.88) 46%, rgba(9,10,12,.93) 100%);
  box-shadow:
    0 0 0 1px rgba(255,255,255,.06) inset,
    0 42px 90px -46px rgba(0,0,0,.95);
}
/* the lit bevel — brightest mid-span, gone by the corners */
.console::before{
  content:''; position:absolute; left:0; right:0; top:0; height:1px; pointer-events:none;
  background:linear-gradient(90deg, transparent, rgba(255,255,255,.34) 20%, rgba(255,255,255,.5) 52%, rgba(255,255,255,.22) 78%, transparent);
}
.console__glow{
  position:absolute; left:4%; top:2%; width:76%; height:42%;
  pointer-events:none; filter:blur(52px); opacity:.34;
  background:radial-gradient(closest-side, var(--ice-dim), transparent 76%);
  transition:opacity .8s var(--ease-out);
}

.console__cap{
  display:block; font-family:var(--font-body); font-weight:500;
  font-size:.68rem; letter-spacing:.17em; text-transform:uppercase; color:var(--silver-500);
}

.console__value{
  position:relative; display:flex; align-items:baseline; gap:.5rem; margin-top:1rem;
  font-family:var(--font-body); letter-spacing:-.035em; line-height:.9;
}
.console__value span{
  font-size:clamp(4.4rem, 7.4vw, 6.6rem); font-weight:500; font-variant-numeric:tabular-nums;
  background:var(--grad-metal); -webkit-background-clip:text; background-clip:text; color:transparent;
}
/* "2 ×" before the class when the load is split between units */
.console__count{
  font-size:clamp(1.8rem, 3vw, 2.6rem); font-weight:400; color:var(--silver-400);
  letter-spacing:-.02em; margin-right:.1rem;
}
.console__count:empty{ display:none; }
.console__value em{
  font-size:1.35rem; font-style:normal; font-weight:400; color:var(--silver-400);
  background:none; -webkit-text-fill-color:var(--silver-400);
}

.console__meter{
  position:relative; margin-top:1.7rem; height:3px; border-radius:100px;
  background:rgba(255,255,255,.07); box-shadow:0 1px 0 rgba(255,255,255,.04) inset;
}
.console__meter i{
  position:absolute; inset:0 auto 0 0; width:18%; border-radius:100px;
  background:linear-gradient(90deg, rgba(143,217,232,.9), var(--silver-100));
  box-shadow:0 0 14px -1px var(--ice-dim);
}

/* ---- 1 unit / 2 units: the same sliding pill, at console scale ---- */
.console__variant{ margin-top:1.4rem; padding:.22rem; }
.console__variant[hidden]{ display:none; }
.console__variant .seg__pill{ top:.22rem; bottom:.22rem; }
.console__variant .seg__opt{ padding:.55rem .6rem; font-size:.78rem; }

/* ---- recommended unit: bespoke line art drawn to the returned count ---- */
.console__unit{
  margin-top:1.9rem; padding-top:1.7rem;
  border-top:1px solid rgba(255,255,255,.07);
}
/* the unit sits in its own pool of light, the way a product shot is lit from
   below — that pool is what stops the line art reading as an icon */
.unitart{
  position:relative; display:flex; align-items:flex-end; justify-content:center;
  gap:clamp(.6rem, 2vw, 1.4rem);
  margin:.4rem 0 1.5rem; color:var(--silver-200);
}
.unitart::before{
  content:""; position:absolute; left:50%; top:46%; translate:-50% 0;
  width:104%; height:150%; pointer-events:none; z-index:0;
  background:radial-gradient(48% 42% at 50% 34%, rgba(255,255,255,.075), transparent 72%);
}
.unitart svg{ position:relative; z-index:1; width:100%; height:auto; overflow:visible; }
.unitart[data-count="1"] svg{ max-width:none; }
.unitart[data-count="2"] svg{ width:47%; }
.unitart[data-count="3"] svg{ width:31%; }
.unitart__more{
  font-family:var(--font-body); font-size:1.05rem; font-weight:500;
  letter-spacing:-.02em; padding-bottom:.9rem;
  background:var(--grad-metal); -webkit-background-clip:text; background-clip:text; color:transparent;
}
/* the unit's own airflow, the only moving light besides the specular pool */
.unitart .air{ animation:airDrift 6s linear infinite; }
.unitart .air:nth-of-type(2){ animation-duration:7.6s; }
.unitart .air:nth-of-type(3){ animation-duration:9.2s; }
@keyframes airDrift{ to{ stroke-dashoffset:-54; } }

.console__reco{
  font-family:var(--font-display); font-size:1.95rem; font-weight:500;
  color:var(--silver-100); letter-spacing:-.01em; margin:.75rem 0 .65rem;
}
.console__reco b{ font-weight:500; color:var(--ice); }
.console__desc{ font-size:.89rem; color:var(--silver-400); font-weight:300; line-height:1.62; }

.console .btn{ margin-top:2rem; }
.console__note{
  margin-top:.95rem; font-size:.72rem; color:var(--silver-500);
  font-weight:300; line-height:1.5; text-align:center;
}
/* the floating result dock is a phone thing — see the phones block */
.calc__dock{ display:none; }


/* ==========================================================================
   SOLUTIONS — where the same install shows up
   Full-bleed photo backdrop (img/solutions-bg.jpg) behind the section head,
   graded dark to sit at this site’s near-black palette. The four categories
   below are photo tiles, but the caption is NOT burned onto the picture:
   each tile is a framed photograph with its title and description set
   underneath, on the section ground. That keeps the photo readable as a
   photo (no scrim eating its bottom third) and the type readable as type —
   same "no card chrome" rule as elsewhere: no border, no fill, no icon
   chip behind the text. The boldness comes from the photograph and the
   scale change on hover, nothing else.
   ========================================================================== */
.solutions{
  --solutions-photo: url("../img/solutions-bg.jpg");
  position:relative; padding:9rem 0; overflow:hidden; background:var(--black);
}
.solutions__bg{
  position:absolute; inset:0; z-index:0; pointer-events:none;
  background-image:var(--solutions-photo,none);
  background-size:cover; background-position:50% 30%;
  filter:brightness(.48) contrast(1.1) saturate(.8);
}
.solutions__scrim{
  position:absolute; inset:0; z-index:1; pointer-events:none;
  background:
    linear-gradient(90deg, rgba(3,4,5,.65) 0%, rgba(3,4,5,.15) 48%, rgba(3,4,5,.3) 100%),
    linear-gradient(180deg, var(--black) 0%, rgba(3,4,5,.45) 22%, rgba(3,4,5,.55) 78%, var(--black) 100%);
}
.solutions .section-head,
.solutions__grid{ position:relative; z-index:2; }
/* the lead sits on the photo, not on black — the default dim grey sank into it */
.solutions .section-lead{ color:var(--silver-300); }

.solutions__grid{
  width:var(--container); margin:0 auto;
  display:grid; grid-template-columns:repeat(4,1fr); gap:1.5rem 1.25rem;
  align-items:start;
}

.solutions__item{ position:relative; --tile-b:.85; --tile-s:.88; }

/* Per-tile grading. The four source photographs arrive at different
   exposures and casts, so a single shared filter would leave the row looking
   like four unrelated shots. These values pull each one to roughly the same
   on-screen weight instead (painted mean luma at 1440px: 45 / 45 / 44 / 43) —
   the office render knocked well down; the commercial frame (AI-generated,
   blue-hour site containers) desaturated toward the row's warm black with a
   touch of sepia, so a hint of dusk blue stays and the lit windows still glow;
   the service frame (AI-generated, a technician washing an outdoor unit)
   lifted, because it is almost all shadow with one lamp in it. */
.solutions__item--home{       --tile-b:.88; --tile-s:.88; }
.solutions__item--office{     --tile-b:.49; --tile-s:.80; }
.solutions__item--commercial{ --tile-b:.84; --tile-s:.72; --tile-sep:.22; }
.solutions__item--service{    --tile-b:.92; --tile-s:.85; --tile-sep:.06; }

/* --- the photograph --- */
.solutions__item-media{
  position:relative; overflow:hidden; border-radius:14px;
  aspect-ratio:4/3; isolation:isolate; background:#0a0b0d;
}
.solutions__item-media img{
  width:100%; height:100%; object-fit:cover; display:block;
  filter:brightness(var(--tile-b)) saturate(var(--tile-s)) sepia(var(--tile-sep,0));
  transform:scale(1.001);
  transition:filter .6s var(--ease-out), transform 1.4s var(--ease-out);
}
/* a whisper of edge so the frame reads against the backdrop photo, not a card border */
.solutions__item-media::after{
  content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  border-radius:inherit;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.06);
}
.solutions__item:hover .solutions__item-media img,
.solutions__item:focus-within .solutions__item-media img{
  filter:brightness(calc(var(--tile-b) * 1.28)) saturate(1) sepia(calc(var(--tile-sep,0) * .5));
  transform:scale(1.05);
}

/* --- the caption, set below the photo rather than over it --- */
.solutions__item-body{ padding:1.05rem .15rem 0; }
.solutions__item-title{
  font-family:var(--font-body);
  font-size:1.02rem; font-weight:500; letter-spacing:-.005em;
  color:#fff; margin-bottom:.2rem; line-height:1.3;
}
/* One title runs to two lines while the rest sit on one; reserving both lines
   keeps every description starting on the same baseline across the row. */
@media (min-width:641px){
  .solutions__item-title{ min-height:2.6em; }
}
.solutions__item-desc{
  font-size:.85rem; line-height:1.55; font-weight:300;
  color:var(--silver-400, rgba(255,255,255,.62));
}

@media (max-width:1024px){
  .solutions__grid{ grid-template-columns:repeat(2,1fr); gap:2rem 1.25rem; }
}
@media (max-width:640px){
  .solutions__grid{ grid-template-columns:1fr; gap:2.25rem; }
  .solutions__item-media{ aspect-ratio:16/10; }
}

/* ==========================================================================
   SHOWCASE — realizacje + opinie klientów
   One rounded shell clipping two flush-adjoining halves (no gap) so the pair
   reads as a single bento component: a dark "realizacje" half (copy + a
   3-photo bento cut from the photographs of realizacje.html) sitting directly
   against a white "opinie" half (single-card testimonial carousel, authors
   anonymous). The white half reuses the same
   --paper/--ink tokens as .why rather than inventing new colour — it's the
   site's only other deliberate light surface.
   ========================================================================== */
.showcase{ padding:9rem 0; border-top:1px solid var(--line); }
.showcase__grid{
  width:var(--container); margin:0 auto; display:grid;
  grid-template-columns:3fr 2fr; border-radius:28px; overflow:hidden;
}
.showcase__col{ display:flex; }

.showcase__col--work{
  background:var(--black-soft);
  align-items:center; gap:clamp(1.8rem,4vw,3.2rem);
  padding:clamp(2.8rem,5vw,4.5rem) clamp(1.8rem,4vw,3rem);
}
.showcase__col--work .showcase__head{ flex:0 0 clamp(200px,25vw,300px); }

.showcase__col--reviews{
  background:var(--paper); flex-direction:column; justify-content:center;
  padding:clamp(2.8rem,5vw,4.5rem) clamp(1.8rem,4vw,3.2rem);
}
.showcase__col--reviews .section-tag{ color:var(--ice-deep); }
.showcase__col--reviews .section-title{
  color:var(--ink); font-size:clamp(1.6rem,2.4vw,2.3rem); margin-bottom:0;
}
.section-title__accent{ color:var(--ice-deep); }

.showcase__head{ margin-bottom:1.8rem; }
.showcase__head .section-lead{ margin-top:1rem; }
.showcase__head .btn{ margin-top:1.7rem; }

.showcase__gallery{
  flex:1; min-width:0; align-self:stretch; min-height:420px;
  display:grid; grid-template-columns:1.6fr 1fr; gap:.9rem;
}
.showcase__photo-stack{ display:grid; grid-template-rows:1fr 1fr; gap:.9rem; min-width:0; }
.showcase__photo{ position:relative; display:block; border-radius:16px; overflow:hidden; min-height:0; }
/* The three tiles are three of the four photographs on realizacje.html — the
   same files, and the same resting grade as .work__media img there: --b is
   that page's per-photo brightness (set on the tile in index.html), times the
   same .9 dim and .9 desaturation, lifting to full on hover. So the preview
   and the page it opens onto read as one set. --pos picks the slice of the
   photograph that the tall, narrow tile shows. */
.showcase__photo img{
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; object-position:var(--pos, 50% 50%);
  filter:brightness(calc(var(--b, 1) * .9)) saturate(.9);
  transform:scale(1.001);
  transition:filter .6s var(--ease-out), transform 1.4s var(--ease-out);
}
.showcase__photo:hover img,
.showcase__photo:focus-visible img{ filter:brightness(calc(var(--b, 1) * 1.02)) saturate(1); transform:scale(1.05); }

/* Each photo is a door to realizacje.html. On hover the frame darkens at its
   foot and says where it leads — the only label it ever wears, and only
   where there is a pointer to hover with. */
.showcase__photo::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:58%; z-index:1;
  pointer-events:none;
  background:linear-gradient(to top, rgba(3,4,5,.78), rgba(3,4,5,0));
  opacity:0; transition:opacity .55s var(--ease-out);
}
.showcase__photo-cta{
  position:absolute; left:1.15rem; bottom:1rem; z-index:2;
  display:inline-flex; align-items:center; gap:.5rem;
  font-size:.8rem; font-weight:500; letter-spacing:.01em; color:#fff;
  opacity:0; transform:translateY(8px);
  transition:opacity .45s var(--ease-out), transform .55s var(--ease-out);
}
.showcase__photo-cta svg{ width:14px; height:14px; flex:none; }
/* the two small tiles are only ~118px wide: a tighter label, boxed on both
   sides, so the wrapped text leaves the arrow its margin instead of pushing
   it against the edge of the tile */
.showcase__photo-stack .showcase__photo-cta{ left:.75rem; right:.75rem; bottom:.8rem; font-size:.76rem; }
.showcase__photo:hover::after,
.showcase__photo:focus-visible::after{ opacity:1; }
.showcase__photo:hover .showcase__photo-cta,
.showcase__photo:focus-visible .showcase__photo-cta{ opacity:1; transform:none; }
.showcase__photo:focus-visible{ outline:2px solid var(--ice); outline-offset:3px; }
@media (hover:none){
  .showcase__photo::after, .showcase__photo-cta{ display:none; }
}

.btn__arrow{ width:15px; height:15px; flex:none; margin-left:.55rem; transition:transform .3s var(--ease-out); }
.btn--outline:hover .btn__arrow{ transform:translateX(3px); }

/* --- opinie klientów: single-card carousel -------------------------- */
.reviews{ position:relative; margin-top:clamp(1.6rem,3vw,2.4rem); }
.reviews__quote-mark{ display:block; width:32px; height:24px; color:var(--quote-mark); margin-bottom:1.1rem; }
.reviews__quote-mark svg{ width:100%; height:100%; }

.reviews__stage{ display:grid; }
.reviews__stage .review{
  grid-area:1/1; opacity:0; visibility:hidden; pointer-events:none;
  transition:opacity .5s var(--ease-out);
}
.reviews__stage .review.is-active{ opacity:1; visibility:visible; pointer-events:auto; }

.review__quote{ font-size:1.05rem; font-weight:400; line-height:1.6; color:var(--ink); }
.review__foot{ display:flex; align-items:center; gap:.9rem; margin-top:1.6rem; }
/* No name, surname or portrait — a review is signed by the kind of place it
   was written about (GDPR), set like the section tag above it. */
.review__who{
  flex:1; min-width:0;
  font-size:.74rem; font-weight:500; letter-spacing:.14em; text-transform:uppercase;
  color:var(--ink-dim);
}
.review__stars{ display:inline-flex; gap:3px; color:var(--star-gold); flex:none; }
.review__stars svg{ width:13px; height:13px; }

.reviews__nav{ display:flex; align-items:center; gap:.6rem; justify-content:flex-end; margin-top:1.8rem; }
.reviews__count{
  margin-right:auto;
  font-size:.78rem; font-weight:500; letter-spacing:.14em; color:var(--ink-dim);
  font-variant-numeric:tabular-nums;
}
.reviews__arrow{
  width:38px; height:38px; border-radius:50%; flex:none;
  border:1px solid var(--paper-line); color:var(--ink);
  display:flex; align-items:center; justify-content:center;
  transition:background .3s, border-color .3s, color .3s, transform .3s var(--ease-out);
}
.reviews__arrow svg{ width:15px; height:15px; }
.reviews__arrow:hover{ background:var(--ink); border-color:var(--ink); color:var(--paper); transform:translateY(-1px); }

/* ==========================================================================
   FAQ
   ========================================================================== */
.faq{ padding:9rem 0; border-top:1px solid var(--line); }
.faq__list{ width:min(900px, 92vw); margin:0 auto; display:flex; flex-direction:column; }
.faq__item{ border-bottom:1px solid var(--line); }
.faq__item summary{
  display:flex; align-items:center; justify-content:space-between; gap:2rem;
  padding:1.7rem .4rem; cursor:none; list-style:none;
  font-size:clamp(1rem,1.6vw,1.15rem); color:var(--silver-200); font-weight:500;
  transition:color .35s;
}
@media (pointer:coarse){ .faq__item summary{ cursor:pointer; } }
.faq__item summary::-webkit-details-marker{ display:none; }
.faq__item summary:hover{ color:var(--silver-100); }
.faq__ico{
  flex:none; position:relative; width:18px; height:18px;
  transition:transform .45s var(--ease-out);
}
.faq__ico::before, .faq__ico::after{
  content:''; position:absolute; left:50%; top:50%; background:var(--ice); border-radius:2px;
  transform:translate(-50%,-50%);
}
.faq__ico::before{ width:14px; height:1.5px; }
.faq__ico::after{ width:1.5px; height:14px; transition:transform .45s var(--ease-out), opacity .35s; }
.faq__item[open] .faq__ico{ transform:rotate(180deg); }
.faq__item[open] .faq__ico::after{ transform:translate(-50%,-50%) scaleY(0); opacity:0; }
.faq__body{ overflow:hidden; }
.faq__body p{
  padding:0 3rem 1.9rem .4rem; color:var(--text-dim); font-weight:300; line-height:1.7; font-size:.96rem;
}

/* ==========================================================================
   CONTACT — full-bleed photo CTA band (same photo+scrim recipe as
   .solutions below; img/hero-bg.png reused since its empty dark left /
   lit architecture right composition already matches this band's
   heading-left, details-right split — see the note on the section in
   index.html).
   ========================================================================== */
.contact{
  --contact-photo: url("../img/hero-bg.png");
  position:relative; overflow:hidden; background:var(--black);
  padding:8rem 0 6rem;
}
.contact__bg{
  position:absolute; inset:0; z-index:0; pointer-events:none;
  background-image:var(--contact-photo,none);
  background-size:cover; background-position:70% 38%;
  filter:brightness(.85) contrast(1.05) saturate(.92);
}
.contact__scrim{
  position:absolute; inset:0; z-index:1; pointer-events:none;
  background:
    linear-gradient(100deg, rgba(3,4,5,.6) 0%, rgba(3,4,5,.18) 45%, rgba(3,4,5,.42) 100%),
    linear-gradient(180deg, var(--black) 0%, rgba(3,4,5,.05) 14%, rgba(3,4,5,.1) 80%, var(--black) 100%);
}
.contact__grid{
  position:relative; z-index:2; width:var(--container); margin:0 auto;
  display:grid; grid-template-columns:1fr 1.15fr; gap:4rem; align-items:center;
}
.contact__title{ font-size:clamp(2.1rem, 3.6vw, 3.2rem); line-height:1.12; color:#fff; }
.contact__body{ display:flex; flex-direction:column; align-items:flex-start; gap:1.8rem; }
.contact__lead{ color:rgba(255,255,255,.7); font-weight:300; font-size:1.02rem; line-height:1.65; max-width:480px; }
.contact__reach{ display:flex; flex-wrap:wrap; gap:1.8rem 3rem; }
.contact__reach-item{ display:flex; flex-direction:column; gap:.4rem; }
.contact__reach-item span{ font-size:.76rem; letter-spacing:.1em; text-transform:uppercase; color:rgba(255,255,255,.5); }
.contact__reach-item strong{ font-family:var(--font-body); font-weight:500; font-size:1.25rem; color:#fff; transition:color .3s; }
.contact__reach-item:hover strong{ color:var(--ice); }

/* ==========================================================================
   FOOTER — slim single-row bar, sits flush under .contact (no gap) so the
   two read as one dark unit.
   ========================================================================== */
.footer{ position:relative; overflow:hidden; isolation:isolate; border-top:1px solid var(--line); background:var(--black); padding:2.4rem 0 2rem; min-height:calc(min(1100px,92vw) / 5.17 + 2.5rem); }
.footer__bar, .footer__bottom{ position:relative; z-index:1; }
/* three equal-weight columns, so the links sit on the page's true centre
   (with space-between they drifted left, pushed by the wide meta block) */
.footer__bar{
  width:var(--container); margin:0 auto;
  display:grid; grid-template-columns:1fr auto 1fr; align-items:center; gap:2.5rem;
}
.footer__logo{ display:flex; align-items:center; flex:none; justify-self:start; }
.footer__meta{ justify-self:end; }
.footer__nav{ display:flex; align-items:center; gap:1.8rem; flex-wrap:wrap; }
.footer__nav a{ font-size:.88rem; color:var(--silver-300); transition:color .3s; }
.footer__nav a[href]:hover{ color:var(--silver-100); }
.footer__meta{ display:flex; flex-direction:column; align-items:flex-end; gap:.6rem; }
.footer__social{ display:flex; gap:.7rem; }
.footer__social a{
  width:34px; height:34px; border:1px solid var(--line); border-radius:50%;
  display:flex; align-items:center; justify-content:center; color:var(--silver-300);
  transition:border-color .3s, color .3s, transform .3s var(--ease-out);
}
.footer__social a svg{ width:15px; height:15px; }
.footer__social a:hover{ border-color:var(--ice); color:var(--ice); transform:translateY(-2px); }
.footer__address{ font-size:.8rem; color:var(--text-dim); }
.footer__contact{ font-size:.85rem; color:var(--silver-500); }
.footer__contact a{ color:var(--silver-300); transition:color .3s; }
.footer__contact a:hover{ color:var(--ice); }
.footer__bottom{ width:var(--container); margin:1.8rem auto 0; padding-top:1.6rem; border-top:1px solid var(--line-soft); }
.footer__bottom p{ font-size:.78rem; color:var(--silver-500); text-align:center; }

/* Signature wordmark — last thing on the page. The PNG is grey on pure black,
   so mix-blend-mode:screen drops the black and leaves only the strokes; the
   mask feathers the edges, opacity keeps it a whisper. Rises in on scroll. */
.footer__mark{
  position:absolute; z-index:0; left:0; right:0; bottom:0; width:min(1100px,92vw); margin:0 auto; pointer-events:none; user-select:none;
  opacity:0; transform:translateY(18px); transition:opacity 1.8s var(--ease-out), transform 1.8s var(--ease-out);
}
.footer__mark.is-in{ opacity:.42; transform:none; }
.footer__mark img{
  display:block; width:100%; height:auto; mix-blend-mode:screen;
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 14%,#000 86%,transparent 100%);
          mask-image:linear-gradient(90deg,transparent 0,#000 14%,#000 86%,transparent 100%);
}
@media (prefers-reduced-motion:reduce){ .footer__mark{ opacity:.42; transform:none; transition:none; } }

/* ==========================================================================
   REALIZACJE — the subpage (realizacje.html)
   --------------------------------------------------------------------------
   Reached only from the Realizacje section of the home page — the "Zobacz
   więcej realizacji" button and the three photos — and on purpose absent
   from the nav, the mobile menu and the footer there.

   Four kinds of object, one row each — kontenery, żłobki, mieszkania, domy:
   a photograph and a short note, the photograph swapping sides row to row.
   Deliberately NOT a gallery. An 18-tile version with a category filter was
   rejected as far too much, so the page says what we do in four statements
   and stops. No card chrome: the photograph is the material and the type
   sits on the page ground. Nothing here is new vocabulary — the numeral is
   the --grad-metal idiom, the headline is the hero's line reveal, the
   closing band is the home page's .contact, photograph and all.

   The header is a full-screen cover, like the home hero: the headline set
   bottom-left over one photograph (below).
   ========================================================================== */
.works-hero{
  position:relative; isolation:isolate; overflow:hidden;
  display:flex; align-items:flex-end;
  min-height:100vh;
  min-height:100svh;
  padding:clamp(8rem, 17vh, 11rem) 0 clamp(3.2rem, 7vh, 5rem);
  background:var(--black);
}

/* THE PHOTOGRAPH: img/realizacje/tlo-naglowka.jpg, supplied by the client
   ("background na rela.png" in the project root is its lossless original) —
   night, two outdoor units with the PW Services print, lit by their wall
   lamps on the right, a moon over the left of the sky. 1764x891 (aspect
   1.98). Two things decide the crop:
     - the units are the subject: the box is pinned to the right edge, so the
       whole cabinet stays in frame at any width;
     - the moon (centre x 388.6, y 352.8) is the brightest thing on the
       left. Under the headline it turns into a smudge; beside the small
       back link it reads as a bullet point. It may only be in the sky —
       left of the copy and clear above it — or out of frame.
   Where the moon goes depends on where the copy ends up, which CSS cannot
   see, so the inline script after the header in realizacje.html frames the
   picture (inline width/top) and this rule is only its safe default: the
   box grown past `cover` until the moon sits 50px past the left edge
   (1.2825 = 1764 / 1375.4, the moon's distance from the right edge),
   standing 30% of its overflow above the header so the wall lamps stay in.
   An <img> in a size container rather than a CSS background, because
   `cover` alone can only fill the header, never push a point of the picture
   where it has to go. The vw/svh line before each is the fallback for
   browsers without container units. */
.works-hero__bg{
  position:absolute; inset:0; z-index:0; pointer-events:none;
  overflow:hidden; container-type:size;
}
.works-hero__photo{
  position:absolute; right:0; top:30%;
  max-width:none; height:auto;
  width:max(100vw, 197.98svh, calc(1.2825 * (100vw + 50px)));
  width:max(100cqw, 197.98cqh, calc(1.2825 * (100cqw + 50px)));
  transform:translateY(-30%);
}
/* Upright screens: the header is taller than wide and the copy spans it, so
   the picture is framed on the larger unit instead — full height, the
   cabinet and its hose run (x 1385–1756) in view, the moon far out of frame —
   and the copy sits over its lower half, which the scrim takes down to
   black. The script leaves this one to CSS. (0.9 = (1764 − 1756) / 891 · 100:
   the far end of the hose lands on the screen edge.) */
@media (max-aspect-ratio:1/1){
  .works-hero__photo{
    top:0; transform:none;
    width:auto; height:100%;
    right:-0.9svh;
    right:-0.9cqh;
  }
}

.works-hero__scrim{
  position:absolute; inset:0; z-index:1; pointer-events:none;
  background:
    linear-gradient(90deg, rgba(3,3,4,.72) 0%, rgba(3,3,4,.3) 48%, rgba(3,3,4,.08) 100%),
    linear-gradient(180deg, rgba(3,3,4,.6) 0%, rgba(3,3,4,0) 30%, rgba(3,3,4,.22) 64%, var(--black) 100%);
}
.works-hero__inner{ position:relative; z-index:2; width:var(--container); margin:0 auto; }

.works-back{
  display:inline-flex; align-items:center; gap:.6rem;
  margin-bottom:clamp(2.2rem, 6vh, 3.6rem);
  font-size:.74rem; font-weight:500; letter-spacing:.16em; text-transform:uppercase;
  color:rgba(255,255,255,.55);
  transition:color .35s;
}
.works-back svg{ width:15px; height:15px; flex:none; transition:transform .35s var(--ease-out); }
.works-back:hover{ color:#fff; }
.works-back:hover svg{ transform:translateX(-3px); }
.works-back:focus-visible{ outline:2px solid var(--ice); outline-offset:6px; border-radius:3px; }

.works-hero__title{
  font-size:clamp(2.7rem, 7vw, 6rem);
  font-weight:500; line-height:1.02; letter-spacing:-.018em;
  color:var(--silver-100);
}
.works-hero__lead{
  max-width:54ch; margin-top:clamp(1.5rem, 3.2vh, 2.2rem);
  font-size:clamp(.98rem, 1.1vw, 1.08rem); font-weight:300; line-height:1.7;
  color:rgba(255,255,255,.58);
}

/* --- one row per kind of object ------------------------------------------- */
/* 12 columns: the photograph takes 7, the note 4, and the column between
   them is air. .work--flip mirrors the row. */
.works{ position:relative; padding:clamp(1.5rem, 4vh, 3rem) 0 clamp(6rem, 13vh, 9.5rem); }
.work{
  width:var(--container); margin:0 auto;
  display:grid; grid-template-columns:repeat(12, minmax(0, 1fr));
  column-gap:clamp(1rem, 2vw, 2rem); align-items:center;
}
.work + .work{ margin-top:clamp(5rem, 10vw, 8.5rem); }
.work__media{ grid-column:1 / span 7; grid-row:1; }
.work__body{ grid-column:9 / span 4; grid-row:1; }
.work--flip .work__media{ grid-column:6 / span 7; }
.work--flip .work__body{ grid-column:1 / span 4; }

/* Each photograph carries its own resting brightness (--b, from its measured
   luma — the bright nursery comes down, the grey site stays near its own)
   and its own crop focus (--pos). Hover lifts it to full. */
.work__media{
  position:relative; overflow:hidden; isolation:isolate;
  aspect-ratio:4 / 3; border-radius:18px; background:#0b0c0e;
}
.work__media img{
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; object-position:var(--pos, 50% 50%);
  filter:brightness(calc(var(--b, 1) * .9)) saturate(.9);
  transform:scale(1.001);
  transition:filter .8s var(--ease-out), transform 1.8s var(--ease-out);
}
/* a whisper of edge so the frame still reads against the black page */
.work__media::after{
  content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  border-radius:inherit; box-shadow:inset 0 0 0 1px rgba(255,255,255,.06);
}
.work:hover .work__media img{
  filter:brightness(calc(var(--b, 1) * 1.02)) saturate(1);
  transform:scale(1.03);
}

.work__kicker{ display:flex; align-items:baseline; gap:1rem; margin-bottom:1.3rem; }
.work__num{
  font-family:var(--font-body); font-size:clamp(2.4rem, 3.6vw, 3.3rem); font-weight:500;
  letter-spacing:-.04em; line-height:.9; font-variant-numeric:tabular-nums;
  background:var(--grad-metal); -webkit-background-clip:text; background-clip:text; color:transparent;
  opacity:.5; transition:opacity .6s var(--ease-out);
}
.work:hover .work__num{ opacity:.9; }
.work__cat{
  font-size:.72rem; font-weight:500; letter-spacing:.16em; text-transform:uppercase;
  color:var(--ice);
}
.work__title{
  font-size:clamp(1.8rem, 2.9vw, 2.7rem); font-weight:500; line-height:1.1;
  color:var(--silver-100);
}
.work__desc{
  margin-top:1.15rem; max-width:44ch;
  font-size:1rem; font-weight:300; line-height:1.72; color:var(--silver-400);
}

/* below the split each row stacks: photograph, then its note */
@media (max-width:900px){
  .work{ row-gap:1.9rem; }
  .work__media, .work--flip .work__media{ grid-column:1 / -1; grid-row:1; }
  .work__body, .work--flip .work__body{ grid-column:1 / -1; grid-row:2; }
  .work__desc{ max-width:60ch; }
}
@media (max-width:640px){
  .works-hero{ padding-top:clamp(7.5rem, 20vh, 9rem); }
  .work__media{ border-radius:16px; }
  .work + .work{ margin-top:4.5rem; }
  .work__kicker{ margin-bottom:1rem; }
}


/* ==========================================================================
   REVEAL BASE (GSAP animates these in; .no-motion is the fallback)
   ========================================================================== */
[data-reveal]{ opacity:0; transform:translateY(36px); }
[data-row]{ opacity:0; transform:translateY(20px); }
/* what follows the headline on a page without the preloader (realizacje.html)
   — played by main.js right after the headline's line reveal */
[data-intro]{ opacity:0; transform:translateY(18px); }
.no-motion [data-reveal],
.no-motion [data-row],
.no-motion [data-intro]{ opacity:1 !important; transform:none !important; }
.no-motion .line-inner{ transform:none !important; }

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */
@media (max-width:1180px){
  /* stacked: the console stops being a sidebar and becomes the closing
     statement under the questions, still a case, just a wider one */
  .calc__shell{ grid-template-columns:1fr; gap:3rem; }
  .calc__console{ position:static; }
  .console{ padding:clamp(1.9rem, 3.4vw, 2.6rem); }
  .console__value{ margin-top:.8rem; }

  /* a laptop is too narrow for a heading column beside three reasons (they
     came down to ~150px each) and for the showcase's head + bento + reviews
     side by side (the button broke onto two lines) — both stack here */
  .why__body{ grid-template-columns:1fr; gap:0; }
  .why__head{ padding-right:0; margin-bottom:clamp(2.4rem,5vw,3.2rem); }

  .showcase__grid{ grid-template-columns:1fr; border-radius:22px; }
  .showcase__col--work{ flex-direction:column; align-items:stretch; }
  .showcase__col--work .showcase__head{ flex:none; margin-bottom:2.2rem; }
  .showcase__gallery{ min-height:360px; }
}
@media (max-width:1024px){
  .contact__grid{ grid-template-columns:1fr; gap:3.5rem; }
}
@media (max-width:900px){
  .showcase__gallery{ min-height:320px; }
  .why__grid{ grid-template-columns:repeat(2,1fr); }
}
@media (max-width:820px){
  .nav__links, .nav__cta{ display:none; }
  .nav__burger{ display:flex; }
  .footer__bar{ display:flex; flex-direction:column; align-items:flex-start; gap:1.6rem; }
  .footer__meta{ align-items:flex-start; }
  .footer__mark{ bottom:.4rem; }
}
@media (max-width:640px){
  body{ cursor:auto; }
  .cursor{ display:none; }
  .why, .calc, .showcase, .faq, .contact{ padding-top:6rem; padding-bottom:6rem; }

  .showcase__gallery{ grid-template-columns:1fr; }
  .showcase__photo-stack{ grid-template-columns:1fr 1fr; grid-template-rows:none; }
  .showcase__photo{ aspect-ratio:4/3; }
  .showcase__photo--main{ aspect-ratio:16/10; }

  .why__grid{ grid-template-columns:1fr; }

  .contact__bg{ background-position:80% 30%; }
  .contact__reach{ gap:1.4rem 2.2rem; }
}

/* --- phones -------------------------------------------------------------
   Everything below is the phone layout only. It starts at 820px, where the
   nav turns into the burger — the site's own line between "desktop" and
   "mobile" — so the desktop layout above it never sees any of it. */
@media (max-width:820px){
  /* HERO = EXACTLY ONE SCREEN. Two rows: the copy at its natural height, and
     whatever the screen has left — that row is the unit's stage. The photo
     layer is placed in the stage row (an absolutely positioned grid child takes
     its grid area as containing block) and reaches 45% of the row up behind the
     copy, which is where the plate's own top fade happens. The plate is then
     sized off that box: by width on a tall phone (the cabinet at the old 84%),
     by height on a short one, so the lid always lands just under the trust row
     instead of under the buttons. Geometry: the cabinet's lid is 31% down the
     image, its feet 86%; plate bottom sits 1.8% of its width below the hero.
     206.1cqh = 2.0537 * 0.95 / (0.6529 * 1.45) — lid 5% of the row below it.
     svh, not vh: on a phone that is the screen with the browser bars showing
     (an iPhone in Safari is ~390x664, not 390x844), so every vertical step in
     the copy scales with it — the stage is what the short screens are short of. */
  .hero{
    display:grid; grid-template-columns:minmax(0,1fr);
    grid-template-rows:auto minmax(9rem,1fr);
    align-items:start;
    padding:clamp(5.1rem,12.4vh,7rem) 0 0;
    padding:clamp(5.1rem,12.4svh,7rem) 0 0;
  }
  .hero__inner{ grid-row:1; }
  .hero__stage{ display:none; }
  .hero__bg{ grid-row:2; grid-column:1; top:-45%; }
  /* Never narrower than the screen, and once it is small enough that the
     centred cabinet would pull the image's right edge into view, it is pinned
     to that edge instead (the unit drifts a few px right of centre). */
  .hero__plate{
    width:clamp(100cqw, 206.1cqh, 277cqw);
    left:max(calc(50cqw - .7099 * clamp(100cqw, 206.1cqh, 277cqw)),
             calc(100cqw - clamp(100cqw, 206.1cqh, 277cqw)));
    bottom:calc(-.018 * clamp(100cqw, 206.1cqh, 277cqw));
  }
  /* the box now starts behind the buttons, so the falloff is re-cut to it:
     dark through the plate's fade, gone by the time the lid comes in */
  .hero__ambient{
    background:radial-gradient(64% 36% at 50% 66%, rgba(255,214,164,.05) 0%, transparent 72%);
  }
  .hero__scrim{
    background:linear-gradient(180deg,
      rgba(4,6,8,.92) 0%, rgba(4,6,8,.78) 16%, rgba(4,6,8,.32) 27%, transparent 33%);
  }

  /* three headline lines, not four: "bez kompromisów." is 8.3em wide with its
     tracking, so the size is whatever lets it span the column (8.7 = margin) */
  .hero__title{
    font-size:clamp(1.9rem, min(calc((100vw - 48px) / 8.7), 5.6vh), 3.45rem);
    font-size:clamp(1.9rem, min(calc((100vw - 48px) / 8.7), 5.6svh), 3.45rem);
    line-height:1.05;
  }
  .hero__subtitle{ margin-top:clamp(.75rem,2svh,1.25rem); font-size:.95rem; line-height:1.5; }
  .hero__actions{ margin-top:clamp(1rem,2.6svh,1.75rem); gap:.5rem; }
  .hero__cta{ padding:.8rem 1.4rem; }
  .hero__trust{ margin-top:clamp(.85rem,2.2svh,1.5rem); row-gap:.4rem; }
}
/* An iPhone SE in Safari is ~375x553: headline, subtitle and both buttons
   already take 384px of it, and the trust row would push the unit below the
   fold. It is the one block the page repeats elsewhere (the CTA itself says
   "bezpłatny pomiar"), so on screens this short it is the one that goes. */
@media (max-width:820px) and (max-height:640px){
  .hero__trust{ display:none; }
}
@media (max-width:820px){

  /* a phone screen holds less, so the breathing room between sections is
     scaled down with it — 6rem of black on 812px read as a dead screen */
  .why, .calc, .showcase, .faq, .contact{ padding-top:4.5rem; padding-bottom:4.5rem; }
  .solutions{ padding:4.5rem 0 4rem; }

  /* six reasons in two columns: one screen instead of two */
  .why__top{ margin-bottom:2.2rem; }
  .why__head{ margin-bottom:2.2rem; }
  .why__grid{ grid-template-columns:repeat(2,1fr); column-gap:1.25rem; row-gap:2.2rem; }
  .why__icon{ width:24px; height:24px; margin-bottom:.85rem; }
  .why__item-title{ font-size:.95rem; line-height:1.3; margin-bottom:.45rem; }
  .why__item-desc{ font-size:.8rem; line-height:1.6; max-width:none; }

  /* the four solutions become a swipeable row: the next photo peeks in from
     the right edge, so it reads as "there is more" without any arrows.
     A swipe moves the row and nothing else — so overflow-y is pinned to hidden
     (beside overflow-x:auto it would compute to auto) and the row carries 40px
     of padding under the tiles, cancelled by the margin: the reveal starts each
     tile 36px low, and for that second the row could scroll 36px vertically,
     so a vertical swipe landing on it moved the tiles instead of the page. */
  .solutions__grid{
    width:100%; padding:0 4vw 2.5rem; margin-bottom:-2.5rem;
    grid-template-columns:none; grid-auto-flow:column; grid-auto-columns:min(80%, 21rem);
    gap:0 .9rem;
    overflow-x:auto; overflow-y:hidden; overscroll-behavior-x:contain;
    scroll-snap-type:x mandatory; scroll-padding:0 4vw;
    scrollbar-width:none; -webkit-overflow-scrolling:touch;
  }
  .solutions__grid::-webkit-scrollbar{ display:none; }
  .solutions__item{ scroll-snap-align:start; }
  .solutions__item-media{ aspect-ratio:1/1; }

  /* CALCULATOR — the same controls, rebuilt for a thumb.
     Segmented: three equal columns that never break onto a second row; long
     labels wrap inside their own cell instead, so the metal pill can keep
     sliding (it is measured, so a grid cell is as good as a flex item). */
  .calc__form{ gap:1.45rem; }
  .q__label{ font-size:.86rem; margin-bottom:.6rem; color:var(--silver-200); }
  .q__val{ font-size:1.2rem; }
  .q__val em{ font-size:.72rem; margin-left:.25rem; }
  .q__range{ margin-top:.85rem; }
  @media (pointer:coarse){ .q__range{ height:5px; } }
  .q__range::-webkit-slider-thumb{ width:22px; height:22px; }
  .seg{ display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); padding:.22rem; border-radius:13px; }
  .seg__pill{ top:.22rem; bottom:.22rem; border-radius:10px; }
  .seg__opt{
    display:flex; align-items:center; justify-content:center; min-height:2.5rem;
    padding:.35rem .4rem; border-radius:10px;
    font-size:.74rem; line-height:1.2; white-space:normal; text-wrap:balance;
  }
  /* people + heat gains: one recessed group, the settings-list idiom — the
     label on the left, its control on the right, rows split by the track's
     own shadow line rather than a drawn card */
  .q--pair{
    display:block; padding:0 1rem; border-radius:14px;
    background:rgba(255,255,255,.04);
    box-shadow:0 1px 0 rgba(255,255,255,.045) inset, 0 -1px 0 rgba(0,0,0,.4) inset;
  }
  .q--pair > div:first-child{
    display:flex; align-items:center; justify-content:space-between; gap:1rem;
    min-height:3.3rem; border-bottom:1px solid rgba(255,255,255,.065);
  }
  .q--pair > div:first-child .q__label{ margin:0; font-size:.86rem; white-space:nowrap; }
  .q--pair .stepper{ flex:none; gap:0; padding:.2rem; background:rgba(255,255,255,.05); }
  .q--pair .stepper__btn{ width:30px; height:30px; font-size:1rem; }
  .q--pair .stepper__val{ min-width:1.7rem; font-size:.98rem; }
  .q--pair > div:last-child{ padding-top:.85rem; }
  .q--pair > div:last-child .q__label{
    margin:0; font-size:.6rem; font-weight:500; letter-spacing:.16em;
    text-transform:uppercase; color:var(--silver-500);
  }
  .toggles{ gap:0; }
  .toggle{
    flex-direction:row-reverse; justify-content:space-between; width:100%;
    min-height:2.9rem; padding:0; font-size:.86rem; font-weight:400; color:var(--silver-300);
  }
  .toggle + .toggle{ border-top:1px solid rgba(255,255,255,.065); }
  .toggle__box{ width:40px; height:23px; }
  .toggle__box::after{ top:3px; left:3px; width:17px; height:17px; }
  .toggle.is-on .toggle__box::after{ transform:translateX(17px); }
  .calc__reset{ align-self:center; margin-top:-.6rem; padding:.4rem 1rem; font-size:.74rem; }

  /* the result case, compact: a modest figure, and the unit drawing moved
     beside the recommendation instead of filling half a screen on its own */
  .calc__shell{ gap:2.2rem; }
  .console{ padding:1.35rem 1.25rem 1.2rem; border-radius:20px; }
  .console__cap{ font-size:.6rem; letter-spacing:.16em; }
  .console__value{ margin-top:.55rem; gap:.35rem; }
  .console__value span{ font-size:clamp(2.6rem, 11vw, 3.2rem); }
  .console__value em{ font-size:.95rem; }
  .console__count{ font-size:1.5rem; }
  .console__variant{ grid-template-columns:repeat(2, minmax(0,1fr)); margin-top:1rem; }
  .console__variant .seg__opt{ min-height:2.2rem; font-size:.74rem; }
  .console__meter{ margin-top:1rem; height:2px; }
  .console__unit{
    display:grid; grid-template-columns:1fr auto; align-items:center; column-gap:1rem;
    margin-top:1.15rem; padding-top:1.1rem;
  }
  .console__unit > .console__cap{ grid-column:1; grid-row:1; white-space:nowrap; }
  .unitart{
    grid-column:2; grid-row:1 / span 2; width:7.5rem; margin:0; gap:.3rem;
    color:var(--silver-300);
  }
  .unitart svg{ stroke-width:1.8; }
  .unitart__more{ font-size:.8rem; padding-bottom:.3rem; }
  .console__reco{ grid-column:1; grid-row:2; font-size:1.4rem; margin:.3rem 0 0; }
  .console__desc{ grid-column:1 / -1; margin-top:.7rem; font-size:.78rem; line-height:1.55; }
  .console .btn{ margin-top:1.15rem; padding-top:.78rem; padding-bottom:.78rem; font-size:.84rem; }
  .console__note{ margin-top:.7rem; font-size:.66rem; }

  /* the live result, floating over the questions: figure on the left, the
     unit it maps to on the right, a metal button that drops you to the case.
     main.js toggles .is-on — only while the form is up and the case is not. */
  .calc__dock{
    display:block; position:fixed; z-index:40; left:50%;
    bottom:calc(14px + env(safe-area-inset-bottom, 0px));
    width:min(calc(100% - 32px), 30rem);
    transform:translate(-50%, 150%); opacity:0; pointer-events:none;
    transition:transform .6s var(--ease-out), opacity .4s var(--ease-out);
  }
  .calc__dock.is-on{ transform:translate(-50%, 0); opacity:1; pointer-events:auto; }
  .dock{
    position:relative; overflow:hidden; display:flex; align-items:center; gap:1rem;
    width:100%; padding:.65rem .65rem .65rem 1.2rem; border-radius:22px; text-align:left;
    backdrop-filter:blur(22px) saturate(1.3); -webkit-backdrop-filter:blur(22px) saturate(1.3);
    background:
      linear-gradient(180deg, rgba(255,255,255,.075), rgba(255,255,255,.015) 45%, rgba(255,255,255,0)),
      rgba(15,16,20,.8);
    box-shadow:0 0 0 1px rgba(255,255,255,.08) inset, 0 20px 44px -16px rgba(0,0,0,.95);
  }
  .dock::before{
    content:''; position:absolute; left:0; right:0; top:0; height:1px; pointer-events:none;
    background:linear-gradient(90deg, transparent, rgba(255,255,255,.3) 25%, rgba(255,255,255,.45) 55%, transparent);
  }
  .dock__part{ display:flex; flex-direction:column; gap:.28rem; min-width:0; }
  .dock__part--reco{ margin-left:auto; padding-left:1rem; border-left:1px solid rgba(255,255,255,.08); }
  .dock__cap{
    font-size:.58rem; font-weight:500; letter-spacing:.16em; text-transform:uppercase;
    color:var(--silver-500); white-space:nowrap;
  }
  .dock__kw{ display:flex; align-items:baseline; gap:.3rem; font-size:.78rem; color:var(--silver-400); line-height:1; }
  .dock__kw b{
    font-size:1.7rem; font-weight:500; letter-spacing:-.03em; font-variant-numeric:tabular-nums;
    background:var(--grad-metal); -webkit-background-clip:text; background-clip:text; color:transparent;
  }
  .dock__reco{
    font-family:var(--font-display); font-size:1.08rem; font-weight:500; line-height:1.15;
    color:var(--ice); white-space:nowrap;
  }
  .dock__go{
    flex:none; position:relative; width:42px; height:42px; border-radius:50%;
    background:var(--grad-metal); box-shadow:0 1px 0 rgba(255,255,255,.7) inset, 0 6px 16px -6px rgba(0,0,0,.9);
  }
  .dock__go::after{
    content:''; position:absolute; left:50%; top:44%; width:8px; height:8px;
    border-right:1.7px solid #0a0a0c; border-bottom:1.7px solid #0a0a0c;
    transform:translate(-50%,-50%) rotate(45deg);
  }
  .dock__meter{
    position:absolute; left:0; bottom:0; height:2px; width:18%;
    background:linear-gradient(90deg, rgba(143,217,232,.9), var(--silver-100));
    box-shadow:0 0 10px -1px var(--ice-dim);
  }

  /* CONTACT — one centred column that reads as an invitation, not a ledger:
     a kicker, the headline, one line of reassurance, the two ways to reach us
     as quiet rows you tap (label left, value right, a chevron — the settings-
     list idiom, hairlines only, no card), then the hero's plain white button
     instead of the brushed-metal one. Same markup as desktop. */
  .contact{ padding:4.75rem 0 4.25rem; }
  .contact__bg{ background-position:72% 45%; }
  .contact__scrim{
    background:linear-gradient(180deg,
      var(--black) 0%, rgba(3,4,5,.6) 20%, rgba(3,4,5,.68) 74%, var(--black) 100%);
  }
  .contact__grid{ gap:1.1rem; justify-items:center; text-align:center; }
  .contact__title{ font-size:clamp(2rem, 7.4vw, 2.6rem); line-height:1.14; }
  .contact__title::before{
    content:"Kontakt"; display:block; margin-bottom:.95rem;
    font-family:var(--font-body); font-size:.72rem; font-weight:500;
    letter-spacing:.18em; text-transform:uppercase; color:var(--ice);
  }
  .contact__body{ width:100%; align-items:center; gap:1.9rem; }
  .contact__lead{ max-width:34ch; font-size:.98rem; line-height:1.6; color:rgba(255,255,255,.74); text-wrap:balance; }
  .contact__reach{
    width:100%; max-width:24rem; flex-direction:column; gap:0;
    border-top:1px solid rgba(255,255,255,.13);
  }
  .contact__reach-item{
    flex-direction:row; align-items:center; gap:1rem;
    min-height:3.7rem; padding:.25rem .2rem;
    border-bottom:1px solid rgba(255,255,255,.13);
  }
  .contact__reach-item span{ font-size:.7rem; letter-spacing:.14em; color:rgba(255,255,255,.5); }
  .contact__reach-item strong{ margin-left:auto; font-size:1rem; font-weight:400; letter-spacing:0; }
  .contact__reach-item::after{
    content:""; flex:none; width:6px; height:6px; margin-right:.25rem;
    border-top:1.5px solid rgba(255,255,255,.4); border-right:1.5px solid rgba(255,255,255,.4);
    transform:rotate(45deg);
  }
  .contact__btn{
    width:100%; max-width:24rem; padding:1rem 1.5rem;
    background:#fff; color:#07090b;
    box-shadow:0 1px 0 rgba(255,255,255,.85) inset, 0 14px 34px -16px rgba(0,0,0,.95);
  }

  /* FOOTER — a small centred colophon. The script wordmark is left out here:
     at phone width it could only sit on top of the copyright line. */
  .footer{ padding:2.75rem 0 2.1rem; min-height:0; }
  .footer__bar{ align-items:center; text-align:center; gap:1.3rem; }
  .footer__logo .nav__logo-img{ height:50px; }
  .footer__nav{ justify-content:center; gap:.1rem 1.6rem; }
  .footer__nav a{ display:inline-block; padding:.45rem 0; font-size:.9rem; }
  .footer__meta{ align-items:center; gap:.9rem; }
  .footer__bottom{ margin-top:1.5rem; padding-top:1.35rem; }
  /* the signature is the backdrop of the link row, as on desktop: centred on
     the nav line (8.4rem down = top padding + logo + gap; the image is
     1/5.17 of its width tall, so half of it is 10.45vw), a touch dimmer so
     the links stay crisp on top of it */
  .footer__mark{
    bottom:auto; right:auto; left:50%;
    top:calc(8.4rem - 10.45vw); width:108vw; margin:0 0 0 -54vw;
  }
  .footer__mark.is-in{ opacity:.34; }
}
/* Touch phones: no sticky hover. Android keeps :hover on whatever was tapped
   last, so a tap to stop a flick left that tile's photo brightened and zoomed. */
@media (max-width:820px) and (hover:none){
  .solutions__item:hover .solutions__item-media img,
  .solutions__item:focus-within .solutions__item-media img{
    filter:brightness(var(--tile-b)) saturate(var(--tile-s)) sepia(var(--tile-sep,0));
    transform:scale(1.001);
  }
}

@media (prefers-reduced-motion: reduce){
  *{ animation-duration:0.001ms !important; animation-iteration-count:1 !important; transition-duration:0.001ms !important; scroll-behavior:auto !important; }
  [data-reveal],[data-row],[data-intro]{ opacity:1 !important; transform:none !important; }
  .line-inner{ transform:none !important; }
}
