/* ============================================================================
   Store Management — landing site
   Design system: "Industry" (steel-blue wireframe). Tokens below are copied
   verbatim from the design-system stylesheet; take every colour, font and
   spacing value from them rather than hard-coding a hex.
   ========================================================================= */

:root {
  --color-bg: #f2f2f3;
  --color-surface: #e9e9ea;
  --color-text: #1d1f20;
  /* TEAL — buttons and accent text only. The grounds, the grid, the frames and
     the hairlines stay steel blue: the owner wants the teal on the controls
     and the type, not on the background. */
  --color-accent: #14776E;
  --color-accent-2: #2EC4B6;
  --color-divider: color-mix(in srgb, #1d1f20 16%, transparent);

  /* Tonal ramps — generated in OKLCH on one shared lightness scale. */
  --color-neutral-100: #f5f5f8;
  --color-neutral-200: #e7e7ea;
  --color-neutral-300: #d4d4d7;
  --color-neutral-400: #b7b7ba;
  --color-neutral-500: #98989b;
  --color-neutral-600: #7a7a7d;
  --color-neutral-700: #5d5d60;
  --color-neutral-800: #424244;
  --color-neutral-900: #2b2b2d;

  --color-accent-100: #eef6ff;
  --color-accent-200: #BCEDE7;   /* v2 */
  --color-accent-300: #b5d9fd;
  --color-accent-400: #94bce3;
  --color-accent-500: #749dc4;
  --color-accent-600: #597ea3;
  --color-accent-700: #14776E;   /* v2 */
  --color-accent-800: #105F58;   /* derived — v2 draws no hover step */
  --color-accent-900: #1d2d3d;

  --font-heading: "Barlow Condensed", "Heebo", system-ui, sans-serif;
  --font-body: "Barlow", "Heebo", system-ui, sans-serif;

  --space-1: 3.4px;
  --space-2: 6.8px;
  --space-3: 10.2px;
  --space-4: 13.6px;
  --space-6: 20.4px;
  --space-8: 27.2px;

  --radius-sm: 2px;
  --radius-md: 4px;
  --radius-lg: 7px;

  /* Site-level roles derived from the ramps. */
  --ink: #1d2d3d;                       /* dark ground (accent-900) */
  --paper: #f2f2f3;                     /* light ground */
  --paper-text: #1d1f20;
  --ink-text: #f2f2f3;
  /* TEAL — this token colours the highlighted headline runs, the HUD figures,
     the kickers, every link, the live dot and the bar fills. --hud-dim and
     --hud-faint are NOT moved with it: they draw the frames, the panel edges
     and the input borders, which are background chrome and stay steel blue. */
  --hud: #2EC4B6;                       /* accent-400 */
  --hud-dim: rgba(148, 188, 227, 0.35);
  --hud-faint: rgba(148, 188, 227, 0.18);
  --scan-red: #ff5a5a;                  /* barcode-scanner beam (deliberate
                                           exception to the mono palette) */

  /* --color-accent is the design system's accent and stays as it is for rules,
     borders and icons. Behind light text it is not usable: #f2f2f3 on it is
     3.71, and 1.4.3 wants 4.5 for anything under 24px. These three are the
     ramp steps that clear it — 5.78, 8.87, 12.56 — so every state of a filled
     control passes, not just the resting one. */
  --accent-fill: var(--color-accent-700);
  --accent-fill-hover: var(--color-accent-800);
  --accent-fill-active: var(--color-accent-900);
  --gutter: clamp(28px, 5vw, 72px);
  --max: 1280px;
}

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

/* The UA rule for [hidden] loses to any class that sets `display`, and several
   toggled panels here are flex containers — so state it with weight. */
[hidden] { display: none !important; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--ink-text);
  font-family: var(--font-body);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { font-family: var(--font-heading); font-weight: 700; margin: 0; }
p { margin: 0; }

a { color: var(--hud); }
a:hover { color: var(--color-accent-200); }

:focus-visible { outline: 2px solid var(--hud); outline-offset: 2px; }
/* The ring (--hud) and the button fill are now the same hue, so they no longer
   separate — 2.49 where 1.4.11 asks 3.0. On a filled control the ring goes
   light: #BCEDE7 on #14776E is 4.21. */
.btn:focus-visible,
.tab:focus-visible,
.pause-btn:focus-visible,
.hero-vid__play:focus-visible { outline-color: var(--color-accent-200); }
::selection { background: color-mix(in srgb, var(--color-accent) 45%, transparent); }

img { max-width: 100%; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* 2.4.1 Bypass Blocks — the page's first tab stop. Parked above the viewport
   rather than hidden, because a display:none or clipped link cannot show a
   focus indicator (2.4.7); it slides in on focus and out again on blur. The
   fixed nav is z-40, so this has to clear it. */
.skip-link {
  position: fixed;
  /* Inset rather than flush, so the 2px focus ring at its 2px offset is not
     clipped by the top of the viewport. */
  top: 10px; inset-inline-start: 10px;
  z-index: 100;
  transform: translateY(-200%);
  padding: 14px 22px;
  background: var(--accent-fill);
  font-family: var(--font-heading);
  font-weight: 600; font-size: 17px; letter-spacing: .04em;
  text-decoration: none;
  transition: transform .18s ease;
}
/* Pinned against the global `a` and `a:hover` colours, which are tuned for the
   ink ground and would drop the label to 2.4 on this fill. */
.skip-link, .skip-link:hover, .skip-link:focus { color: var(--ink-text); }
.skip-link:focus { transform: none; }

/* The skip link's target. It is not in the tab order and is never operated by
   keyboard, so 2.4.7 does not reach it — and an outline drawn around the whole
   page reads as a rendering fault rather than as a focus indicator. */
main:focus { outline: none; }

/* ---------------------------------------------------------------- keyframes */

@keyframes smScan   { 0% { transform: translateY(-10vh); } 100% { transform: translateY(110vh); } }
/* Percentages resolve against the clipping wrapper, so the table beam sweeps
   the panel whatever its height. */
@keyframes smScanIn { 0% { top: -60px; } 100% { top: 100%; } }
@keyframes smBlink  { 0%, 49% { opacity: 1; } 50%, 100% { opacity: .15; } }
@keyframes smDrift  { from { background-position: 0 0, 0 0; } to { background-position: 0 64px, 64px 0; } }
@keyframes smBoot   { 0% { opacity: 0; letter-spacing: .6em; filter: blur(8px); }
                      60% { opacity: 1; letter-spacing: .04em; filter: blur(0); }
                      100% { opacity: 1; letter-spacing: .02em; } }
@keyframes smRise   { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: none; } }
@keyframes smPulse  { 0%, 100% { box-shadow: 0 0 0 0 rgba(148, 188, 227, .5); }
                      70% { box-shadow: 0 0 0 14px rgba(148, 188, 227, 0); } }
