/* ============================================================
   YAHAMD — Living Mechanism design system
   Palette: near-black / dark green, green glow, white, metal-gray
   ============================================================ */
:root{
  --bg:#04100b;
  --bg-2:#061a12;
  --panel:#08201700;
  --card:rgba(10,32,24,.55);
  /* ---- ACCENT HIERARCHY -------------------------------------------------
     Two tiers, not one. --green stays fully saturated and is reserved for
     things that genuinely demand attention: buttons, focus rings, kickers,
     the hero mechanism, active states.

     Everything STRUCTURAL — card hairlines, hover borders, the timeline
     rule, dashed outlines — uses the desaturated hue below. Same colour
     family, much lower chroma. Previously both tiers were #00e08a at
     varying alpha, so the borders competed with the buttons and nothing
     read as emphasised.

     Alphas are tuned so composited lightness over --bg is unchanged; only
     the chroma drops. Card hairline lands on rgb(20,49,37) where it used
     to be rgb(3,49,31) — same value, less colour. */
  --green-struct:#4a9e7a;
  --card-brd:rgba(74,158,122,.23);
  --green:#00e08a;
  --green-soft:#2ff0a4;
  --green-dim:rgba(74,158,122,.73);
  /* WhatsApp brand green — fixed by their guidelines, deliberately NOT
     harmonised with --green. It reads as a third-party mark, not our accent. */
  --wa:#25d366;
  --ink:#eef4f1;
  --muted:#9fb0a8;
  /* was #6f847a — 4.85:1, uncomfortably close to the 4.5 floor for the fine
     print it carries (footer copy, disclaimers, the comparison footnote) */
  --muted-2:#7b9086;
  --metal:#8a95a1;
  --line:rgba(255,255,255,.07);
  --radius:16px;
  --maxw:1180px;
  --font-display:'Chakra Petch',system-ui,sans-serif;
  --font-body:'Inter',system-ui,sans-serif;
  --font-mono:'JetBrains Mono',ui-monospace,monospace;
  --header-h:66px;

  /* ---- TYPE SCALE -------------------------------------------------------
     Eight steps replacing the 22 near-identical sizes this file had grown.
     Values sit at each old cluster's median, so nothing moves more than
     ~0.6px — the point is that new work now has a step to land on instead
     of inventing .84rem next to an existing .85rem. */
  --fs-3xs:.64rem;   /* badges, the smallest mono tags */
  --fs-2xs:.70rem;   /* readout rows, fine print */
  --fs-xs:.76rem;    /* mono labels, kickers, captions, field labels */
  --fs-sm:.84rem;    /* secondary body */
  --fs-base:.95rem;  /* body */
  --fs-md:1.03rem;   /* lead, inputs, FAQ questions */
  --fs-lg:1.14rem;   /* card headings */
  --fs-xl:1.22rem;   /* brand lockup */

  /* ---- TRACKING ---------------------------------------------------------
     Tracking is a function of size: display type tightens, small caps open
     up. The old file had 13 arbitrary values with no such logic. */
  --tr-display:-.015em;  /* h1 — large type needs negative tracking to read tight */
  --tr-head:-.005em;     /* h2 */
  --tr-normal:.03em;
  --tr-wide:.08em;       /* small uppercase */
  --tr-label:.14em;      /* mono labels */
  --tr-kicker:.21em;     /* section kickers, eyebrow */

  /* ---- VERTICAL RHYTHM -------------------------------------------------- */
  --sp-section:clamp(80px,10.5vw,148px);
  --sp-head:64px;

  /* ---- MOTION SYSTEM ----------------------------------------------------
     One curve for everything reads as "default". These are split by the
     PHYSICAL ROLE the motion plays, so the page has a motion hierarchy.

     --ease-mech    Metal moving under its own weight. Critically damped:
                    strong deceleration, settles hard, never overshoots.
                    Reserved for the YAFRUT mechanism + anything that
                    represents the product itself.
     --ease-entrance Content arriving. Long tail, no bounce — the Apple/
                    Linear house curve. Reveals, section arrivals, load.
     --ease-ui      Small interface acknowledgements. Fast, flat, honest.
     --ease-press   The ONLY curve allowed to overshoot, and only barely
                    (1.06). Release-from-press, so a click feels sprung.
     --ease-swing   Drawers/panels that pivot rather than translate.       */
  --ease-mech:cubic-bezier(.16,.84,.24,1);
  --ease-entrance:cubic-bezier(.16,1,.3,1);
  --ease-ui:cubic-bezier(.33,.8,.4,1);
  --ease-press:cubic-bezier(.34,1.06,.64,1);
  --ease-swing:cubic-bezier(.4,.72,.2,1);
  /* Legacy alias — fully retired from style.css as of the micro-interaction
     pass. Kept defined only so any future/third-party rule referencing it
     resolves to something sane rather than to an invalid value. */
  --ease-elastic:var(--ease-press);

  /* Durations — paired with the curves above so timing is not ad-hoc. */
  --d-fast:150ms;
  --d-ui:260ms;
  --d-mid:520ms;
  --d-slow:820ms;
  --d-mech:1150ms;

  /* Reveal stagger step. Multiplied by --stagger-i, set by the scroll
     engine. 62ms is the point where a row reads as one gesture rather
     than as separate elements firing. */
  --stagger-step:62ms;
}

*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth;scroll-padding-top:calc(var(--header-h) + 14px)}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{
  margin:0;background:var(--bg);color:var(--ink);
  font-family:var(--font-body);font-size:16px;line-height:1.6;
  -webkit-font-smoothing:antialiased;overflow-x:hidden;
}
img{max-width:100%;display:block;height:auto}
a{color:inherit;text-decoration:none}
h1,h2,h3{font-family:var(--font-display);line-height:1.08;letter-spacing:var(--tr-normal);margin:0}
ul{margin:0;padding:0;list-style:none}
button{font-family:inherit}

/* Focus visibility */
:focus-visible{outline:2px solid var(--green);outline-offset:3px;border-radius:4px}
/* Sections receive tabindex="-1" so nav clicks can move focus with the
   viewport (see script.js §5b). They must never paint a focus ring for that
   programmatic focus — the ring belongs to real keyboard traversal, and a
   glowing outline around a whole section reads as a rendering fault.
   :focus-visible still applies normally to everything inside. */
.section:focus,main:focus{outline:none}

.skip-link{
  position:fixed;left:12px;top:-60px;z-index:200;background:var(--green);color:#04100b;
  padding:10px 16px;border-radius:8px;font-weight:600;transition:top var(--d-ui) var(--ease-press);
}
.skip-link:focus{top:12px}

.wrap{width:min(var(--maxw),92vw);margin-inline:auto}
.wrap--narrow{width:min(760px,92vw)}