@keyframes smRing   { 0% { transform: scale(.6); opacity: 0; } 30% { opacity: .7; } 100% { transform: scale(1.6); opacity: 0; } }
@keyframes smTick   { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }
@keyframes smGlitch { 0%, 92%, 100% { transform: none; opacity: 1; }
                      93% { transform: translateX(-3px); opacity: .8; }
                      95% { transform: translateX(3px); }
                      97% { transform: none; opacity: .9; } }

/* Scroll reveal — an IntersectionObserver adds .is-in. Replaces the
   prototype's scroll-driven `animation-timeline: view()`, which only Chromium
   ships; the transition below reads the same and works everywhere. */
.reveal {
  opacity: 0;
  transform: translateY(40px);
  transition: opacity .8s cubic-bezier(.2, .8, .2, 1), transform .8s cubic-bezier(.2, .8, .2, 1);
  transition-delay: var(--reveal-delay, 0s);
}
.reveal.is-in { opacity: 1; transform: none; }

.wipe {
  clip-path: inset(0 0 0 100%);
  transition: clip-path 1s cubic-bezier(.2, .8, .2, 1);
  transition-delay: var(--reveal-delay, 0s);
}
.wipe.is-in { clip-path: inset(0 0 0 0); }

/* The end state overshoots the box so the registration marks, which sit 8px
   outside it, are not clipped away once the reveal finishes. */
.wipe-v {
  clip-path: inset(100% -12px -12px -12px);
  transition: clip-path 1s cubic-bezier(.2, .8, .2, 1);
}
.wipe-v.is-in { clip-path: inset(-12px); }

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

/* ------------------------------------------- blueprint registration marks */

/* Every framed object wears "+" crosshair marks at its corners. `.marks`
   draws two (top-right, bottom-left) with generated content; adding
   `.marks--4` plus an empty `<i class="mk">` child draws the other two.
   Placement is physical, not logical — the marks are symmetric decoration and
   must land in the same corners whatever the element's direction. */
.marks { position: relative; }
.marks::before, .marks::after,
.marks > .mk::before, .marks > .mk::after {
  content: "";
  position: absolute;
  width: 15px; height: 15px;
  pointer-events: none;
  z-index: 2;
  background:
    linear-gradient(var(--mark, rgba(29, 31, 32, .55)), var(--mark, rgba(29, 31, 32, .55))) 7px 0 / 1px 100% no-repeat,
    linear-gradient(var(--mark, rgba(29, 31, 32, .55)), var(--mark, rgba(29, 31, 32, .55))) 0 7px / 100% 1px no-repeat;
}
.marks::before { top: -8px; right: -8px; }
.marks::after  { bottom: -8px; left: -8px; }
/* inset:-1px makes the helper's box match the parent's border box, so the
   two extra marks land exactly where the other two do. */
.marks--4 > .mk { position: absolute; inset: -1px; pointer-events: none; }
.marks--4 > .mk::before { top: -8px; left: -8px; }
.marks--4 > .mk::after  { bottom: -8px; right: -8px; }
.on-ink { --mark: #94bce3; }

/* Smaller marks for buttons. */
.marks--sm::before, .marks--sm::after,
.marks--sm > .mk::before, .marks--sm > .mk::after {
  width: 11px; height: 11px;
  background:
    linear-gradient(var(--mark), var(--mark)) 5px 0 / 1px 100% no-repeat,
    linear-gradient(var(--mark), var(--mark)) 0 5px / 100% 1px no-repeat;
}
.marks--sm::before { top: -6px; right: -6px; }
.marks--sm::after  { bottom: -6px; left: -6px; }
.marks--sm > .mk::before { top: -6px; left: -6px; }
.marks--sm > .mk::after  { bottom: -6px; right: -6px; }

/* --------------------------------------------------------------- fixed HUD */

.hud {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 50;
}
.hud__progress {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: var(--hud);
  transform-origin: right;
  transform: scaleX(0);
}
.hud__corner {
  position: absolute;
  width: 22px; height: 22px;
  border: 0 solid rgba(148, 188, 227, .7);
}
.hud__corner--tr { top: 18px; right: 18px; border-top-width: 1px; border-right-width: 1px; }
.hud__corner--tl { top: 18px; left: 18px;  border-top-width: 1px; border-left-width: 1px; }
.hud__corner--br { bottom: 18px; right: 18px; border-bottom-width: 1px; border-right-width: 1px; }
.hud__corner--bl { bottom: 18px; left: 18px;  border-bottom-width: 1px; border-left-width: 1px; }
.hud__status {
  position: absolute;
  bottom: 24px; left: 52px;
  display: flex; align-items: center; gap: 8px;
  font-family: var(--font-heading);
  font-size: 12px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--hud);
}
/* The line is fixed and drifts over both grounds; --hud is 7.06 on the ink and
   1.78 on the paper. initScroll adds this class while a paper section is the
   one under it. accent-700 is 5.78 there — the same hue, taken down the ramp
   until it clears 1.4.3, exactly as the filled controls were.

   The design's own answer here was mix-blend-mode: difference, which was
   removed rather than kept: .hud carries z-index: 50, a stacking context is an
   isolation group for blending, so the property never had any effect — the
   painted pixels were the declared colour, measured. Left in place it reads
   like a working safeguard and is not one. */
.hud__status.is-on-paper { color: var(--color-accent-700); }
.hud__status.is-on-paper .dot-live { background: var(--color-accent-700); }
.dot-live {
  width: 7px; height: 7px;
  background: var(--hud);
  animation: smBlink 1.4s steps(1) infinite;
  flex: none;
}

/* 2.2.2 Pause, Stop, Hide. In flow in the scan panel, beside the live table,
   and stopping every animation on the page, rather than floating in a corner:
   fixed chrome sits over whatever the page has scrolled to, and at 390px it
   covered body text outright. Deliberately not inside .hud__status either —
   that line is mix-blend-mode: difference, and a control inside it measured
   1.78 against the paper sections. Here it carries the site's own button fill,
   5.78 either way. */
.readout__head-live { display: flex; align-items: center; gap: 12px; }
.pause-btn {
  padding: 4px 12px;
  border: 1px solid var(--hud);
  background: var(--accent-fill);
  color: var(--ink-text);
  font-family: var(--font-heading);
  font-size: 12px; font-weight: 600; letter-spacing: .14em;
  line-height: 1.5;
  cursor: pointer;
  white-space: nowrap;
  transition: background .2s;
}
.pause-btn:hover { background: var(--accent-fill-hover); }
.pause-btn:active { background: var(--accent-fill-active); }
.panel__meta .pause-btn { margin-inline-start: 4px; }

/* Freezes every CSS animation where it stands — the blinking dot, the drifting
   grid, the scan beams, the hero's pulse. `paused` and not `none`, so a resume
   picks up mid-cycle instead of snapping back to the first frame. */
.is-paused *, .is-paused *::before, .is-paused *::after {
  animation-play-state: paused !important;
}

/* ------------------------------------------------------------------- nav */