/* ============ ANIMATED BACKGROUND ============ */
.bg-layers{position:fixed;inset:0;z-index:-1;overflow:hidden;background:
  radial-gradient(1200px 700px at 78% -5%, rgba(0,224,138,.08), transparent 60%),
  linear-gradient(180deg,#04100b,#03130d 40%,#020c08)}
.bg-grid{
  position:absolute;inset:-2px;
  background-image:
    linear-gradient(rgba(0,224,138,.055) 1px,transparent 1px),
    linear-gradient(90deg,rgba(0,224,138,.055) 1px,transparent 1px);
  background-size:44px 44px;
  mask-image:radial-gradient(circle at 50% 30%,#000 0%,transparent 78%);
  will-change:transform;
}
/* Far plane: 4× the cell size, dimmer, and drifts at roughly a third of the
   near grid's rate (see script.js §3). The scale difference is what sells
   the distance — matching cell sizes would just look like a brightness
   change. Sits behind the near grid via source order. */
.bg-grid--far{
  background-image:
    linear-gradient(rgba(0,224,138,.03) 1px,transparent 1px),
    linear-gradient(90deg,rgba(0,224,138,.03) 1px,transparent 1px);
  background-size:176px 176px;
  mask-image:radial-gradient(circle at 50% 34%,#000 0%,transparent 86%);
}
/* PERF: each masked, will-change'd grid is a full-viewport composited layer,
   and a mask forces its own rasterisation pass. Two of them is a fair trade
   on desktop for the depth it buys; on phones — least GPU headroom, smallest
   screen, weakest payoff — the far plane is dropped entirely rather than
   merely dimmed. The near grid alone is the original, known-good cost. */
@media (max-width:860px){
  .bg-grid--far{display:none}
}
.bg-glow{position:absolute;border-radius:50%;filter:blur(90px);opacity:.5;will-change:transform}
.bg-glow--a{width:520px;height:520px;top:-120px;right:-80px;background:radial-gradient(circle,rgba(0,224,138,.22),transparent 70%)}
.bg-glow--b{width:460px;height:460px;bottom:-140px;left:-120px;background:radial-gradient(circle,rgba(0,160,120,.16),transparent 70%)}
.fiber-canvas{position:absolute;inset:0;width:100%;height:100%;opacity:.5}

/* ============ HEADER ============ */
.site-header{
  position:sticky;top:0;z-index:100;
  backdrop-filter:blur(14px);
  background:rgba(4,16,11,.55);
  border-bottom:1px solid var(--line);
  transition:background var(--d-ui) var(--ease-ui),border-color var(--d-ui) var(--ease-ui);
}
.site-header.scrolled{background:rgba(4,16,11,.86)}
.header-inner{display:flex;align-items:center;gap:20px;height:var(--header-h)}
.brand{display:flex;align-items:center;gap:10px;color:var(--green)}
/* Logo mark is a raster PNG: fix the box so it can't shift layout while
   loading, and let the browser downscale the 477px master for retina. */
.brand-mark{flex:none;width:34px;height:34px;object-fit:contain;
  transition:transform var(--d-mid) var(--ease-mech)}
.brand:hover .brand-mark{transform:rotate(-6deg) scale(1.06)}
.brand-name{font-family:var(--font-display);font-weight:700;font-size:var(--fs-xl);letter-spacing:var(--tr-kicker);color:var(--ink)}
.nav{display:flex;gap:6px;margin-inline-start:auto}
/* NAV — family gesture: RULE DRAWS IN from the leading edge.
   Transform-only (scaleX), so it composites. Direction flips under RTL so
   the rule always draws from where reading starts. */
.nav a{
  font-size:var(--fs-sm);letter-spacing:var(--tr-normal);color:var(--muted);padding:8px 12px;border-radius:8px;
  transition:color var(--d-ui) var(--ease-ui),background var(--d-ui) var(--ease-ui);position:relative;
}
.nav a::after{
  content:"";position:absolute;left:12px;right:12px;bottom:4px;height:1.5px;border-radius:2px;
  background:var(--green);transform:scaleX(0);transform-origin:left center;
  transition:transform var(--d-ui) var(--ease-entrance);
}
[dir="rtl"] .nav a::after{transform-origin:right center}
.nav a:hover{color:var(--ink);background:rgba(0,224,138,.05)}
.nav a:hover::after,.nav a:focus-visible::after{transform:scaleX(1)}
.header-actions{display:flex;align-items:center;gap:12px}
.lang-switch{display:flex;border:1px solid var(--card-brd);border-radius:999px;overflow:hidden}
.lang-switch button{
  background:transparent;border:0;color:var(--muted);padding:6px 11px;font-size:var(--fs-xs);
  font-family:var(--font-mono);letter-spacing:var(--tr-wide);cursor:pointer;transition:color var(--d-fast) linear,background var(--d-ui) var(--ease-ui);
}
.lang-switch button:hover{color:var(--ink)}
.lang-switch button.is-active{background:var(--green);color:#04100b;font-weight:600}

/* Buttons */
/* BUTTONS — family gesture: LIFT + BLOOM, then COMPRESS on press.
   Buttons are the only family on the page allowed to leave their plane.
   The press state is the piece that was missing entirely: without it a
   click is acknowledged only by the page changing, which is what makes
   an interface feel unresponsive even when it is fast. */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  font-family:var(--font-display);font-weight:600;font-size:var(--fs-base);letter-spacing:var(--tr-normal);
  padding:13px 24px;border-radius:10px;border:1px solid transparent;cursor:pointer;
  white-space:nowrap;position:relative;
  transition:transform var(--d-ui) var(--ease-press),
             box-shadow var(--d-ui) var(--ease-ui),
             background var(--d-ui) var(--ease-ui),
             color var(--d-fast) linear,
             border-color var(--d-fast) linear;
}
/* Press: fast, flat, and deeper than the hover lift so the button clearly
   travels THROUGH its rest position. Release runs on --ease-press, the one
   curve permitted a (1.06) overshoot — that tiny rebound is the "sprung"
   feel. 70ms because a press must never feel like it lags the finger. */
.btn:active{transition-duration:70ms;transform:translateY(1px) scale(.978)}
.btn--sm{padding:9px 16px;font-size:var(--fs-sm)}
.btn--full{width:100%}

.btn--primary{background:var(--green);color:#03130d;box-shadow:0 1px 2px rgba(0,0,0,.2)}
.btn--primary:hover{background:var(--green-soft);transform:translateY(-2px);
  box-shadow:0 10px 32px -6px rgba(0,224,138,.45),0 2px 6px rgba(0,0,0,.25)}
.btn--primary:active{box-shadow:0 1px 4px rgba(0,224,138,.3)}

.btn--ghost{background:rgba(255,255,255,.02);color:var(--ink);border-color:var(--card-brd)}
.btn--ghost:hover{border-color:var(--green);color:var(--green);transform:translateY(-2px);
  background:rgba(0,224,138,.06);box-shadow:0 8px 24px -8px rgba(0,224,138,.3)}
.btn--ghost:active{background:rgba(0,224,138,.1);box-shadow:none}

.btn--wa{background:#1eb35a;color:#fff;box-shadow:0 1px 2px rgba(0,0,0,.2)}
.btn--wa:hover{background:#25d366;transform:translateY(-2px);
  box-shadow:0 10px 28px -6px rgba(37,211,102,.45),0 2px 6px rgba(0,0,0,.25)}
.btn--wa:active{box-shadow:0 1px 4px rgba(37,211,102,.3)}

/* Keyboard users get the same bloom as hover — a focus ring alone tells you
   where you are but not that the control is live. */
.btn:focus-visible{transform:translateY(-2px)}

.nav-toggle{display:none;flex-direction:column;gap:5px;background:none;border:0;cursor:pointer;padding:6px}
.nav-toggle span{width:24px;height:2px;background:var(--ink);border-radius:2px;transition:transform var(--d-ui) var(--ease-swing),opacity var(--d-fast) linear}
.nav-toggle[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.nav-toggle[aria-expanded="true"] span:nth-child(2){opacity:0}
.nav-toggle[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

/* ============ HERO ============ */
.hero{position:relative;padding:clamp(48px,9vw,110px) 0 80px;min-height:calc(100vh - var(--header-h));display:flex;align-items:center}
.hero-inner{display:grid;grid-template-columns:1.05fr .95fr;gap:48px;align-items:center;width:min(var(--maxw),92vw);margin-inline:auto}
.eyebrow{font-family:var(--font-mono);font-size:var(--fs-xs);letter-spacing:var(--tr-kicker);color:var(--green);display:flex;align-items:center;gap:10px;margin:0 0 18px}
.eyebrow .dot{width:8px;height:8px;border-radius:50%;background:var(--green);box-shadow:0 0 12px var(--green);animation:pulse 2.4s ease-in-out infinite}
@keyframes pulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.4;transform:scale(.7)}}
.hero-title{font-size:clamp(2.1rem,5.4vw,4rem);font-weight:700;letter-spacing:var(--tr-display);
  background:linear-gradient(180deg,#fff 30%,#bfe9d7);-webkit-background-clip:text;background-clip:text;color:transparent}
.hero-sub{color:var(--muted);font-size:clamp(1rem,1.6vw,1.18rem);max-width:46ch;margin:22px 0 32px}
.hero-btns{display:flex;gap:14px;flex-wrap:wrap}

/* Hero mechanism */
.hero-mech{display:flex;flex-direction:column;align-items:center;gap:20px}
.mech-stage{position:relative;width:min(420px,80vw);aspect-ratio:1;background:
  radial-gradient(circle at 50% 55%,rgba(0,224,138,.09),transparent 62%);
  border:1px solid var(--card-brd);border-radius:24px;cursor:pointer;
  display:grid;place-items:center;padding:0;overflow:hidden;
  transition:border-color var(--d-ui) var(--ease-ui),box-shadow var(--d-ui) var(--ease-ui);
}
.mech-stage:hover{border-color:var(--green-dim);box-shadow:0 0 50px rgba(0,224,138,.12) inset}
.mech-stage svg{width:100%;height:100%}
/* While the mechanism is actually working, the stage lights from within —
   the hinge is doing the work, so the light comes from the hinge outward.
   Compositor-safe: opacity and box-shadow only, no filter, no layout. */
.mech-stage.is-moving{border-color:var(--green-dim);box-shadow:0 0 70px rgba(0,224,138,.2) inset}
.mech-stage{transition:border-color var(--d-ui) var(--ease-ui),box-shadow var(--d-mid) var(--ease-ui)}

.hinge-glow{animation:heartbeat 2.8s ease-in-out infinite;transform-origin:200px 268px;
  transition:opacity var(--d-ui) var(--ease-ui)}
@keyframes heartbeat{0%,100%{opacity:.55;transform:scale(.85)}45%{opacity:1;transform:scale(1.12)}}
/* The idle heartbeat is the mechanism at rest. Under load it stops pulsing
   and simply burns brighter — a machine under tension, not breathing. */
.mech-stage.is-moving .hinge-glow{animation-play-state:paused;opacity:1}

/* Cast shadow needs a soft edge; a blur filter on this ONE small static
   ellipse is affordable where a filter on the animating arm group would
   not be (that would re-rasterise 10 strokes every frame). */
#mechShadow{filter:blur(7px)}
.airflow-arc{stroke-dasharray:6 12;animation:flow 6s linear infinite}
@keyframes flow{to{stroke-dashoffset:-72}}
.mech-hint{position:absolute;bottom:14px;left:0;right:0;text-align:center;font-family:var(--font-mono);
  font-size:var(--fs-2xs);letter-spacing:var(--tr-label);color:var(--muted-2);text-transform:uppercase}
.mech-readout{display:flex;gap:10px;flex-wrap:wrap;justify-content:center}
.mech-readout li{font-family:var(--font-mono);font-size:var(--fs-2xs);letter-spacing:var(--tr-wide);color:var(--muted-2);
  border:1px solid var(--card-brd);border-radius:8px;padding:7px 12px;display:flex;gap:8px;align-items:center;background:rgba(10,32,24,.4)}
.mech-readout b{color:var(--green)}

.scroll-cue{position:absolute;bottom:22px;left:50%;transform:translateX(-50%)}
.scroll-cue span{display:block;width:22px;height:34px;border:2px solid var(--muted-2);border-radius:12px;position:relative}
.scroll-cue span::after{content:"";position:absolute;top:6px;left:50%;transform:translateX(-50%);width:3px;height:7px;background:var(--green);border-radius:2px;animation:scrolldot 1.8s ease-in-out infinite}
@keyframes scrolldot{0%{opacity:0;transform:translate(-50%,0)}40%{opacity:1}80%{opacity:0;transform:translate(-50%,12px)}}

/* ============ SECTIONS ============ */
.section{padding:var(--sp-section) 0;position:relative}
.section--alt{background:linear-gradient(180deg,transparent,rgba(0,224,138,.025),transparent)}
.section-head{max-width:760px;margin-bottom:var(--sp-head)}
.kicker{font-family:var(--font-mono);font-size:var(--fs-xs);letter-spacing:var(--tr-kicker);color:var(--green);margin:0 0 14px}
.section-head h2{font-size:clamp(1.7rem,3.6vw,2.7rem);font-weight:600;letter-spacing:var(--tr-head)}
/* 62ch keeps the lead inside a comfortable measure — the 760px head was
   letting it run past 90 characters on wide screens. */
.lead{color:var(--muted);font-size:var(--fs-md);margin-top:16px;max-width:62ch}

/* Grid & cards */
.grid{display:grid;gap:20px}
.grid-3{grid-template-columns:repeat(3,1fr)}
.grid-4{grid-template-columns:repeat(4,1fr)}
.grid-5{grid-template-columns:repeat(5,1fr)}
/* CARDS — family gesture: ILLUMINATE, not lift.
   Cards previously used translateY(-4px), the same move as .btn and .shot.
   Three families sharing one gesture is what makes a page read as a
   template. Cards now stay planted and light up from their top edge
   instead: the surface brightens, the border traces, the icon settles.
   Nothing moves off its plane, so the buttons keep that gesture to
   themselves. */
.card{
  position:relative;background:var(--card);border:1px solid var(--card-brd);border-radius:var(--radius);
  padding:28px;overflow:hidden;
  transition:border-color var(--d-ui) var(--ease-ui),
             background var(--d-ui) var(--ease-ui),
             box-shadow var(--d-ui) var(--ease-ui);
}
/* The light itself: a soft wash from the top edge, revealed on hover.
   A pseudo-element fading in beats animating `background` because it is a
   pure opacity change on its own layer — no repaint of the card body. */
.card::after{
  content:"";position:absolute;inset:0;pointer-events:none;border-radius:inherit;
  background:linear-gradient(180deg,rgba(0,224,138,.09),transparent 58%);
  opacity:0;transition:opacity var(--d-ui) var(--ease-ui);
}
.card:hover::after{opacity:1}
.card h3{font-size:var(--fs-lg);font-weight:600;margin-bottom:10px}
.card p{color:var(--muted);font-size:var(--fs-base);margin:0}

/* blueprint border trace on hover / in view */
.fold-card::before{
  content:"";position:absolute;inset:0;border-radius:var(--radius);padding:1px;pointer-events:none;
  background:conic-gradient(from var(--ang,0deg),transparent 0 75%,var(--green) 88%,transparent 100%);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;opacity:0;transition:opacity var(--d-mid) var(--ease-ui);
}
.fold-card:hover::before,.fold-card.in-view::before{opacity:.9}
/* No translate — see the CARDS note above. Border + grounding shadow only. */
.fold-card:hover{border-color:var(--green-dim);box-shadow:0 12px 40px -18px rgba(0,224,138,.5)}

/* Card icon — the one part of a card that DOES move. Because the card body
   stays planted, this small mechanical settle carries the whole interaction,
   which is why it gets the product's own easing curve. */
.card-icon{width:46px;height:46px;border:1px solid var(--card-brd);border-radius:12px;margin-bottom:18px;position:relative;
  display:grid;place-items:center;background:rgba(0,224,138,.05);
  transition:transform var(--d-mid) var(--ease-mech),
             border-color var(--d-ui) var(--ease-ui),
             background var(--d-ui) var(--ease-ui)}
.fold-card:hover .card-icon{transform:rotate(-8deg) scale(1.06);
  border-color:var(--green-dim);background:rgba(0,224,138,.1)}
.card-icon::before,.card-icon::after{content:"";position:absolute}
/* icon glyphs via masks */
.card-icon[data-icon]{background-image:none}
.card-icon::before{width:22px;height:22px;background:var(--green)}
.card-icon[data-icon="bulb"]::before{-webkit-mask:radial-gradient(circle at 50% 40%,#000 42%,transparent 44%) ;mask:radial-gradient(circle at 50% 40%,#000 42%,transparent 44%);border-radius:0}
.card-icon[data-icon="bulb"]::after{width:10px;height:5px;background:var(--green);bottom:9px}
.card-icon[data-icon="shield"]::before{-webkit-mask:linear-gradient(#000,#000);mask:linear-gradient(#000,#000);clip-path:polygon(50% 0,100% 22%,100% 60%,50% 100%,0 60%,0 22%)}
.card-icon[data-icon="user"]::before{border-radius:50% 50% 0 0;clip-path:polygon(0 0,100% 0,100% 45%,0 45%)}
.card-icon[data-icon="user"]::after{width:16px;height:10px;background:var(--green);bottom:11px;border-radius:8px 8px 0 0}
.card-icon[data-icon="compress"]::before{width:18px;height:2px;box-shadow:0 -6px var(--green),0 6px var(--green)}
.card-icon[data-icon="hand"]::before{border-radius:6px 6px 3px 3px;height:18px;width:16px}
.card-icon[data-icon="gear"]::before{border-radius:50%;-webkit-mask:radial-gradient(circle,transparent 30%,#000 32%);mask:radial-gradient(circle,transparent 30%,#000 32%)}
.card-icon[data-icon="grid"]::before{-webkit-mask:linear-gradient(#000,#000) 0 0/9px 9px no-repeat,linear-gradient(#000,#000) 13px 0/9px 9px no-repeat,linear-gradient(#000,#000) 0 13px/9px 9px no-repeat,linear-gradient(#000,#000) 13px 13px/9px 9px no-repeat;mask:linear-gradient(#000,#000) 0 0/9px 9px no-repeat,linear-gradient(#000,#000) 13px 0/9px 9px no-repeat,linear-gradient(#000,#000) 0 13px/9px 9px no-repeat,linear-gradient(#000,#000) 13px 13px/9px 9px no-repeat}
.card-icon[data-icon="wall"]::before{-webkit-mask:linear-gradient(#000,#000) 0 0/22px 6px no-repeat,linear-gradient(#000,#000) 0 8px/14px 6px no-repeat,linear-gradient(#000,#000) 0 16px/22px 6px no-repeat;mask:linear-gradient(#000,#000) 0 0/22px 6px no-repeat,linear-gradient(#000,#000) 0 8px/14px 6px no-repeat,linear-gradient(#000,#000) 0 16px/22px 6px no-repeat}

/* ============ YAFRUT product ============ */
.yafrut-grid{display:grid;grid-template-columns:1fr 1fr;gap:52px;align-items:center}
/* Frame lives on the WRAPPER, not the image: §5c scales the image to 1.06
   so its scroll drift never exposes an edge, and a border on the image
   itself would be cropped by the wrapper's overflow clip. */
.yafrut-visual{border:1px solid var(--card-brd);border-radius:var(--radius);
  box-shadow:0 20px 60px rgba(0,0,0,.4)}
.yafrut-visual img{display:block;width:100%}
.prod-title{font-size:clamp(1.5rem,3vw,2.2rem);font-weight:600;margin-bottom:8px}
.feature-list{margin-top:26px;display:grid;gap:12px}
.feature-list li{position:relative;padding-inline-start:30px;color:var(--ink);font-size:var(--fs-base)}
.feature-list li::before{content:"";position:absolute;inset-inline-start:0;top:.55em;width:12px;height:12px;border:2px solid var(--green);border-radius:3px;transform:rotate(45deg);box-shadow:0 0 8px rgba(0,224,138,.4)}

/* ============ CONSOLE (specs) ============ */
.console{border:1px solid var(--card-brd);border-radius:var(--radius);overflow:hidden;background:rgba(3,13,9,.7);
  box-shadow:0 0 60px rgba(0,224,138,.06) inset}
.console-bar{display:flex;align-items:center;gap:8px;padding:12px 18px;border-bottom:1px solid var(--line);background:rgba(0,224,138,.04)}
.console-dot{width:10px;height:10px;border-radius:50%;background:var(--muted-2)}
.console-dot:first-child{background:var(--green)}
.console-tag{margin-inline-start:auto;font-family:var(--font-mono);font-size:var(--fs-2xs);letter-spacing:var(--tr-label);color:var(--muted)}
.console-rows{display:grid}
.crow{display:grid;grid-template-columns:minmax(140px,1fr) 2fr;gap:16px;padding:15px 20px;border-bottom:1px solid var(--line);align-items:baseline}
.crow:last-child{border-bottom:0}
.crow:nth-child(odd){background:rgba(255,255,255,.012)}
.crow span{font-family:var(--font-mono);font-size:var(--fs-xs);letter-spacing:var(--tr-wide);color:var(--muted);text-transform:uppercase}
.crow span::before{content:"› ";color:var(--green)}
.crow b{font-weight:500;color:var(--ink)}

/* ============ PROTECTION ============ */
.protect-inner{max-width:900px}
.protect-card{padding:clamp(28px,5vw,48px);text-align:center;background:
  radial-gradient(600px 200px at 50% 0%,rgba(0,224,138,.08),transparent 70%),var(--card)}
.protect-tags{display:flex;gap:12px;flex-wrap:wrap;justify-content:center;margin-top:26px}
.protect-tags span{font-family:var(--font-mono);font-size:var(--fs-xs);letter-spacing:var(--tr-wide);color:var(--green);
  border:1px dashed var(--green-dim);border-radius:999px;padding:8px 16px}

/* ============ DEALER TIERS ============ */
.tier-card{display:flex;flex-direction:column}
.tier-card ul{margin:18px 0 24px;display:grid;gap:10px;flex:1}
.tier-card ul li{display:flex;justify-content:space-between;gap:12px;font-size:var(--fs-base);color:var(--muted);
  border-bottom:1px dashed var(--line);padding-bottom:9px}
.tier-card ul li b{color:var(--ink);font-family:var(--font-mono);font-size:var(--fs-sm)}
.tier-price{font-family:var(--font-display);font-size:var(--fs-lg);color:var(--green);margin:2px 0 0}
.tier-card--feature{border-color:var(--green-dim);box-shadow:0 0 50px rgba(0,224,138,.1)}
.tier-badge{position:absolute;top:16px;inset-inline-end:16px;font-family:var(--font-mono);font-size:var(--fs-3xs);
  /* 500, not 600: only JetBrains Mono 400 and 500 are loaded, so 600 was
     being faux-bolded by the browser. A real 500 renders cleaner than a
     synthesised 600, and it avoids pulling another font file for one badge. */
  letter-spacing:var(--tr-label);background:var(--green);color:#04100b;padding:4px 10px;border-radius:6px;font-weight:500}

/* ============ TIMELINE ============ */
.timeline{display:grid;grid-template-columns:repeat(5,1fr);gap:18px;position:relative}
.timeline::before{content:"";position:absolute;top:26px;inset-inline:6%;height:1px;background:linear-gradient(90deg,transparent,var(--green-dim),transparent)}
.tl-step{position:relative;padding-top:64px;text-align:center}
.tl-num{position:absolute;top:0;left:50%;transform:translateX(-50%);width:52px;height:52px;border-radius:50%;
  display:grid;place-items:center;font-family:var(--font-mono);font-size:var(--fs-base);color:var(--green);
  border:1px solid var(--green-dim);background:var(--bg-2);box-shadow:0 0 20px rgba(0,224,138,.15)}
.tl-step h3{font-size:var(--fs-md);margin-bottom:6px}
.tl-step p{color:var(--muted);font-size:var(--fs-sm);margin:0}

/* ============ GALLERY ============ */
/* One feature frame across the top, three portraits beneath. A wall-mounted
   vertical product is badly served by four small landscape crops, which is
   what the old grid-4 gave it. */
.gallery-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
.shot--feature{grid-column:1/-1}
/* aspect-ratio + object-fit is what lets real photography drop straight in:
   any source size crops to the frame with no distortion and no layout shift. */
.shot img{width:100%;height:auto;display:block;object-fit:cover;aspect-ratio:4/5}
.shot--feature img{aspect-ratio:16/9}
.shot-btn{display:block;width:100%;padding:0;border:0;background:none;cursor:zoom-in;color:inherit}
.shot-btn:focus-visible{outline:2px solid var(--green);outline-offset:-2px}
/* GALLERY — family gesture: PUSH IN.
   The frame stays put and the image scales inside it, so hovering reads as
   moving toward the subject rather than lifting the object (which is the
   buttons' gesture). Scale on the img only; the figure never moves. */
.shot{margin:0;border:1px solid var(--card-brd);border-radius:var(--radius);overflow:hidden;
  background:var(--bg-2);position:relative;
  transition:border-color var(--d-ui) var(--ease-ui),box-shadow var(--d-ui) var(--ease-ui)}
.shot:hover{border-color:var(--green-dim);box-shadow:0 14px 44px -20px rgba(0,224,138,.45)}
.shot img{transition:opacity .8s ease,transform var(--d-slow) var(--ease-entrance)}
.shot:hover img{transform:scale(1.045)}
.shot figcaption{transition:color var(--d-ui) var(--ease-ui)}
.shot:hover figcaption{color:var(--ink)}
.shot figcaption{font-family:var(--font-mono);font-size:var(--fs-xs);letter-spacing:var(--tr-wide);color:var(--muted);padding:12px 16px;border-top:1px solid var(--line);text-transform:uppercase}

/* ============ LIGHTBOX ============ */
.lbx{position:fixed;inset:0;z-index:200;display:grid;place-items:center;padding:clamp(16px,4vw,56px);
  background:rgba(2,8,6,.92);backdrop-filter:blur(6px);opacity:0;
  transition:opacity var(--d-mid) var(--ease-ui)}
.lbx[hidden]{display:none}
.lbx.open{opacity:1}
/* width, not max-width: the parent centres with place-items, so the figure
   would otherwise shrink to its content and the image could never fill it */
.lbx-fig{margin:0;width:min(1100px,100%);max-height:100%;display:flex;flex-direction:column;gap:14px}
/* explicit width, or an SVG with small intrinsic dimensions renders at its
   own size instead of filling the frame */
.lbx-fig img{width:100%;height:auto;max-height:78vh;object-fit:contain;border-radius:var(--radius);
  border:1px solid var(--card-brd);background:var(--bg-2);
  transform:scale(.985);transition:transform var(--d-mid) var(--ease-entrance)}
.lbx.open .lbx-fig img{transform:scale(1)}
.lbx-fig figcaption{font-family:var(--font-mono);font-size:var(--fs-xs);letter-spacing:var(--tr-wide);
  color:var(--muted);text-transform:uppercase;text-align:center}
.lbx-close{position:absolute;inset-block-start:clamp(12px,3vw,26px);inset-inline-end:clamp(12px,3vw,26px);
  width:42px;height:42px;border-radius:50%;border:1px solid var(--card-brd);background:rgba(6,26,18,.9);
  color:var(--ink);font-size:1.4rem;line-height:1;cursor:pointer;display:grid;place-items:center;
  transition:border-color var(--d-ui) var(--ease-ui),color var(--d-ui) var(--ease-ui)}
.lbx-close:hover{border-color:var(--green);color:var(--green)}
.lbx-close:focus-visible{outline:2px solid var(--green);outline-offset:2px}

/* ============ FAQ ============ */
.faq{display:grid;gap:12px}
.faq-item{border:1px solid var(--card-brd);border-radius:12px;overflow:hidden;background:var(--card)}
.faq-q{width:100%;display:flex;align-items:center;justify-content:space-between;gap:16px;background:none;border:0;
  color:var(--ink);font-family:var(--font-display);font-weight:600;font-size:var(--fs-md);text-align:start;padding:18px 20px;cursor:pointer}
/* The +/− glyph is a small mechanism, so it takes the product curve. */
.faq-q i{flex:none;width:20px;height:20px;position:relative;transition:transform var(--d-mid) var(--ease-mech)}
.faq-q i::before,.faq-q i::after{content:"";position:absolute;background:var(--green);inset-inline:0;top:9px;height:2px;transition:transform var(--d-mid) var(--ease-mech)}
.faq-q{transition:background var(--d-ui) var(--ease-ui),color var(--d-ui) var(--ease-ui)}
.faq-q:hover{background:rgba(0,224,138,.04)}
.faq-item{transition:border-color var(--d-ui) var(--ease-ui)}
.faq-item.open,.faq-item:hover{border-color:var(--green-dim)}
.faq-q i::after{transform:rotate(90deg)}
.faq-q[aria-expanded="true"] i{transform:rotate(180deg)}
.faq-q[aria-expanded="true"] i::after{transform:rotate(0)}
/* (c) spring-like open/close: elastic height + content easing in */
/* Panel pivots open — --ease-swing. The inner copy trails slightly behind
   the panel edge (longer duration, entrance curve) so the text feels like
   it is carried by the panel rather than painted onto it. */
.faq-a{max-height:0;overflow:hidden;transition:max-height var(--d-mid) var(--ease-swing)}
.faq-a p{color:var(--muted);font-size:var(--fs-base);padding:0 20px 20px;margin:0;
  opacity:0;transform:translateY(-8px);
  transition:opacity var(--d-ui) var(--ease-ui),transform var(--d-slow) var(--ease-entrance)}
.faq-item.open .faq-a p{opacity:1;transform:none}

/* ============ CONTACT ============ */
.contact-grid{display:grid;grid-template-columns:1fr 1.05fr;gap:48px;align-items:start}
.con-list{margin:26px 0;display:grid;gap:14px}
.con-list li{display:flex;flex-direction:column;gap:2px;border-inline-start:2px solid var(--green-dim);padding-inline-start:14px}
.con-list li span{font-family:var(--font-mono);font-size:var(--fs-2xs);letter-spacing:var(--tr-wide);color:var(--muted-2);text-transform:uppercase}
.con-list li a,.con-list li b{color:var(--ink);font-size:var(--fs-md);font-weight:500}
.con-list li a:hover{color:var(--green)}
.quick-btns{display:flex;gap:10px;flex-wrap:wrap}

/* FIELDS — family gesture: FOCUS TRAVELS.
   A border colour swap plus a static ring is the stock treatment and reads
   as nothing happening. Here the label brightens and shifts toward the
   field, and a rule sweeps across the underside from the leading edge, so
   focus has a direction — it arrives rather than switching on. */
.contact-form{padding:30px}
.field{margin-bottom:18px;position:relative}
.field label{display:block;font-family:var(--font-mono);font-size:var(--fs-xs);letter-spacing:var(--tr-wide);
  color:var(--muted);margin-bottom:7px;text-transform:uppercase;
  transform-origin:left center;
  transition:color var(--d-ui) var(--ease-ui),transform var(--d-ui) var(--ease-entrance)}
[dir="rtl"] .field label{transform-origin:right center}
.field:focus-within label{color:var(--green);transform:translateX(2px)}
[dir="rtl"] .field:focus-within label{transform:translateX(-2px)}

.field input,.field textarea{width:100%;background:rgba(3,13,9,.6);border:1px solid var(--card-brd);border-radius:10px;
  color:var(--ink);font-family:var(--font-body);font-size:var(--fs-base);padding:13px 15px;resize:vertical;
  transition:border-color var(--d-ui) var(--ease-ui),
             box-shadow var(--d-ui) var(--ease-ui),
             background var(--d-ui) var(--ease-ui)}
.field input:hover,.field textarea:hover{border-color:rgba(74,158,122,.45)}
.field input:focus,.field textarea:focus{outline:none;border-color:var(--green);
  background:rgba(3,13,9,.85);box-shadow:0 0 0 3px rgba(0,224,138,.12)}
.field input[aria-invalid="true"],.field textarea[aria-invalid="true"]{
  border-color:#ff6b6b;box-shadow:0 0 0 3px rgba(255,107,107,.1)}

/* Error text keeps its reserved 1em of space (so appearing never shifts the
   layout) and eases in from just above — it should feel like it dropped out
   of the field it belongs to. :empty is the state hook, since the message is
   written via textContent. */
.err{display:block;color:#ff8585;font-size:var(--fs-xs);margin-top:6px;min-height:1em;
  opacity:0;transform:translateY(-4px);
  transition:opacity var(--d-ui) var(--ease-ui),transform var(--d-ui) var(--ease-entrance)}
.err:not(:empty){opacity:1;transform:none}
.form-status{margin:14px 0 0;font-size:var(--fs-base);text-align:center;min-height:1.2em}
.form-status.ok{color:var(--green)}
.form-status.bad{color:#ff8585}
.btn.is-loading{opacity:.7;pointer-events:none;position:relative}
.btn.is-loading::after{content:"";width:16px;height:16px;border:2px solid rgba(3,19,13,.4);border-top-color:#03130d;border-radius:50%;animation:spin .7s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}

/* ============ REZERVASYON / ÖN TALEP ============ */
.reserve-grid{display:grid;grid-template-columns:1fr 1.05fr;gap:44px;align-items:start}
.res-label{font-family:var(--font-mono);font-size:var(--fs-xs);letter-spacing:var(--tr-label);color:var(--muted);
  text-transform:uppercase;margin:0 0 16px}
.res-label::before{content:"› ";color:var(--green)}
.prod-slots{display:grid;gap:12px}

/* product slot — reads like a console row that can latch */
.prod-slot{
  display:flex;align-items:center;gap:16px;width:100%;text-align:start;
  background:rgba(3,13,9,.6);border:1px solid var(--card-brd);border-radius:14px;
  padding:16px 18px;cursor:pointer;color:var(--ink);position:relative;overflow:hidden;
  transition:border-color var(--d-ui) var(--ease-ui),
             transform var(--d-ui) var(--ease-press),
             box-shadow var(--d-ui) var(--ease-ui);
}
/* Slots are pressable controls, so they get the button family's press. */
.prod-slot:not([disabled]):active{transition-duration:70ms;transform:translateY(0) scale(.99)}
.prod-slot-mark{color:var(--green);flex:none;display:grid;place-items:center;
  transition:transform var(--d-mid) var(--ease-mech)}
.prod-slot-body{display:flex;flex-direction:column;gap:3px;flex:1;min-width:0}
.prod-slot-body b{font-family:var(--font-display);font-size:var(--fs-md);letter-spacing:var(--tr-normal)}
.prod-slot-body small{color:var(--muted);font-size:var(--fs-sm)}
.prod-slot-tag{font-family:var(--font-mono);font-size:var(--fs-3xs);letter-spacing:var(--tr-label);flex:none;
  border:1px solid var(--green-dim);color:var(--green);border-radius:999px;padding:4px 10px}

.prod-slot:not([disabled]):hover{border-color:var(--green-dim);transform:translateY(-2px)}
.prod-slot:not([disabled]):hover .prod-slot-mark{transform:rotate(-6deg) scale(1.06)}
.prod-slot.is-active{border-color:var(--green);box-shadow:0 0 40px rgba(0,224,138,.12) inset}
/* latched indicator bar on the active slot */
.prod-slot.is-active::after{content:"";position:absolute;inset-block:0;inset-inline-start:0;width:3px;background:var(--green)}

/* coming-soon slots: visibly inert */
.prod-slot--soon{cursor:not-allowed;opacity:.42;filter:grayscale(1);background:rgba(255,255,255,.015)}
.prod-slot--soon .prod-slot-mark{color:var(--muted-2)}
.prod-slot--soon .prod-slot-tag{border-color:var(--line);color:var(--muted-2)}
.prod-slot--soon .prod-slot-body b{color:var(--muted)}

.soon-note{font-family:var(--font-mono);font-size:var(--fs-2xs);letter-spacing:var(--tr-label);color:var(--muted-2);
  text-transform:uppercase;margin:14px 0 2px;display:flex;align-items:center;gap:10px}
.soon-note::after{content:"";flex:1;height:1px;background:linear-gradient(90deg,var(--line),transparent)}

.res-disclaimer{display:flex;gap:12px;align-items:flex-start;margin:26px 0 0;padding:16px 18px;
  border:1px dashed var(--card-brd);border-radius:12px;background:rgba(0,224,138,.03);
  color:var(--muted);font-size:var(--fs-sm);line-height:1.55}
.res-disclaimer-mark{flex:none;width:16px;height:16px;margin-top:3px;border:2px solid var(--green);
  border-radius:3px;transform:rotate(45deg);box-shadow:0 0 8px rgba(0,224,138,.4)}

/* form */
.reserve-form{padding:30px}
.field-row{display:grid;grid-template-columns:1fr 1fr;gap:0 16px}
.field .opt{color:var(--muted-2);text-transform:none;letter-spacing:0}
.field .hint{display:block;color:var(--muted-2);font-size:var(--fs-xs);margin-top:6px}
.field--qty .err{margin-top:2px}

/* quantity stepper — mechanical, matches the hinge language */
.qty-control{display:flex;align-items:stretch;gap:0;border:1px solid var(--card-brd);border-radius:10px;
  overflow:hidden;background:rgba(3,13,9,.6);transition:border-color var(--d-ui) var(--ease-ui),box-shadow var(--d-ui) var(--ease-ui)}
.qty-control:focus-within{border-color:var(--green);box-shadow:0 0 0 3px rgba(0,224,138,.12)}
.qty-control input{width:100%;flex:1;min-width:0;background:transparent;border:0;text-align:center;
  color:var(--ink);font-family:var(--font-mono);font-size:var(--fs-md);padding:13px 6px;-moz-appearance:textfield}
.qty-control input:focus{outline:none}
.qty-control input::-webkit-outer-spin-button,.qty-control input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.qty-btn{flex:none;width:48px;border:0;background:rgba(255,255,255,.03);color:var(--green);
  font-size:1.2rem;line-height:1;cursor:pointer;
  transition:background var(--d-ui) var(--ease-ui),transform var(--d-ui) var(--ease-press)}
.qty-btn:hover{background:rgba(0,224,138,.12)}
/* Already had the best press state on the page — kept, just re-curved so
   the release springs on --ease-press like every other pressable control. */
.qty-btn:active{transition-duration:70ms;transform:scale(.9)}
.qty-control input[aria-invalid="true"]{color:#ff8585}

/* honeypot — off-screen, never shown to humans */
.hp-field{position:absolute;left:-9999px;width:1px;height:1px;opacity:0;pointer-events:none}

.res-wa{margin-top:10px}

/* ============ FOOTER ============ */
/* Bottom padding clears the floating quick-contact widget, which is fixed
   58px tall at a 22px inset — 80px of reserved viewport corner. The footer's
   last line lands exactly there when the page is scrolled to the end, so with
   the old 34px the studio credit sat underneath the WhatsApp button. */
.site-footer{border-top:1px solid var(--line);padding:52px 0 88px;background:rgba(3,11,8,.6)}
.footer-inner{display:grid;grid-template-columns:1.4fr 1fr;gap:28px;align-items:start}
.foot-lockup{display:flex;align-items:center;gap:10px}
.foot-lockup .brand-mark{width:30px;height:30px}
.foot-legal{color:var(--muted);font-size:var(--fs-base);margin:10px 0 4px}
.foot-product{font-family:var(--font-mono);color:var(--green);font-size:var(--fs-sm);letter-spacing:var(--tr-wide)}
.foot-links{display:flex;flex-wrap:wrap;gap:8px 20px;justify-content:flex-end}
.foot-links a{color:var(--muted);font-size:var(--fs-base)}
.foot-links a:hover{color:var(--green)}
/* Bottom rule now carries the border the copyright used to own, so the
   copyright and the studio credit share one baseline row. flex-wrap does the
   mobile work: they stack rather than crushing together. */
.foot-bottom{grid-column:1/-1;border-top:1px solid var(--line);margin-top:22px;padding-top:20px;
  display:flex;flex-wrap:wrap;gap:6px 24px;justify-content:space-between;align-items:baseline}
.foot-copy{color:var(--muted-2);font-size:var(--fs-sm);margin:0}
/* Studio signature: one type step below the copyright it sits beside, and
   deliberately the quietest line on the page. --muted-2 rather than anything
   dimmer keeps it at 5.70:1 — quiet, but not below the AA floor. */
.foot-credit{color:var(--muted-2);font-size:var(--fs-xs);margin:0}
.foot-credit a{color:inherit;border-bottom:1px solid transparent;
  transition:color var(--d-ui) var(--ease-ui),border-color var(--d-ui) var(--ease-ui)}
.foot-credit a:hover{color:var(--green);border-bottom-color:var(--green-dim)}
.foot-credit a:focus-visible{outline:2px solid var(--green);outline-offset:3px;border-radius:2px}

/* ============ FLOATING QUICK-CONTACT ============ */
.qc{position:fixed;inset-block-end:22px;inset-inline-end:22px;z-index:120;display:flex;flex-direction:column;align-items:center}
.qc.hidden{display:none}
.qc-toggle{width:58px;height:58px;border-radius:50%;border:0;background:var(--wa);color:#fff;cursor:pointer;
  display:grid;place-items:center;box-shadow:0 10px 30px rgba(37,211,102,.35);
  transition:transform var(--d-ui) var(--ease-press),box-shadow var(--d-ui) var(--ease-ui)}
.qc-toggle:hover{transform:scale(1.06);box-shadow:0 14px 38px rgba(37,211,102,.45)}
.qc-toggle:active{transition-duration:70ms;transform:scale(.95)}
/* Both glyphs share one grid cell and cross-fade. The brand mark itself never
   rotates or distorts — only the neutral close glyph carries the motion. */
.qc-toggle-ico{grid-area:1/1;display:grid;place-items:center;
  transition:opacity var(--d-ui) var(--ease-ui),transform var(--d-ui) var(--ease-press)}
.qc-toggle-ico--close{opacity:0;transform:rotate(-40deg) scale(.72)}
.qc-toggle[aria-expanded="true"] .qc-toggle-ico--wa{opacity:0;transform:scale(.72)}
.qc-toggle[aria-expanded="true"] .qc-toggle-ico--close{opacity:1;transform:rotate(0) scale(1)}
.qc-fan{position:absolute;inset-block-end:70px;inset-inline-end:0;display:grid;gap:10px;pointer-events:none}
.qc-item{pointer-events:none;opacity:0;transform:translateY(14px) scale(.8);transform-origin:bottom right;
  display:flex;align-items:center;gap:10px;padding:11px 16px;border-radius:999px;font-family:var(--font-display);
  font-weight:600;font-size:var(--fs-sm);white-space:nowrap;border:1px solid var(--card-brd);background:rgba(6,26,18,.95);
  color:var(--ink);backdrop-filter:blur(8px);box-shadow:0 8px 24px rgba(0,0,0,.35);
  transition:opacity var(--d-ui) var(--ease-ui),transform var(--d-mid) var(--ease-press)}
.qc-item--wa{border-color:var(--wa)}
.qc-item::before{content:"";width:9px;height:9px;border-radius:50%;background:var(--green)}
/* the WhatsApp row carries the real mark instead of the generic status dot */
.qc-item--wa::before{display:none}
.qc-ico{flex:none;color:var(--wa)}
.qc.open .qc-fan{pointer-events:auto}
.qc.open .qc-item{opacity:1;transform:translateY(0) scale(1)}
/* Was .02/.07/.12s — a 50ms step invented locally while the reveal engine
   used --stagger-step (62ms). Two different staggers on one page read as
   two different products. */
.qc.open .qc-item:nth-child(1){transition-delay:calc(var(--stagger-step) * 0)}
.qc.open .qc-item:nth-child(2){transition-delay:calc(var(--stagger-step) * 1)}
.qc.open .qc-item:nth-child(3){transition-delay:calc(var(--stagger-step) * 2)}
.qc-item:hover{border-color:var(--green);color:var(--green)}
.qc-item--wa:hover{border-color:var(--wa);color:var(--wa)}
.qc-dismiss{position:absolute;inset-block-start:-8px;inset-inline-end:-8px;width:22px;height:22px;border-radius:50%;
  border:1px solid var(--card-brd);background:var(--bg-2);color:var(--muted);cursor:pointer;font-size:14px;line-height:1;display:grid;place-items:center;opacity:0;transition:opacity var(--d-ui) var(--ease-ui)}
.qc:hover .qc-dismiss,.qc.open .qc-dismiss{opacity:1}

/* ============ SCROLL REVEAL (fold) ============
   --stagger-i is assigned by the scroll engine (script.js §2) to each
   element's index within its own sibling group, so a grid row unfolds as
   one gesture instead of all cards firing in the same frame.
   Delay is clamped at 6 steps so a long row never feels like it lags. */
.reveal{
  opacity:0;transform:translate3d(0,28px,0);
  transition:opacity var(--d-slow) var(--ease-entrance),
             transform var(--d-slow) var(--ease-entrance);
  transition-delay:calc(var(--stagger-i,0) * var(--stagger-step));
}
.reveal.in-view{opacity:1;transform:none}

/* Fold reveal for cards/timeline: unfolds from the vertical centre line,
   echoing the way the product itself opens.
   clip-path is a paint-tier property, so it is driven ALONE here — the
   card's hover transform lives on a separate rule to avoid re-painting
   the clip on every pointer move. */
.fold-card{
  clip-path:inset(0 46% 0 46%);opacity:0;
  transition:clip-path var(--d-slow) var(--ease-entrance),
             opacity var(--d-mid) var(--ease-entrance);
  transition-delay:calc(var(--stagger-i,0) * var(--stagger-step));
}
.fold-card.in-view{clip-path:inset(0 0 0 0);opacity:1}
/* Once revealed, hand transform/border back to the hover transition at UI
   speed. Without this the hover would inherit the 820ms reveal timing. */
.fold-card.in-view{
  transition:clip-path var(--d-slow) var(--ease-entrance),
             opacity var(--d-mid) var(--ease-entrance),
             transform var(--d-ui) var(--ease-ui),
             border-color var(--d-ui) linear,
             box-shadow var(--d-ui) linear;
}

/* ============ ANIMATION SYSTEM v2 (grounded in the product world) ============ */

/* (e) PAGE-LOAD CINEMATIC ENTRANCE
   Only hidden when JS is active (html.js), so no-JS visitors still see content.

   This was a uniform 110ms-per-element stagger with one shared transform —
   which reads as a list animating, not as a scene assembling. It is now
   art-directed: each element has its own delay, distance and duration, and
   the two halves of the hero (copy and mechanism) rise TOGETHER rather than
   in sequence, so they read as one object.

   Beat sheet:
     0.05s  chrome (brand, header actions) settles from above
     0.18s  eyebrow
     0.28s  title wipes up behind a mask  ┐ same beat — the hero
     0.34s  mechanism stage rises         ┘ reads as a single unit
     0.48s  subhead
     0.60s  buttons
     0.95s  the fan unfurls (JS) — the finale, alone on stage
     1.40s  scroll cue                                                    */
html.js [data-load]{
  opacity:0;transform:translate3d(0,18px,0);
  transition:opacity var(--d-slow) var(--ease-entrance),
             transform var(--d-slow) var(--ease-entrance);
  transition-delay:var(--load-d,0s);
}
html.js body.loaded [data-load]{opacity:1;transform:none}

html.js .brand{--load-d:.05s;transform:translate3d(0,-10px,0)}
html.js .header-actions{--load-d:.09s;transform:translate3d(0,-10px,0)}
html.js .eyebrow{--load-d:.18s}
html.js .hero-sub{--load-d:.48s}
html.js .hero-btns{--load-d:.60s}

/* Title: wipes upward from behind its own baseline rather than fading.
   clip-path animates on the paint tier, but this runs exactly once on load
   for a single element, so the cost is a non-issue. */
html.js .hero-title{
  --load-d:.28s;
  clip-path:inset(0 0 105% 0);transform:translate3d(0,24px,0);
  transition:opacity var(--d-slow) var(--ease-entrance),
             transform 1s var(--ease-entrance),
             clip-path 1s var(--ease-entrance);
  transition-delay:var(--load-d);
}
html.js body.loaded .hero-title{clip-path:inset(0 0 -12% 0)}

/* Mechanism: rises and settles from slightly back in Z, so the stage feels
   like it arrives into depth rather than sliding up a plane. */
html.js .hero-mech{
  --load-d:.34s;
  transform:translate3d(0,26px,0) scale(.94);
  transition:opacity var(--d-mech) var(--ease-entrance),
             transform var(--d-mech) var(--ease-mech);
  transition-delay:var(--load-d);
}

/* Scroll cue arrives last, after the fan has finished opening — it should
   never compete with the signature moment. */
html.js .scroll-cue{--load-d:1.4s;opacity:0;transition:opacity var(--d-slow) var(--ease-entrance);transition-delay:var(--load-d)}
html.js body.loaded .scroll-cue{opacity:1}

/* (a) Specs console — values "type in" like a data readout, with a blinking caret */
/* ============ COMPARISON MATRIX (inside NEDEN YAFRUT) ============
   Shares the console's material — 1px lines, odd-row tint, mono labels — but
   reads as a matrix rather than a readout. The YAFRUT column is the only
   tinted surface; the alternative column stays deliberately neutral so the
   section argues rather than shouts. */
.cmp{margin-top:34px;border:1px solid var(--card-brd);border-radius:var(--radius);
  overflow:hidden;background:rgba(3,13,9,.7)}
.cmp-title{padding:15px 20px;border-bottom:1px solid var(--line);background:rgba(0,224,138,.04);
  font-family:var(--font-mono);font-size:var(--fs-2xs);letter-spacing:var(--tr-label);text-transform:uppercase;color:var(--muted)}
.cmp-row{display:grid;grid-template-columns:minmax(150px,1fr) 1.3fr 1.3fr;gap:16px;
  padding:15px 20px;border-bottom:1px solid var(--line);align-items:baseline}
.cmp-row:last-child{border-bottom:0}
.cmp-row:nth-of-type(odd){background:rgba(255,255,255,.012)}
.cmp-k{font-family:var(--font-mono);font-size:var(--fs-xs);letter-spacing:var(--tr-wide);color:var(--muted);text-transform:uppercase}
.cmp-k::before{content:"› ";color:var(--green)}
.cmp-v{color:var(--muted);font-size:var(--fs-base)}
.cmp-v b{font-weight:500}
/* the one emphasis in the table */
.cmp-us{color:var(--ink)}
.cmp-row:not(.cmp-row--head) .cmp-us{box-shadow:inset 2px 0 0 var(--green-dim);padding-inline-start:12px}
.cmp-row--head{background:rgba(0,224,138,.03)}
.cmp-row--head .cmp-v{font-family:var(--font-mono);font-size:var(--fs-2xs);letter-spacing:var(--tr-label);text-transform:uppercase}
.cmp-row--head .cmp-us{color:var(--green)}
/* per-value column tags: only needed once the columns stack on small screens */
.cmp-tag{display:none;font-family:var(--font-mono);font-size:var(--fs-3xs);letter-spacing:var(--tr-label);
  text-transform:uppercase;color:var(--muted-2);font-style:normal}
.cmp-note{margin-top:14px;font-size:var(--fs-sm);line-height:1.6;color:var(--muted-2);max-width:74ch}

.crow b.typing{white-space:pre-wrap}
.crow b.typing::after{content:"▌";color:var(--green);margin-inline-start:1px;animation:caret .7s step-end infinite}
@keyframes caret{50%{opacity:0}}

/* (b) Gallery — a scan line sweeps across each image once on scroll-into-view */
/* The dim-then-reveal is ARMED BY JS (.scan-armed). Without it the images
   simply show — previously they were dimmed by default and only undimmed by
   the observer, so with JS off every photo stayed at 55% opacity forever. */
.shot img{opacity:1;transition:opacity var(--d-slow) var(--ease-entrance)}
.shot.scan-armed img{opacity:.55}
.shot.scan-armed.scan img{opacity:1}
.shot::after{content:"";position:absolute;left:0;right:0;top:0;height:42%;pointer-events:none;z-index:2;opacity:0;
  transform:translateY(-120%);mix-blend-mode:screen;
  background:linear-gradient(180deg,transparent,rgba(0,224,138,.14) 44%,rgba(150,255,210,.75) 50%,rgba(0,224,138,.14) 56%,transparent)}
.shot.scan::after{animation:scan 1.15s ease-in-out forwards}
@keyframes scan{0%{opacity:0;transform:translateY(-120%)}12%{opacity:1}88%{opacity:1}100%{opacity:0;transform:translateY(320%)}}

/* (d) Dealer-tier cards — cursor-follow 3D tilt (JS sets perspective+rotate inline)
   PERF: will-change was applied permanently, which promotes all three cards
   to their own composited layers for the entire life of the page even though
   they only move while a pointer is inside one. Scoped to hover/focus so the
   hint is given just before it is needed and released afterwards. */
.tier-card:hover,.tier-card:focus-within{will-change:transform}

/* ============ SECTION ARRIVAL (signature moment 2) ============
   Played on a section when a nav click lands on it. Three beats, quiet
   enough to survive being seen on every nav click:
     1. a rule sweeps the section's top edge  (the "you are here" marker)
     2. the kicker settles in
     3. the heading follows a beat behind it
   Everything is transform/opacity, so the whole sequence composites. The
   section itself is never transformed — moving a full section on arrival
   would fight the scroll that just placed it. */
.section::before{
  content:"";position:absolute;inset-inline:0;top:0;height:1px;pointer-events:none;z-index:1;
  background:linear-gradient(90deg,transparent,var(--green),transparent);
  opacity:0;transform:scaleX(.2);
}
.section.arrived::before{animation:arriveSweep 900ms var(--ease-entrance) forwards}
@keyframes arriveSweep{
  0%{opacity:0;transform:scaleX(.2)}
  22%{opacity:.9}
  100%{opacity:0;transform:scaleX(1)}
}

/* The head re-states itself. `animation` rather than a transition, because
   this must be able to REPLAY on a section that has long since revealed —
   a transition has nowhere left to travel once .in-view has settled. */
.section.arrived .kicker{animation:arriveRise 620ms var(--ease-entrance) both}
.section.arrived .section-head h2{animation:arriveRise 700ms var(--ease-entrance) 70ms both}
@keyframes arriveRise{
  0%{opacity:0;transform:translate3d(0,10px,0)}
  100%{opacity:1;transform:none}
}

/* Product image sits slightly oversized so the scroll drift in §5c never
   exposes an edge inside the frame. will-change is justified here (unlike
   on the tier cards) because this element moves on every scroll frame for
   as long as it is on screen, not only during a hover. */
.yafrut-visual{overflow:hidden;border-radius:var(--radius)}
.yafrut-visual img{will-change:transform}

/* ============ RESPONSIVE ============ */
@media (max-width:960px){
  .nav{position:fixed;inset-block-start:var(--header-h);inset-inline:0;flex-direction:column;gap:2px;
    background:rgba(4,16,11,.97);backdrop-filter:blur(16px);padding:16px 6vw 28px;border-bottom:1px solid var(--line);
    transform:translateY(-140%);transition:transform var(--d-mid) var(--ease-swing);margin:0}
  .nav.open{transform:translateY(0)}
  .nav a{padding:14px 10px;font-size:var(--fs-md);border-bottom:1px solid var(--line)}
  .nav-toggle{display:flex;order:3}
  .header-actions .btn--sm{display:none}
  .hero-inner{grid-template-columns:1fr;text-align:center;gap:36px}
  .hero-btns{justify-content:center}
  .hero-sub{margin-inline:auto}
  .hero{min-height:auto}
  .yafrut-grid,.contact-grid,.reserve-grid{grid-template-columns:1fr;gap:36px}
  .grid-3,.grid-5,.grid-4{grid-template-columns:repeat(2,1fr)}
  .gallery-grid{grid-template-columns:repeat(2,1fr)}
  .timeline{grid-template-columns:1fr;gap:14px}
  .timeline::before{inset-inline-start:26px;inset-inline-end:auto;top:0;bottom:0;width:1px;height:auto;background:linear-gradient(180deg,transparent,var(--green-dim),transparent)}
  .tl-step{padding-top:0;padding-inline-start:72px;text-align:start;min-height:52px;display:flex;flex-direction:column;justify-content:center}
  .tl-num{left:0;transform:none}
  .footer-inner{grid-template-columns:1fr}
  .foot-links{justify-content:flex-start}
}
@media (max-width:560px){
  .grid-3,.grid-5,.grid-4{grid-template-columns:1fr}
  /* single column: the feature frame's 16:9 would be a letterbox strip on a
     phone, so it takes the same portrait crop as the rest */
  .gallery-grid{grid-template-columns:1fr}
  .shot--feature img{aspect-ratio:4/5}
  /* The matrix stacks: each row becomes a small block, and the per-value tags
     take over the job the column header was doing. The header row is clipped
     rather than display:none so it stays in the accessibility tree and the
     role="table" keeps its columnheaders. */
  .cmp-row{grid-template-columns:1fr;gap:7px}
  .cmp-row--head{position:absolute;width:1px;height:1px;margin:-1px;padding:0;
    overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}
  .cmp-tag{display:block;margin-bottom:1px}
  .cmp-k{margin-bottom:3px}
  .crow{grid-template-columns:1fr;gap:4px}
  .header-actions{gap:8px}
  .brand-name{letter-spacing:var(--tr-label);font-size:var(--fs-md)}
  .quick-btns .btn{flex:1}
  .field-row{grid-template-columns:1fr}
  .reserve-form{padding:22px}
  .prod-slot{padding:14px;gap:12px}
  .prod-slot-tag{display:none}
}

/* ============ RTL (Arabic) ============ */
[dir="rtl"] .eyebrow{flex-direction:row-reverse}
[dir="rtl"] .console-tag{margin-inline-start:auto}
[dir="rtl"] body{font-family:'Segoe UI',Tahoma,var(--font-body)}
[dir="rtl"] .hero-title,[dir="rtl"] h1,[dir="rtl"] h2,[dir="rtl"] h3{font-family:'Segoe UI',Tahoma,sans-serif}
/* reservation: mirror the mono "› " markers and flip the soon-note rule */
[dir="rtl"] .res-label::before{content:"‹ "}
[dir="rtl"] .soon-note::after{background:linear-gradient(270deg,var(--line),transparent)}
/* the quantity stepper stays LTR (− left, + right) so the number reads naturally */
[dir="rtl"] .qty-control{direction:ltr}
/* The widget sits on the left in RTL, so the fan must unfold from the bottom
   LEFT corner — transform-origin takes physical keywords and does not flip. */
[dir="rtl"] .qc-item{transform-origin:bottom left}
/* inset box-shadow offsets are physical — mirror the YAFRUT column's edge rule */
[dir="rtl"] .cmp-row:not(.cmp-row--head) .cmp-us{box-shadow:inset -2px 0 0 var(--green-dim)}
[dir="rtl"] .field--qty label,[dir="rtl"] .field--qty .hint{text-align:start}

/* ============ REDUCED MOTION ============ */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important;scroll-behavior:auto !important}
  /* Reveals resolve to their finished state with no delay. transition-delay
     is NOT covered by the blanket duration override above, so the stagger
     must be zeroed explicitly or content would still wait its turn. */
  .reveal,.fold-card{opacity:1 !important;transform:none !important;clip-path:none !important}
  *,*::before,*::after{transition-delay:0s !important;animation-delay:0s !important}
  .hinge-glow{opacity:.7 !important;transform:none !important}
  .fiber-canvas{display:none}
  .bg-grid{mask-image:radial-gradient(circle at 50% 30%,#000 0%,transparent 78%)}
  /* v2 animation static fallbacks */
  html.js [data-load]{opacity:1 !important;transform:none !important}
  /* v3 hero cinematic — resolve to the finished frame, not a fast version */
  html.js .hero-title{clip-path:none !important;transform:none !important;opacity:1 !important}
  html.js .hero-mech,html.js .hero-copy{transform:none !important;opacity:1 !important}
  html.js .scroll-cue{opacity:1 !important}
  .mech-stage.is-moving{box-shadow:none !important}
  .hinge-glow{animation:none !important}
  #mechShadow{filter:none !important;opacity:.28 !important}
  .bg-grid--far{display:none}
  .crow b.typing::after{display:none !important}
  .shot img{opacity:1 !important}
  .shot::after{display:none !important}
  .faq-a p{opacity:1 !important;transform:none !important}
  .tier-card{transform:none !important}
  .prod-slot,.prod-slot-mark,.qty-btn,.brand-mark{transform:none !important}
  /* v4 micro-interactions — colour/border feedback is retained (it is not
     motion and it is what conveys state), but every positional change is
     removed rather than merely shortened. */
  .btn,.btn:hover,.btn:active,.btn:focus-visible{transform:none !important}
  .fold-card:hover .card-icon{transform:none !important}
  .shot:hover img{transform:none !important}
  .nav a::after{transition:none !important}
  /* the lightbox still appears and disappears — it just stops easing in */
  .lbx,.lbx-fig img{transition:none !important}
  .lbx-fig img{transform:none !important}
  .qc-toggle:hover,.qc-toggle:active{transform:none !important}
  /* The glyph swap survives — it conveys open/closed state — but it becomes a
     pure cross-fade with no rotation or scale. */
  .qc-toggle-ico{transition-property:opacity !important}
  .qc-toggle-ico--close,
  .qc-toggle[aria-expanded="true"] .qc-toggle-ico--wa,
  .qc-toggle[aria-expanded="true"] .qc-toggle-ico--close{transform:none !important}
  .prod-slot:not([disabled]):active{transform:none !important}
  .field label,.field:focus-within label{transform:none !important}
  .err{opacity:1 !important;transform:none !important}
  .card::after{transition:none !important}
  /* v5 — arrival and media parallax are removed entirely, not shortened.
     The JS for both is already skipped under reduced motion; these rules
     guarantee the static end state even if that guard is ever bypassed. */
  .section::before{display:none !important}
  .section.arrived .kicker,
  .section.arrived .section-head h2{animation:none !important;opacity:1 !important;transform:none !important}
  .yafrut-visual img{transform:none !important;will-change:auto}
  /* Nothing moves under reduced motion, so release every compositing hint —
     these layers would otherwise hold GPU memory for no benefit at all. */
  .bg-grid,.bg-glow,.tier-card{will-change:auto !important}
}

/* ============ 404 PAGE ============
   Lives here rather than in a <style> block inside 404.html so the
   Content-Security-Policy in vercel.json can forbid inline styles
   outright (no 'unsafe-inline' in style-src). */
.nf{min-height:100vh;display:grid;place-items:center;text-align:center;padding:40px}
.nf-code{font-family:var(--font-display);font-size:clamp(5rem,20vw,11rem);font-weight:700;line-height:1;
  background:linear-gradient(180deg,#fff,#2ff0a4);-webkit-background-clip:text;background-clip:text;color:transparent}
.nf-svg{width:min(260px,60vw);margin:8px auto 20px}
.nf h1{font-size:clamp(1.3rem,3.5vw,2rem);margin-bottom:12px}
.nf p{color:var(--muted);max-width:44ch;margin:0 auto 28px}
.nf .tag{font-family:var(--font-mono);color:var(--green);letter-spacing:var(--tr-kicker);font-size:var(--fs-xs);margin-bottom:10px}