.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 40;
  display: flex; align-items: center; gap: clamp(20px, 2.8vw, 40px);
  padding: 22px var(--gutter);
  background: linear-gradient(180deg, rgba(29, 45, 61, .85), rgba(29, 45, 61, 0));
  backdrop-filter: blur(6px);
}
/* The brand is pinned to the leading edge; everything after it is pushed to
   the far trailing edge. */
.nav__brand {
  display: flex; align-items: center; gap: 12px;
  text-decoration: none;
  color: var(--ink-text);
  margin-inline-end: auto;
  flex: none;
}
.nav__brand img { height: clamp(32px, 3.9vw, 56px); width: auto; display: block; flex: none; }
.nav__brand span {
  font-family: var(--font-heading);
  font-weight: 600; font-size: clamp(18px, 2.1vw, 30px); letter-spacing: .06em;
  margin-inline-start: 12px;
  white-space: nowrap;
}
/* Doubled at the owner's request. It is a clamp rather than a flat 24px
   because a fixed 24px overflows the bar between 861px — where the links stop
   being hidden — and about 1200px. The 2× value is reached from ~1410px up. */
.nav__link {
  color: var(--ink-text);
  text-decoration: none;
  font-size: clamp(15px, 1.7vw, 24px);
  opacity: .8;
  white-space: nowrap;
  transition: opacity .2s;
}
.nav__link:hover, .nav__link:focus-visible { opacity: 1; color: var(--ink-text); }

/* ---------------------------------------------------------------- buttons */

.btn {
  position: relative;
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font-heading);
  font-weight: 600;
  text-decoration: none;
  border: 1px solid var(--accent-fill);
  background: var(--accent-fill);
  color: var(--ink-text);
  cursor: pointer;
  transition: background .2s;
  --mark: #94bce3;
}
/* Darker on hover, not lighter: the lighter steps of the ramp drop the label
   to 2.55 against white. */
.btn:hover { background: var(--accent-fill-hover); border-color: var(--accent-fill-hover); color: var(--ink-text); }
.btn:active { background: var(--accent-fill-active); border-color: var(--accent-fill-active); }
.btn--nav { padding: clamp(8px, .85vw, 12px) clamp(16px, 1.8vw, 26px); font-size: clamp(15px, 1.7vw, 24px); white-space: nowrap; flex: none; }
.btn--hero { padding: 14px 28px; font-size: 18px; animation: smPulse 2.4s infinite; }
.btn--ghost {
  background: transparent;
  border-color: rgba(242, 242, 243, .25);
  color: var(--ink-text);
  padding: 14px 22px;
  font-size: 18px;
}
.btn--ghost:hover { background: rgba(242, 242, 243, .08); }
.btn--block { width: 100%; justify-content: center; min-height: 52px; font-size: 19px; letter-spacing: .04em; }

/* ------------------------------------------------------------- structure */

.section { position: relative; padding: 140px var(--gutter); overflow: hidden; }
.section--ink   { background: var(--ink); color: var(--ink-text); }
.section--paper { background: var(--paper); color: var(--paper-text); }
.wrap { position: relative; max-width: var(--max); margin: 0 auto; }

.grid-bg {
  position: absolute; inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(rgba(148, 188, 227, .08) 1px, transparent 1px),
    linear-gradient(90deg, rgba(148, 188, 227, .08) 1px, transparent 1px);
  background-size: 64px 64px;
}
.grid-bg--drift { animation: smDrift 12s linear infinite; }
.grid-bg--paper {
  background-image:
    linear-gradient(rgba(29, 31, 32, .05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(29, 31, 32, .05) 1px, transparent 1px);
}
.glow { position: absolute; inset: 0; pointer-events: none; }

.scanlines {
  position: absolute; inset: 0;
  background: repeating-linear-gradient(0deg, rgba(0, 0, 0, .18) 0 1px, transparent 1px 3px);
  pointer-events: none;
  opacity: .6;
}
/* Barcode-scanner beam — a hard red line with a soft halo. */
.beam {
  position: absolute; left: 0; right: 0; top: 0;
  height: 120px;
  background: linear-gradient(180deg,
    transparent,
    rgba(224, 64, 64, .16) 48%,
    var(--scan-red) 50%,
    rgba(224, 64, 64, .16) 52%,
    transparent);
  animation: smScan 6s linear infinite;
  pointer-events: none;
}
.beam--table {
  height: 60px;
  background: linear-gradient(180deg,
    transparent,
    rgba(224, 64, 64, .2) 46%,
    var(--scan-red) 50%,
    rgba(224, 64, 64, .2) 54%,
    transparent);
  animation: smScanIn 4s linear infinite;
}
/* Scan effects only render when the toggle is on (see SCANLINES in app.js). */
body:not(.scanlines-on) .scanlines,
body:not(.scanlines-on) .beam { display: none; }

.kicker {
  display: flex; align-items: center; gap: 12px;
  font-family: var(--font-heading);
  font-size: 13px; letter-spacing: .14em; text-transform: uppercase;
  /* Pinned, not `normal`. The rule sits at the centre of this box, and in
     #demo that centre has to land on the form card's top border across the
     grid gap (see .demo__copy). Left to the font, the box is ~20px with Heebo
     loaded and ~15px before it arrives — which would shift the rule off the
     border during the webfont swap. 20px is what the design renders. */
  line-height: 20px;
  color: var(--color-accent-700);
}
.kicker::after { content: ""; flex: 1; height: 1px; background: rgba(29, 31, 32, .16); }
.kicker--ink { color: var(--hud); }
.kicker--ink::after { background: rgba(148, 188, 227, .25); }

.rule-top {
  position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--color-accent), transparent);
}

.h-display {
  font-family: var(--font-heading);
  font-weight: 800;
  line-height: 1.02;
  letter-spacing: -.01em;
  text-wrap: balance;
}
.lead { font-size: 17px; line-height: 1.6; }
.on-paper .lead, .section--paper .lead { color: rgba(29, 31, 32, .78); }
.section--ink .lead { color: rgba(242, 242, 243, .75); }

.card {
  position: relative;
  border: 1px solid rgba(29, 31, 32, .16);
  padding: 28px;
}
.card--ink { border-color: var(--hud-dim); }
.card__code {
  font-family: var(--font-heading);
  font-size: 13px; letter-spacing: .14em;
  color: var(--color-accent-700);
}
.card__title { margin-top: 14px; font-size: 26px; line-height: 1.1; }
.card__body { margin-top: 14px; font-size: 15px; line-height: 1.6; color: rgba(29, 31, 32, .78); }

/* ------------------------------------------------------- 01 · hero */

.hero {
  min-height: 100vh;
  min-height: 100svh;
  display: grid; align-items: center;
  padding: 140px var(--gutter) 80px;
}
.hero .grid-bg { mask-image: radial-gradient(ellipse at 70% 40%, #000 20%, transparent 75%); }
.hero .glow { background: radial-gradient(ellipse at 75% 35%, rgba(89, 128, 166, .45), transparent 55%); }
.hero__inner {
  position: relative;
  display: grid;
  /* The design says 7fr/5fr. The owner asked for the right half to match the
     copy column, so the hero is split down the middle. The halves are
     bottom-aligned: the video's tagline stands on the line of the buttons. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 48px; align-items: end;
  max-width: var(--max); margin: 0 auto; width: 100%;
}
.hero__eyebrow {
  display: flex; align-items: center; gap: 12px;
  font-family: var(--font-heading);
  font-size: 13px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--hud);
  animation: smBoot 1.6s cubic-bezier(.2, .8, .2, 1) both;
}
.hero__eyebrow::before { content: ""; width: 28px; height: 1px; background: var(--hud); flex: none; }
.hero__title {
  margin-top: 28px;
  font-size: clamp(52px, 8vw, 118px);
  line-height: 1;
  color: var(--ink-text);
}
.hero__title span { display: block; animation: smRise 1s cubic-bezier(.2, .8, .2, 1) both; }
.hero__title span:nth-child(1) { animation-delay: .3s; }
.hero__title span:nth-child(2) { animation-delay: .5s; }
.hero__title span:nth-child(3) {
  color: var(--hud);
  animation: smRise 1s .7s cubic-bezier(.2, .8, .2, 1) both, smGlitch 7s 2s infinite;
}
.hero__lead {
  margin-top: 32px; max-width: 56ch;
  font-size: 18px; line-height: 1.6;
  color: rgba(242, 242, 243, .75);
  animation: smRise 1s .9s cubic-bezier(.2, .8, .2, 1) both;
}
.hero__actions {
  display: flex; gap: 14px; flex-wrap: wrap; margin-top: 40px;
  animation: smRise 1s 1.1s cubic-bezier(.2, .8, .2, 1) both;
}
.hero__scroll {
  position: absolute; bottom: 28px; left: 50%;
  transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  font-family: var(--font-heading);
  font-size: 12px; letter-spacing: .2em;
  /* .5 is 4.32 on the ink — under 1.4.3's 4.5 for 12px text. .58 is 5.27. */
  color: rgba(242, 242, 243, .58);
}
.hero__scroll i {
  width: 1px; height: 40px;
  background: linear-gradient(180deg, var(--hud), transparent);
  animation: smTick 1.6s infinite;
}

/* The owner's video, in the place the data panel held (03.10). The frame holds
   16:9 itself, with the poster and later the iframe positioned inside it —
   WebKit does not resolve `aspect-ratio` through a flex child with `flex: 1`,
   which is how the mobile screenshots once collapsed to zero height. It is
   centred against the copy column rather than stretched to its height: the
   panel could grow, a video frame cannot. .hero__media is a plain block, not
   a flex column, for the same WebKit reason — side by side it is a grid (below),
   where the frame's width is its own and the ratio derives the height. */
.hero__media {
  animation: smRise 1.2s 1s cubic-bezier(.2, .8, .2, 1) both;
}
.hero-vid {
  position: relative;
  aspect-ratio: 16 / 9;
  border: 1px solid var(--hud-dim);
  background: var(--ink);
}
/* Title above, tagline below; both gaps clear the frame's corner marks, which
   hang 8px outside it. One size for the two, so the lettering above and below
   the video matches at every width (owner, 05.10 — the title's size, chosen
   over the H1's that the tagline carried for a day). */
.hero__media { --vid-fs: clamp(56px, 6vw, 88px); }
.hero-vid__title,
.hero-vid__tag {
  font-size: var(--vid-fs);
  color: var(--ink-text);
}
.hero-vid__title { margin-bottom: 22px; text-align: center; }
.hero-vid__tag { margin-top: 22px; }
.hero-vid__tag span { color: var(--hud); }
/* Side by side, the tagline's last line stands on the bottom line of the
   copy column's buttons (owner, 04.10). Both columns are bottom-aligned, and
   the tagline's box is pulled down by the gap between its baseline and its
   box bottom — .112–.122em of Heebo at this line-height, measured from 1100
   to 1920 — so the letters, not the box, meet the line. */
@media (min-width: 1081px) {
  .hero-vid__tag { margin-bottom: -.115em; }
}
/* Side by side, the title, the video and the tagline stay between the top of
   the H1 and the bottom line of the buttons, and the lettering gives way, not
   the video (owner, 18.10). The column is stretched to the copy's row and
   contributes no height of its own (a size container), less a top margin of
   the eyebrow's line (13px at the page's 1.5) and the H1's 28px. The video
   keeps the full width; the title and tagline share what is left — 1.02em for
   the title, 2 × 1.02em for the two-line tagline less its .115em pull, after
   the frame and the two 22px gaps — capped at the size they had before.

   That arithmetic holds only for a two-line tagline, and at this size the
   whole line fits on one from 1280 up, which left ~60px above the title (owner,
   18.10: «זה כבר לא ישר עם המלל»). So side by side the tagline breaks where it
   used to fall, «סרוק. השאר» over «קורה לבד.»; stacked, the break is hidden and
   the line wraps where it falls, as before.

   The poster has no `decoding="async"`: inside a size container Chromium often
   did not paint the asynchronously decoded image at all — the frame stayed
   ink-dark in six of eight runs with it, and showed the poster in every run
   without. */
.hero-vid__br { display: none; }
@media (min-width: 1081px) {
  .hero__media {
    --vid-fs: min(clamp(56px, 6vw, 88px), (100cqh - 100cqw * 9 / 16 - 44px) / 2.945);
    align-self: stretch;
    container-type: size;
    display: grid; align-content: end;
    margin-top: calc(13px * 1.5 + 28px);
  }
  .hero-vid__br { display: inline; }
}
.hero-vid picture,
.hero-vid img,
.hero-vid iframe {
  position: absolute; inset: 0;
  display: block; width: 100%; height: 100%;
  border: 0;
}
.hero-vid img { object-fit: cover; }
.hero-vid__play {
  position: absolute; inset: 0; margin: auto;
  width: 84px; height: 84px;
  display: grid; place-items: center;
  border: 1px solid var(--hud);
  border-radius: 50%;
  background: var(--accent-fill);
  color: var(--ink-text);
  cursor: pointer;
  box-shadow: 0 8px 28px rgba(0, 0, 0, .35);
  transition: background .2s, transform .2s;
}
.hero-vid__play:hover { background: var(--accent-fill-hover); transform: scale(1.05); }
.hero-vid__play:active { background: var(--accent-fill-active); }
/* A play triangle points right in every script, Hebrew included, and its
   optical centre sits left of its box — so the nudge is physical, not
   logical: `margin-inline-start` would push it the wrong way under RTL. */
.hero-vid__play svg { width: 34px; height: 34px; fill: currentColor; transform: translateX(3px); }

.readout {
  position: relative;
  display: flex; flex-direction: column; justify-content: space-between;
  border: 1px solid var(--hud-dim);
  padding: 28px;
  font-family: var(--font-heading);
  background: rgba(29, 45, 61, .5);
  backdrop-filter: blur(4px);
  animation: smRise 1.2s 1s cubic-bezier(.2, .8, .2, 1) both;
}
.readout__head {
  display: flex; justify-content: space-between;
  font-size: 17px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--hud);
  border-bottom: 1px solid rgba(148, 188, 227, .25);
  padding-bottom: 12px;
}
.readout__stats {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 44px; margin-top: 34px;
}
.readout__label { font-size: 17px; letter-spacing: .1em; color: rgba(242, 242, 243, .55); }
.readout__value {
  /* Scales with the viewport rather than sitting at a flat 70px: the two-column
     stats grid sets the readout's min-content, and "אוטומטית" at 70px is wider
     than the column gets below about 1400px. */
  font-size: clamp(30px, 3.76vw, 56px);
  font-weight: 600; line-height: 1; margin-top: 10px;
  font-variant-numeric: tabular-nums;
}
.readout__value--accent { color: var(--hud); }
.readout__bars { margin-top: 36px; display: flex; flex-direction: column; gap: 20px; }
.bar { display: flex; align-items: center; gap: 16px; font-size: 18px; color: rgba(242, 242, 243, .7); }
.bar__label { width: 118px; flex: none; }
.bar__track { flex: 1; height: 12px; background: rgba(148, 188, 227, .15); position: relative; }
.bar__fill {
  position: absolute; inset: 0;
  background: var(--hud);
  transform-origin: right;
  transform: scaleX(0);
  transition: transform .9s cubic-bezier(.2, .8, .2, 1);
}
.bar__pct { width: 50px; text-align: left; font-variant-numeric: tabular-nums; }

/* -------------------------------------------------- 02 · problem */

.ghost-number {
  position: absolute;
  right: -4vw;
  top: 50%;
  margin-top: -.5em;
  font-family: "Barlow Condensed", sans-serif;
  font-weight: 600;
  font-size: clamp(200px, 32vw, 480px);
  line-height: 1;
  color: transparent;
  -webkit-text-stroke: 1px rgba(89, 128, 166, .25);
  pointer-events: none;
  will-change: transform;
}
.cards-3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(20px, 3vw, 48px);
}

/* --------------------------------------------------- 03 · system */

.system__head {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: 48px; align-items: end; margin-top: 36px;
}
.feature {
  min-height: 230px;
  display: flex; flex-direction: column;
  transition: background .3s;
}
.feature:hover { background: rgba(89, 128, 166, .06); }
.feature__top { display: flex; justify-content: space-between; align-items: center; }
.feature__top svg { color: var(--icon, var(--color-accent)); display: block; }
/* The design gives every module icon the same accent. The owner asked for
   colour, so each module carries its own hue — all held near the accent's own
   lightness and saturation so the grid still reads as one family. */
.feature--i1 { --icon: #4f8a80; }   /* live stock       */
.feature--i2 { --icon: #5980a6; }   /* catalogue        */
.feature--i3 { --icon: #a8813f; }   /* supplier orders  */
.feature--i4 { --icon: #7a6aa6; }   /* returns          */
.feature--i5 { --icon: #5d8f57; }   /* reports          */
.feature--i6 { --icon: #b05c52; }   /* alerts           */
.feature__title { margin-top: 22px; font-size: 24px; line-height: 1.1; }
.feature__body { margin-top: 12px; font-size: 15px; line-height: 1.6; color: rgba(29, 31, 32, .78); }

/* --------------------------------------- 03b · how it works + screens */

.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(20px, 3vw, 48px); margin-top: 64px; position: relative; }
.steps__line {
  position: absolute; top: 34px; right: 10%; left: 10%; height: 1px;
  background: repeating-linear-gradient(90deg, var(--color-accent) 0 6px, transparent 6px 12px);
}
.step { position: relative; }
.step__n {
  width: 68px; height: 68px;
  border: 1px solid var(--color-accent);
  background: var(--paper);
  display: grid; place-items: center;
  font-family: "Barlow Condensed", sans-serif;
  font-size: 30px; font-weight: 600;
  color: var(--color-accent-700);
  position: relative; z-index: 1;
}
.step__n--solid { background: var(--color-accent); color: var(--ink-text); }
.step h3 { margin-top: 24px; font-size: 26px; line-height: 1.1; }
.step p { margin-top: 12px; font-size: 15px; line-height: 1.6; color: rgba(29, 31, 32, .78); max-width: 34ch; }

.screens {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: clamp(20px, 3vw, 48px);
  margin-top: 96px;
  align-items: stretch;
  height: clamp(320px, 38vw, 560px);
}
.screens figure { margin: 0; border: 1px solid rgba(29, 31, 32, .16); position: relative; display: flex; flex-direction: column; }
/* Screenshot frame — the port of the design's <image-slot>. Unfilled it shows
   its placeholder caption on the slot's own black ground; filled it holds an
   <img> laid out by initSlots() with the same cover-fit maths the design uses,
   so the crop survives a responsive resize. */
.slot {
  position: relative;
  width: 100%; flex: 1; min-height: 0;
  display: grid; place-items: center;
  overflow: hidden;
  padding: 24px;
  text-align: center;
  background: #000;
  color: rgba(242, 242, 243, .45);
  font-family: var(--font-heading);
  font-size: 14px; letter-spacing: .06em;
}
.slot.is-filled { padding: 0; }
.slot img {
  position: absolute;
  max-width: none;
  display: block;
  transform: translate(-50%, -50%);
}
/* Fallback for a filled slot with no data-view: plain centred cover. */
.slot.is-filled:not(.is-framed) img {
  inset: 0; width: 100%; height: 100%;
  object-fit: cover; transform: none;
}

/* ------------------------------------------------ 04 · live scan */

.scan .grid-bg {
  background-image:
    linear-gradient(rgba(148, 188, 227, .07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(148, 188, 227, .07) 1px, transparent 1px);
  mask-image: radial-gradient(ellipse at 50% 50%, #000 30%, transparent 80%);
}
.scan__head {
  display: flex; justify-content: space-between; align-items: end;
  gap: 32px; flex-wrap: wrap; margin-top: 36px;
}
.tabs {
  display: inline-flex;
  border: 1px solid var(--hud-dim);
  font-family: var(--font-heading);
  font-weight: 600; font-size: 15px;
}
.tab {
  padding: 10px 18px;
  border: 0;
  background: transparent;
  color: var(--ink-text);
  font: inherit;
  cursor: pointer;
  transition: background .25s;
}
.tab + .tab { border-inline-start: 1px solid var(--hud-dim); }
.tab:hover { background: rgba(148, 188, 227, .18); }
.tab[aria-pressed="true"] { background: var(--accent-fill); }

.panel {
  position: relative;
  margin-top: 64px;
  border: 1px solid var(--hud-dim);
  background: rgba(29, 45, 61, .6);
}
/* The beam is clipped by its own wrapper — clipping the panel itself would
   also cut off the registration marks outside its border box. */
.panel__beam {
  position: absolute; inset: 0;
  overflow: hidden;
  pointer-events: none;
}
.panel__meta {
  display: flex; flex-wrap: wrap;
  border-bottom: 1px solid rgba(148, 188, 227, .25);
  font-family: var(--font-heading);
  font-size: 13px; letter-spacing: .1em; text-transform: uppercase;
}
.panel__meta > span { padding: 12px 24px; color: rgba(242, 242, 243, .7); }
.panel__meta > span + span { border-inline-start: 1px solid rgba(148, 188, 227, .25); }
.panel__meta > span:first-child { flex: 1; min-width: 16ch; font-weight: 600; color: var(--ink-text); }
.panel__meta > span:last-child { color: var(--hud); display: flex; align-items: center; gap: 8px; }
.panel__meta .dot-live { animation-duration: 1s; }

/* The "this is a mock" label under the scan panel. Quieter than the panel it
   qualifies, but a disclaimer nobody can read is not a disclaimer: .72 alpha
   is 7.26 on the ink, well clear of 4.5. */
.panel__note {
  margin-top: 20px;
  max-width: 92ch;
  font-size: 14px; line-height: 1.65;
  color: rgba(242, 242, 243, .72);
}

.tbl__head, .tbl__row {
  display: grid;
  grid-template-columns: 2fr 1.2fr 1fr 1fr 1.2fr;
  padding: 10px 24px;
}
.tbl__head {
  font-family: var(--font-heading);
  font-size: 12px; letter-spacing: .1em;
  color: rgba(242, 242, 243, .55);
  border-bottom: 1px solid rgba(148, 188, 227, .18);
}
.tbl__row {
  align-items: center;
  padding: 14px 24px;
  border-bottom: 1px solid rgba(148, 188, 227, .1);
  font-size: 15px;
  transition: background .2s;
}
.tbl__row:hover { background: rgba(148, 188, 227, .08); }
.tbl__name { font-weight: 500; }
/* Barcodes sit at the right edge of their own column, LTR digits. */
.tbl__barcode {
  font-family: "Barlow Condensed", sans-serif;
  letter-spacing: .06em;
  color: rgba(242, 242, 243, .6);
  font-variant-numeric: tabular-nums;
  text-align: right;
  direction: ltr;
}
.tbl__num {
  font-family: "Barlow Condensed", sans-serif;
  font-size: 22px; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.tbl__num--low { color: var(--scan-red); }
.tbl__status {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-heading);
  font-size: 13px; letter-spacing: .08em;
  color: rgba(242, 242, 243, .55);
}
.tbl__status::before { content: ""; width: 6px; height: 6px; background: currentColor; flex: none; }
.tbl__status--low { color: var(--scan-red); }
.panel__foot {
  display: flex; justify-content: space-between; align-items: center;
  gap: 16px; flex-wrap: wrap;
  padding: 16px 24px;
  font-size: 14px; color: rgba(242, 242, 243, .7);
}
/* The count in the panel foot is the same alert as the rows it counts. */
.panel__foot b { color: var(--scan-red); }
.panel__cta {
  font-family: var(--font-heading);
  font-weight: 600; font-size: 14px;
  color: var(--hud); letter-spacing: .06em;
}

/* ---------------------------------------------- 05 · logo plate */

.plate {
  position: relative;
  border: 1px solid rgba(29, 31, 32, .16);
  margin-top: 48px;
  display: flex; flex-direction: column; align-items: center;
  text-align: center;
  padding: clamp(56px, 7vw, 96px) clamp(24px, 5vw, 72px);
  gap: 20px;
}
.plate__logo { width: clamp(160px, 18vw, 260px); height: auto; }
.plate__word,
.plate__line {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 800;
  line-height: 1;
  color: var(--paper-text);
}
.plate__word { font-size: clamp(48px, 7vw, 104px); letter-spacing: -.01em; }
.plate__line { font-size: clamp(40px, 5.5vw, 80px); }
.plate__rule { width: 64px; height: 1px; background: var(--color-accent); margin: 8px 0; }
.plate__note {
  margin: 0;
  font-size: clamp(15px, 1.4vw, 19px);
  line-height: 1.6;
  color: rgba(29, 31, 32, .78);
  max-width: 56ch;
}

/* ------------------------------------ 05b · testimonials + FAQ */

/* Grid stretches the three cards to a common height, but the attributions
   would still land wherever each quote happens to end. Push them to the
   bottom of the card so all three sit on one line. */
.quote { margin: 0; display: flex; flex-direction: column; }
.quote blockquote {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 600; font-size: 24px; line-height: 1.25;
}
.quote figcaption { margin-top: auto; padding-top: 20px; font-size: 14px; color: rgba(29, 31, 32, .7); }
.quote figcaption em { font-style: normal; color: var(--color-accent-700); }

.faq {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: 48px; margin-top: 120px; align-items: start;
}
.faq__list { border-top: 1px solid rgba(29, 31, 32, .16); }
.faq__item { border-bottom: 1px solid rgba(29, 31, 32, .16); transition: background .25s; }
.faq__item[data-open="true"] { background: rgba(89, 128, 166, .06); }
.faq__q {
  width: 100%;
  display: flex; justify-content: space-between; align-items: center; gap: 16px;
  padding: 20px 16px;
  background: transparent; border: 0;
  font: inherit; text-align: right;
  cursor: pointer;
  color: var(--paper-text);
  min-height: 56px;
}
.faq__q:hover { color: var(--color-accent-700); }
.faq__q span:first-child { font-family: var(--font-heading); font-weight: 600; font-size: 22px; }
.faq__sign {
  font-family: "Barlow Condensed", sans-serif;
  font-size: 26px; color: var(--color-accent);
  width: 28px; text-align: center; flex: none;
  direction: ltr;
}
.faq__a {
  padding: 0 16px 22px;
  font-size: 15px; line-height: 1.65;
  color: rgba(29, 31, 32, .78);
  max-width: 60ch;
  animation: smRise .4s cubic-bezier(.2, .8, .2, 1) both;
}
.faq__a[hidden] { display: none; }

/* ------------------------------------------------ 06 · demo form */

.demo .grid-bg { mask-image: radial-gradient(ellipse at 30% 50%, #000 20%, transparent 75%); }
.demo .glow { background: radial-gradient(ellipse at 25% 50%, rgba(89, 128, 166, .4), transparent 55%); }
.demo__inner {
  position: relative;
  max-width: var(--max); margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 6fr) minmax(0, 6fr);
  gap: 64px; align-items: start;
}
/* The design nudges the copy column up by 10px so the kicker's rule lands on
   the same line as the form card's top border. */
.demo__copy { margin-top: -10px; }
.demo__stats { display: flex; gap: 32px; margin-top: 40px; font-family: var(--font-heading); }
.demo__stats dt { font-size: 12px; letter-spacing: .12em; color: rgba(242, 242, 243, .55); }
.demo__stats dd { margin: 0; font-size: 30px; font-weight: 600; line-height: 1.1; }

.form-card {
  position: relative;
  border: 1px solid var(--hud-dim);
  padding: 36px;
  background: rgba(29, 45, 61, .6);
  backdrop-filter: blur(6px);
}
.form-card__head {
  display: flex; justify-content: space-between;
  font-family: var(--font-heading);
  font-size: 12px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--hud);
  border-bottom: 1px solid rgba(148, 188, 227, .25);
  padding-bottom: 12px;
}
.form { display: flex; flex-direction: column; gap: 18px; margin-top: 24px; }
.field > span, .field-group > span {
  display: block;
  font-size: 12px; letter-spacing: .06em;
  color: rgba(242, 242, 243, .7);
  margin-bottom: 6px;
}
.input {
  width: 100%; min-height: 44px;
  padding: 8px 14px;
  font: inherit; font-size: 16px;
  color: var(--ink-text);
  background: rgba(242, 242, 243, .06);
  border: 1px solid var(--hud-dim);
  outline: none;
  border-radius: 0;
}
.input::placeholder { color: rgba(242, 242, 243, .4); }
.input:focus { border-color: var(--hud); box-shadow: 0 0 0 2px rgba(148, 188, 227, .25); }
.input--ltr { direction: ltr; text-align: right; }
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  padding: 9px 14px;
  border: 1px solid var(--hud-dim);
  background: transparent;
  color: var(--ink-text);
  font: inherit; font-size: 14px;
  cursor: pointer;
  min-height: 44px;
  transition: all .2s;
}
.chip:hover { border-color: var(--hud); }
.chip[aria-pressed="true"] { background: rgba(89, 128, 166, .45); border-color: var(--hud); }
/* s. 30א consent. The box is 18px so the tick is legible, and the whole row is
   a label so the text is a hit target too — the box alone is under any sane
   minimum. align-items: flex-start keeps the box on the first line when the
   sentence wraps. */
.check {
  display: flex; align-items: flex-start; gap: 10px;
  font-size: 13px; line-height: 1.6;
  color: rgba(242, 242, 243, .8);
  cursor: pointer;
}
.check input {
  width: 18px; height: 18px;
  margin: 2px 0 0;
  flex: none;
  accent-color: var(--color-accent);
  cursor: pointer;
}

.form__err {
  font-size: 13px;
  color: var(--color-accent-200);
  border-inline-start: 2px solid var(--hud);
  padding-inline-start: 10px;
}
.form__note { font-size: 12px; color: rgba(242, 242, 243, .58); line-height: 1.5; }

.sent {
  display: flex; flex-direction: column; align-items: center;
  text-align: center; padding: 24px 0; gap: 18px;
}
.sent__mark { position: relative; width: 72px; height: 72px; display: grid; place-items: center; }
.sent__mark i { position: absolute; inset: 0; border: 1px solid var(--hud); animation: smRing 1.8s ease-out infinite; }
.sent__mark i:nth-child(2) { animation-delay: .6s; }
.sent__kicker {
  font-family: var(--font-heading);
  font-size: 13px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--hud);
}
.sent h3 { font-size: 34px; line-height: 1.1; }
.sent p { font-size: 16px; line-height: 1.6; color: rgba(242, 242, 243, .75); max-width: 34ch; }
.btn--quiet {
  background: transparent;
  border: 1px solid rgba(242, 242, 243, .25);
  color: var(--ink-text);
  padding: 10px 18px;
  font: inherit; font-size: 14px;
  min-height: 44px;
  cursor: pointer;
}
.btn--quiet:hover { background: rgba(242, 242, 243, .08); }

.site-footer { margin-top: 24px; padding-top: 0; border-top: 0; }

.site-footer {
  position: relative;
  max-width: var(--max);
  margin: 120px auto 0;
  padding-top: 28px;
  border-top: 1px solid rgba(148, 188, 227, .2);
  display: flex; justify-content: space-between; align-items: center;
  gap: 16px; flex-wrap: wrap;
  font-size: 13px; color: rgba(242, 242, 243, .55);
}
.site-footer .mono { font-family: var(--font-heading); letter-spacing: .1em; text-transform: uppercase; }
.site-footer .sig { font-family: "Barlow Condensed", sans-serif; letter-spacing: .14em; color: var(--hud); direction: ltr; }
/* The accessibility statement link. --hud rather than the strip's own .55
   white: 7.06 against the ink instead of 4.90, and underlined so it does not
   rely on colour alone to read as a link (1.4.1). */
.site-footer a { color: var(--hud); text-decoration: underline; text-underline-offset: 3px; }
.site-footer a:hover { color: var(--ink-text); }

/* ----------------------------------------------------------- cookie consent */

/* «Cookie Consent.dc.html», the live-site variant: a strip along the bottom of
   the screen, not a dialog — no scrim, no scroll lock, no focus trap. The design
   draws it in the rebuild's colours and asks for this site's own ghost button, so
   the ground, the rule and the link take this site's tokens: the label is 12.8
   and the link 6.48 against the ink. */
.consent {
  position: fixed; inset-inline: 0; bottom: 0; z-index: 60;
  display: flex; align-items: center; justify-content: space-between; gap: 40px;
  min-height: 96px;
  padding: 22px 64px;
  background: var(--ink);
  border-top: 1px solid color-mix(in srgb, var(--hud) 35%, transparent);
  color: var(--ink-text);
}
.consent[hidden] { display: none; }
/* Focus lands on the strip itself when it is reopened from the footer; inset,
   so the ring is not cut off by the bottom of the viewport. */
.consent:focus-visible { outline-offset: -4px; }
.consent__body { max-width: 820px; }
.consent__text { margin: 0; font-size: 16px; line-height: 1.6; }
/* The service's name holds one line; at 390 it broke between its two words. */
.consent__brand { white-space: nowrap; }
.consent__current { margin: 4px 0 0; font-size: 14px; font-weight: 500; line-height: 1.6; color: rgba(242, 242, 243, .75); }
.consent__actions { display: flex; gap: 12px; flex: none; }
/* «אשר» and «דחה» are one component at one size, so neither reads as the
   default; the filled button stays the demo's alone. */
.consent__btn { min-height: 48px; min-width: 120px; padding: 0 28px; justify-content: center; font-size: 17px; }

/* While the strip is open nothing may stay under it: the page gains its height
   at the bottom, and the HUD's lower corners and status line ride up with it —
   the design's rule for every fixed element on the bottom edge. */
.consent-open body { padding-bottom: var(--consent-h, 0px); }
.hud__corner--br, .hud__corner--bl { bottom: calc(18px + var(--consent-h, 0px)); }
.hud__status { bottom: calc(24px + var(--consent-h, 0px)); }

/* A button, not a link — it reopens the strip rather than going anywhere — set
   in the footer links' own style. */
.site-footer__consent {
  padding: 0; border: 0; background: none;
  font: inherit; color: var(--hud);
  text-decoration: underline; text-underline-offset: 3px;
  cursor: pointer;
}
.site-footer__consent:hover { color: var(--ink-text); }

@media (max-width: 860px) {
  .consent {
    flex-direction: column; align-items: stretch; gap: 14px;
    min-height: 0;
    padding: 18px 20px calc(16px + env(safe-area-inset-bottom, 0px));
  }
  .consent__text { font-size: 15px; }
  .consent__actions { display: grid; grid-template-columns: 1fr 1fr; }
  .consent__btn { min-width: 0; }
}

@media print { .consent { display: none; } }

/* ============================================================== responsive */

@media (max-width: 1080px) {
  .hero__inner,
  .system__head,
  .screens,
  .faq,
  .demo__inner { grid-template-columns: 1fr; }
  .hero__inner { gap: 56px; }
  /* Stacked, the video's tagline ends the hero at full width, and its last
     line reached the centred «גלול» hint (66px tall, 28px off the bottom). */
  .hero { padding-bottom: 120px; }
  .faq, .screens { gap: 40px; }
  /* The design sets one fixed height across the two-up screenshot row.
     Once the row stacks, that height would have to be shared by both
     frames — so release it and let each frame keep its own aspect.
     The height goes on the slot, in viewport units, rather than coming from
     `aspect-ratio` on the figure with a `flex: 1` child stretching to fill it.
     WebKit does not resolve that pair: the figure got no height at all, the
     black slot collapsed with it, and both frames rendered as bare hairlines
     with their corner marks stacked on one line — an iPhone showed an empty
     band where the screenshots belong while Chromium was fine at every width.
     Written this way nothing depends on the ratio box or on the flex fill.
     .625 is the 16/10 the design uses; the column is the section's own
     content width, hence the gutter on both sides. */
  .screens { height: auto; }
  .screens figure { display: block; }
  .screens .slot { height: calc((100vw - var(--gutter) * 2) * .625); }
  .demo__inner { gap: 48px; }
  .cards-3 { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 860px) {
  .section { padding: 96px var(--gutter); }
  .nav { gap: 16px; padding: 14px var(--gutter); }
  .nav__link { display: none; }
  .nav__brand span { font-size: 15px; }
  /* The HUD is drawn for the design's fixed canvas, where the corner marks sit
     in the margins and the status line runs along the bottom gutter. Below this
     breakpoint there are no margins to sit in: the top-left mark crosses the
     nav's CTA — 12×22px of it at 390px — and the status line lands on whatever
     is scrolled under it, the hero's figures, a product row, the form's chips.
     Both are decoration, and nothing leaves the accessibility tree with them:
     the status line is a clock, not a live region, and the pause control is
     in flow in the scan panel. .hud__progress stays; it rides the
     very top edge and touches nothing. */
  .hud__corner, .hud__status { display: none; }
  .cards-3, .steps { grid-template-columns: 1fr; }
  .steps__line { display: none; }
  .step p { max-width: none; }
  .ghost-number { font-size: clamp(160px, 46vw, 300px); opacity: .7; }

  /* The five-column table cannot hold its shape here, so each row becomes a
     small labelled card: product name, then the figures side by side with
     their column name above, then the status. */
  .tbl__head { display: none; }
  .tbl__row {
    grid-template-columns: repeat(3, 1fr);
    gap: 12px;
    padding: 16px 18px;
  }
  .tbl__name { grid-column: 1 / -1; font-size: 16px; }
  .tbl__barcode { direction: rtl; text-align: right; font-size: 14px; }
  .tbl__num { font-size: 20px; }
  .tbl__row > .tbl__barcode, .tbl__row > .tbl__num {
    display: flex; flex-direction: column; gap: 3px;
  }
  .tbl__row > .tbl__barcode::before, .tbl__row > .tbl__num::before {
    content: attr(data-label);
    font-family: var(--font-heading);
    font-size: 11px; font-weight: 400; letter-spacing: .1em;
    color: rgba(242, 242, 243, .45);
  }
  .tbl__status { grid-column: 1 / -1; }

  .plate { padding: clamp(40px, 8vw, 64px) 24px; }
  .form-card { padding: 24px; }
  .site-footer { margin-top: 72px; }
}

@media (max-width: 640px) {
  /* Four store tabs will not fit on one line — lay them out 2×2 instead of
     letting the strip overflow the viewport. */
  .tabs { display: grid; grid-template-columns: 1fr 1fr; width: 100%; margin-top: 24px; }
  .tab { text-align: center; }
  .tab + .tab { border-inline-start: 0; }
  .tab:nth-child(even) { border-inline-start: 1px solid var(--hud-dim); }
  .tab:nth-child(n+3) { border-top: 1px solid var(--hud-dim); }
}

@media (max-width: 520px) {
  /* The wordmark plus the CTA no longer fit on one line — the SM monogram
     carries the brand on its own here. */
  .nav__brand span { display: none; }
  .nav__brand img { height: 26px; }
  .readout { padding: 20px; }
  .hero-vid__play { width: 64px; height: 64px; }
  .hero-vid__play svg { width: 26px; height: 26px; }
  /* The stat numerals are the widest unbreakable run in the hero. Held at a
     fixed size they set the readout's min-content — and with it the whole
     hero grid track — wider than a 320px viewport, which pushes the column
     off the left edge in RTL. Scale them with the viewport instead, and let
     a value wrap rather than clip if a future one is longer still.

     `break-word` and not `anywhere`: both break a word that would otherwise
     overflow, but `anywhere` also counts the break when the browser computes
     min-content, so the grid track collapsed below the width of the longest
     word and then split it — "אוטומטית" rendered as "אוטומטי" over "ת" at every
     width up to 390px. The clamp is what keeps the track narrow enough; the
     wrap mode only has to catch a value that genuinely cannot fit. Measured
     at 320, 360, 390, 430 and 520: the word holds one line at all of them and
     nothing overflows the viewport. */
  .readout__value { font-size: clamp(26px, 8vw, 34px); overflow-wrap: break-word; }
  .bar__label { width: 66px; }
  .demo__stats { flex-direction: column; gap: 18px; }
  .hero__actions .btn { width: 100%; justify-content: center; }
}

/* Owner, 24.10 (docs/blog/PRODUCT-CLAIMS.md): a capability still in development
   keeps its place on the page and says so beside its name. The kicker's face,
   in currentColor, so one chip reads on the paper sections and on the ink ones. */
.dev-tag {
  display: inline-block; vertical-align: middle; margin-inline-start: .45em;
  padding: .4em .75em; border: 1px solid currentColor; border-radius: 999px;
  font-family: var(--font-heading); font-size: 13px; font-weight: 500; line-height: 1;
  letter-spacing: .06em; white-space: nowrap;
}
