/* ============================================================
   DALLAS ROBOTER — WEBSITE8
   Direction: Blueprint Noir · technical editorial
   Type: Inter — single family (matches WEBSITE7)
   Accent: electric amber on deep ink + warm paper
   ============================================================ */

:root{
  --ink:#08090c;
  --ink-2:#0f1116;
  --ink-3:#171a21;
  --paper:#fbfaf7;
  --cream:#f2efe8;
  --cream-2:#e9e5db;

  --orange:#ff6a00;
  --orange-2:#ffa14d;
  --orange-soft:rgba(255,106,0,.10);
  --orange-line:rgba(255,106,0,.35);

  --line:rgba(8,9,12,.10);
  --line-strong:rgba(8,9,12,.18);
  --line-dark:rgba(255,255,255,.12);
  --line-dark-strong:rgba(255,255,255,.22);

  --text:#0c0d10;
  --text-dim:#4c4f57;
  --text-muted:rgba(8,9,12,.42);
  --text-invert:#f6f5f2;
  --text-invert-dim:rgba(246,245,242,.62);
  --text-invert-muted:rgba(246,245,242,.38);

  --radius:16px;
  --radius-sm:10px;
  --radius-lg:26px;
  --shadow:0 18px 50px -24px rgba(8,9,12,.28);
  --shadow-lg:0 40px 90px -40px rgba(8,9,12,.45);

  --font-display:'Inter',system-ui,-apple-system,sans-serif;
  --font-body:'Inter',system-ui,-apple-system,sans-serif;
  --font-serif:'Inter',system-ui,-apple-system,sans-serif;
  --font-mono:'Inter',system-ui,-apple-system,sans-serif;

  --ease:cubic-bezier(.22,.61,.36,1);
  --ease-out:cubic-bezier(.16,1,.3,1);
}

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{font-size:16px;scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{
  font-family:var(--font-body);
  background:var(--paper);
  color:var(--text);
  line-height:1.62;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  padding-top:72px;
  overflow-x:hidden;
}
img{max-width:100%;height:auto;display:block}
a{color:inherit;text-decoration:none;transition:color .2s var(--ease)}
a:hover{color:var(--orange)}
a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{outline:2px solid var(--orange);outline-offset:3px;border-radius:4px}
strong{font-weight:600}
button{cursor:pointer;font-family:inherit}
::selection{background:var(--orange);color:#fff}

/* ---------- ambient overlays (injected by JS) ---------- */
.grain{
  position:fixed;inset:0;z-index:9998;pointer-events:none;opacity:.5;mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.055'/%3E%3C/svg%3E");
}
.scroll-progress{
  position:fixed;top:0;left:0;height:2px;width:0;z-index:9999;
  background:linear-gradient(90deg,var(--orange),var(--orange-2));
  box-shadow:0 0 14px rgba(255,106,0,.7);
  transition:width .08s linear;
}

/* ---------- layout ---------- */
.w{max-width:1200px;margin:0 auto;padding:0 1.75rem}
.w-narrow{max-width:820px;margin:0 auto;padding:0 1.75rem}
.s{padding:6.5rem 0;position:relative}
.s-cream{background:var(--cream)}
.s-ink{background:var(--ink);color:var(--text-invert)}
.s-ink h2,.s-ink h3,.s-ink h4,.s-ink p,.s-ink li,.s-ink .kicker{color:var(--text-invert)}
.s-ink p,.s-ink li{color:var(--text-invert-dim)}
.s-ink .kicker{color:var(--orange-2)}
.s-ink{background-image:
  radial-gradient(900px 380px at 12% 0%,rgba(255,106,0,.10),transparent 60%),
  linear-gradient(180deg,#0a0b0f,#08090c)}
.s-ink .card,.s-ink .pillar,.s-ink .pipe-step{border-color:var(--line-dark)}

/* blueprint grid texture */
.s-ink::before{content:'';position:absolute;inset:0;pointer-events:none;opacity:.5;background-image:linear-gradient(var(--line-dark) 1px,transparent 1px),linear-gradient(90deg,var(--line-dark) 1px,transparent 1px);background-size:64px 64px;mask-image:radial-gradient(circle at 50% 40%,#000 0%,transparent 78%);-webkit-mask-image:radial-gradient(circle at 50% 40%,#000 0%,transparent 78%)}
.s-ink>.w{position:relative;z-index:1}
.grid-tex::before{
  content:'';position:absolute;inset:0;pointer-events:none;opacity:.5;
  background-image:linear-gradient(var(--line) 1px,transparent 1px),linear-gradient(90deg,var(--line) 1px,transparent 1px);
  background-size:64px 64px;
  mask-image:radial-gradient(circle at 50% 40%,#000 0%,transparent 78%);
  -webkit-mask-image:radial-gradient(circle at 50% 40%,#000 0%,transparent 78%);
}
.s-ink.grid-tex::before{
  background-image:linear-gradient(var(--line-dark) 1px,transparent 1px),linear-gradient(90deg,var(--line-dark) 1px,transparent 1px);
  opacity:.6;
}

/* ---------- type ---------- */
.kicker{
  font-family:var(--font-mono);font-size:.6875rem;letter-spacing:.18em;text-transform:uppercase;
  font-weight:600;color:var(--orange);margin-bottom:.85rem;display:inline-flex;align-items:center;gap:.55rem;
}
.kicker::before{content:'';width:22px;height:1px;background:currentColor;opacity:.6}
.h2{
  font-family:var(--font-display);font-size:clamp(2rem,4.4vw,3.35rem);font-weight:600;
  line-height:1.06;letter-spacing:-.035em;margin-bottom:1.15rem;
}
.h2 em,h1 em,h2 em{
  font-family:var(--font-serif);font-style:italic;font-weight:500;letter-spacing:-.015em;
  background:linear-gradient(100deg,var(--orange),var(--orange-2));
  -webkit-background-clip:text;background-clip:text;color:transparent;
  padding-right:.06em;
}
.sec-header{margin-bottom:3.25rem;max-width:760px}
.sec-header p{font-size:1.0625rem;color:var(--text-dim);line-height:1.75}
/* Standard designations break at their hyphen - "EN 3691-" then "4" - which
   reads as a different code. nowrap keeps a designation whole and lets the
   break fall at the space before it, where it belongs. */
.nw{white-space:nowrap}

/* ---------- nav ---------- */
.nav{
  position:fixed;top:0;left:0;right:0;height:72px;z-index:1000;
  display:flex;align-items:center;
  background:rgba(251,250,247,.72);
  border-bottom:1px solid transparent;
  backdrop-filter:blur(18px) saturate(160%);
  -webkit-backdrop-filter:blur(18px) saturate(160%);
  transition:height .3s var(--ease),background .3s var(--ease),border-color .3s var(--ease),box-shadow .3s var(--ease);
}
.nav.scrolled{height:60px;background:rgba(251,250,247,.9);border-bottom-color:var(--line);box-shadow:0 10px 30px -22px rgba(8,9,12,.5)}
.nav-inner{width:100%;max-width:1200px;margin:0 auto;padding:0 1.75rem;display:flex;align-items:center;justify-content:space-between;gap:1rem}
.nav-brand{display:flex;align-items:center;gap:.65rem;font-family:var(--font-display);font-weight:600;font-size:1rem;letter-spacing:-.02em;white-space:nowrap}
.nav-brand img{height:30px;width:auto;transition:transform .4s var(--ease)}
.nav-brand:hover img{transform:rotate(-6deg) scale(1.06)}
.nav-links{display:flex;align-items:center;gap:1.75rem;list-style:none}
.nav-links a{font-size:.8125rem;font-weight:500;color:var(--text-dim);position:relative;padding:.25rem 0}
.nav-links a::after{content:'';position:absolute;left:0;bottom:-2px;width:0;height:1.5px;background:var(--orange);transition:width .28s var(--ease)}
.nav-links a:hover{color:var(--text)}
.nav-links a:hover::after{width:100%}
.nav-links a.active{color:var(--text);font-weight:600}
.nav-links a.active::after{width:100%}
.nav-right{display:flex;align-items:center;gap:1rem}
.nav-cta{
  position:relative;overflow:hidden;background:var(--ink);color:var(--paper)!important;
  padding:.55rem 1.15rem;font-size:.8125rem;font-weight:600;border-radius:999px;
  transition:transform .2s var(--ease),background .2s var(--ease);
}
.nav-cta::after{content:'';position:absolute;inset:0;background:linear-gradient(100deg,var(--orange),var(--orange-2));opacity:0;transition:opacity .25s var(--ease);z-index:-1}
.nav-cta:hover{background:var(--orange)!important;color:#fff!important;transform:translateY(-1px)}

/* hamburger */
.nav-toggle{display:none;flex-direction:column;justify-content:center;width:40px;height:40px;background:none;border:none;padding:8px;gap:5px;z-index:1001}
.nav-toggle span{display:block;height:2px;background:var(--text);border-radius:2px;transition:transform .3s var(--ease),opacity .3s var(--ease)}
.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)}
/* Seven links plus the Request a Demo pill need roughly 880 px. Below 960 the
   bar wraps: the brand collided with "Applications", "Code-Less" broke over
   two lines and the pill wrapped inside itself. The overlay therefore takes
   over at 960, well before the 768 layout breakpoint. It has to be declared
   after the base rule above - same specificity, and the later rule wins. */
@media(max-width:959px){
  .nav-toggle{display:flex}
  .nav-links,.nav-right{display:none}
}

.mobile-overlay{
  display:flex;position:fixed;inset:0;z-index:999;flex-direction:column;align-items:center;justify-content:center;gap:2rem;
  background:rgba(8,9,12,.97);backdrop-filter:blur(10px);
  opacity:0;visibility:hidden;transition:opacity .35s var(--ease),visibility .35s var(--ease);
}
body.nav-open .mobile-overlay{opacity:1;visibility:visible}
body.nav-open{overflow:hidden}
.mobile-overlay a{font-family:var(--font-display);font-size:1.5rem;color:var(--paper)!important;font-weight:500;letter-spacing:-.02em;transform:translateY(12px);opacity:0;transition:transform .4s var(--ease),opacity .4s var(--ease)}
body.nav-open .mobile-overlay a{transform:translateY(0);opacity:1}
.mobile-overlay a:hover{color:var(--orange)!important}
.mobile-overlay .nav-cta-mobile{display:inline-block;background:var(--orange);color:#fff!important;padding:.8rem 2.4rem;border-radius:999px;font-weight:600;margin-top:.5rem;font-size:1.0625rem}

/* ---------- buttons ---------- */
.btn{
  position:relative;display:inline-flex;align-items:center;gap:.55rem;justify-content:center;
  padding:.85rem 1.65rem;font-size:.875rem;font-weight:600;font-family:var(--font-body);
  border-radius:999px;overflow:hidden;isolation:isolate;
  transition:transform .25s var(--ease),box-shadow .25s var(--ease),background .25s var(--ease),color .25s var(--ease),border-color .25s var(--ease);
}
.btn::after{content:'';position:absolute;inset:0;z-index:-1;background:linear-gradient(100deg,var(--orange),var(--orange-2));opacity:0;transition:opacity .3s var(--ease)}
.btn-primary{background:var(--ink);color:var(--paper);box-shadow:0 12px 26px -14px rgba(8,9,12,.7)}
.btn-primary:hover{color:#fff;transform:translateY(-2px);box-shadow:0 20px 36px -16px rgba(255,106,0,.7)}
.btn-primary:hover::after{opacity:1}
.btn-outline{background:transparent;color:var(--text);border:1px solid var(--line-strong)}
.btn-outline:hover{color:#fff;border-color:transparent;transform:translateY(-2px)}
.btn-outline:hover::after{opacity:1}
.s-ink .btn-outline{color:var(--text-invert);border-color:var(--line-dark-strong)}
.s-ink .btn-outline:hover{color:#fff}
.btn .arrow{transition:transform .25s var(--ease)}
.btn:hover .arrow{transform:translateX(4px)}

/* ---------- hero ---------- */
.hero-center{
  position:relative;min-height:min(88vh,860px);display:flex;align-items:center;text-align:center;
  padding:5rem 0 4rem;overflow:hidden;isolation:isolate;
}
.hero-center::before{
  content:'';position:absolute;inset:-30%;z-index:-2;
  background:
    radial-gradient(600px 420px at 22% 18%,rgba(255,106,0,.16),transparent 62%),
    radial-gradient(720px 520px at 82% 78%,rgba(120,90,255,.10),transparent 64%),
    radial-gradient(500px 400px at 60% 10%,rgba(255,161,77,.10),transparent 60%);
  animation:aurora 18s ease-in-out infinite alternate;
}
.hero-center::after{
  content:'';position:absolute;z-index:-1;top:50%;left:50%;width:min(78vw,880px);aspect-ratio:1;
  transform:translate(-50%,-50%);
  border-radius:50%;
  background:conic-gradient(from 0deg,transparent 0deg,rgba(255,106,0,.22) 40deg,transparent 120deg,transparent 200deg,rgba(255,106,0,.14) 250deg,transparent 320deg);
  mask-image:radial-gradient(circle,transparent 52%,#000 53%,#000 63%,transparent 64%);
  -webkit-mask-image:radial-gradient(circle,transparent 52%,#000 53%,#000 63%,transparent 64%);
  animation:spin 34s linear infinite;
  opacity:.9;
}
@keyframes aurora{
  0%{transform:translate3d(-2%,-1%,0) scale(1)}
  100%{transform:translate3d(3%,2%,0) scale(1.08)}
}
@keyframes spin{to{transform:translate(-50%,-50%) rotate(360deg)}}
.hero-center .w{position:relative;z-index:2}
.hero-center .kicker{margin-bottom:1.5rem;justify-content:center}
.hero-center .kicker::before{display:none}
.hero-center h1{
  font-family:var(--font-display);font-size:clamp(2.9rem,8.2vw,6.4rem);font-weight:600;
  line-height:.98;letter-spacing:-.045em;margin-bottom:1.5rem;
}
.hero-center p{max-width:620px;margin:0 auto 2.5rem;font-size:1.125rem;color:var(--text-dim);line-height:1.7}
.hero-center .hero-meta{display:flex;flex-wrap:wrap;gap:.5rem 1.5rem;justify-content:center;font-family:var(--font-mono);font-size:.6875rem;letter-spacing:.06em;text-transform:uppercase;color:var(--text-muted)}
.hero-center .hero-meta span{display:flex;align-items:center;gap:.5rem}
.hero-center .hero-meta span::before{content:'';width:5px;height:5px;border-radius:50%;background:var(--orange)}
.hero-actions{display:flex;gap:.85rem;flex-wrap:wrap;justify-content:center}

/* ---------- hero background video ----------
   The clip is a floor demo, so the hero becomes the dark surface the rest of
   the site already uses for sub-page heroes: footage underneath, ink scrim
   over it, light type on top. The scrim is a two-axis gradient rather than a
   flat wash so the machines stay visible where the type is not.

   The <video> has no src until main.js gives it one. On a phone, on save-data,
   and for reduced-motion visitors the poster alone is shown: this hero is the
   LCP element and a 1.7 MB clip is not worth spending to move a background. */
.hero-video{color:var(--text-invert)}
.hero-video::before,.hero-video::after{display:none}
.hero-media{position:absolute;inset:0;z-index:-2;overflow:hidden;background:var(--ink)}
.hero-media-el{width:100%;height:100%;object-fit:cover;object-position:50% 80%;display:block}
.hero-media::after{
  content:'';position:absolute;inset:0;pointer-events:none;
  /* Two layers: a soft pool of ink behind the type column, and a top-to-bottom
     wash that keeps the nav and the ticker edge from fighting the footage.
     Measured against the brightest area of the clip (the window at ~0.21
     relative luminance) the pool keeps body copy above 4.5:1 at 62% white. */
  background:
    radial-gradient(980px 680px at 50% 46%,rgba(8,9,12,.55) 0%,rgba(8,9,12,.40) 60%,rgba(8,9,12,.14) 100%),
    radial-gradient(120% 120% at 50% 50%,rgba(8,9,12,0) 42%,rgba(8,9,12,.42) 100%),
    linear-gradient(180deg,rgba(8,9,12,.30) 0%,rgba(8,9,12,.14) 30%,rgba(8,9,12,.20) 64%,rgba(8,9,12,.62) 82%,rgba(8,9,12,.86) 100%);
}
.hero-video .kicker{color:var(--orange-2)}
.hero-video h1{color:var(--text-invert)}
.hero-video p{color:rgba(246,245,242,.86)}
.hero-video .hero-meta{color:rgba(246,245,242,.62)}
.hero-video .btn-outline{color:var(--text-invert);border-color:var(--line-dark-strong)}
.hero-video .btn-outline:hover{color:#fff}
/* The Code-Less link rides in the meta row rather than under it: the master's
   burned-in captions occupy the bottom 18% of the frame, and a second line of
   small print was landing right on top of them. */
.hero-meta-link{display:flex;align-items:center;gap:.5rem;color:var(--orange-2);font-weight:600}
.hero-meta-link::before{content:'';width:5px;height:5px;border-radius:50%;background:var(--orange)}
.hero-meta-link:hover{color:var(--orange)}
.hero-video .hero-meta .hero-meta-link{color:var(--orange-2)}
/* The master carries its own burned-in captions across the bottom ~15% of the
   frame, left-aligned. They are part of the video the client asked to keep, so
   the hero copy yields instead. The hero is a fixed height and the inner block
   carries bottom padding: because the block is centred, that padding lifts the
   text without growing the hero, which is what a plain padding-bottom on the
   section did — it only made the video taller and left the captions where they
   were. */
@media(min-width:769px){
  .hero-video .w{padding-bottom:7rem}
}
/* Past ~2160px the hero is far shorter than the 16:9 frame, and the burned-in
   caption can no longer fit both under the copy and inside the hero — the
   arithmetic has no solution at any vertical anchor. Rather than show half a
   sentence, anchor the frame to its top and crop the subtitle band away. The
   threshold is a width, not a viewport aspect, because the hero height is
   capped at 860px: 860*2.5 is where the hero itself becomes wider than 5:2. */
@media(min-width:2160px){
  .hero-media-el{object-position:50% 0}
}
/* WCAG 2.2.2: motion that starts on its own and runs longer than five seconds
   needs a way to stop it. Small, quiet, and only rendered when a clip is
   actually playing. */
.hero-media-toggle{
  position:absolute;left:1.25rem;bottom:1.25rem;z-index:3;
  width:38px;height:38px;display:grid;place-items:center;border-radius:50%;
  background:rgba(246,245,242,.14);border:1px solid rgba(246,245,242,.42);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  transition:background .2s var(--ease),border-color .2s var(--ease);
}
.hero-media-toggle:hover{background:rgba(246,245,242,.26);border-color:rgba(246,245,242,.7)}
/* `display:grid` above outranks the UA rule for [hidden], so the attribute
   alone would leave the control on screen in every state that skips video. */
.hero-media-toggle[hidden]{display:none}
.hero-media-toggle-icon{width:10px;height:12px;border-left:3px solid var(--text-invert);border-right:3px solid var(--text-invert)}
.hero-media-toggle[aria-pressed="true"] .hero-media-toggle-icon{width:0;height:0;border-left:11px solid var(--text-invert);border-right:0;border-top:7px solid transparent;border-bottom:7px solid transparent}

/* ---------- ticker ---------- */
.ticker{overflow:hidden;background:var(--ink);color:var(--text-invert);padding:.8rem 0;position:relative;z-index:2}
.ticker-inner{display:flex;gap:3rem;width:max-content;animation:ticker 38s linear infinite;white-space:nowrap;font-family:var(--font-mono);font-size:.6875rem;letter-spacing:.1em;text-transform:uppercase;color:var(--text-invert-dim)}
.ticker:hover .ticker-inner{animation-play-state:paused}
.ticker-inner span{display:flex;align-items:center;gap:.6rem}
.ticker-inner .dot{width:6px;height:6px;background:var(--orange);border-radius:50%;flex-shrink:0;box-shadow:0 0 10px var(--orange)}
@keyframes ticker{0%{transform:translateX(0)}100%{transform:translateX(-50%)}}

/* ---------- stats ---------- */
.stats-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line);border:1px solid var(--line);border-radius:var(--radius-lg);overflow:hidden}
.stat-card{position:relative;background:var(--paper);padding:2.25rem 1.75rem;transition:background .3s var(--ease)}
.s-cream .stat-card{background:var(--cream)}
.s-ink .stats-grid{background:var(--line-dark);border-color:var(--line-dark)}
.s-ink .stat-card{background:var(--ink-2)}
.stat-card::before{content:'';position:absolute;inset:0;background:radial-gradient(260px circle at var(--mx,50%) var(--my,50%),var(--orange-soft),transparent 62%);opacity:0;transition:opacity .35s var(--ease);pointer-events:none}
.stat-card:hover::before{opacity:1}
.stat-card:hover{background:var(--paper)}
.stat-card .stat-val{font-family:var(--font-display);font-size:clamp(2.4rem,4vw,3.1rem);font-weight:600;line-height:1;letter-spacing:-.04em;margin-bottom:.6rem;font-variant-numeric:tabular-nums}
.stat-card .stat-val .unit{font-family:var(--font-mono);font-size:.8125rem;font-weight:400;color:var(--orange);letter-spacing:.02em;margin-left:.15em}
.stat-card .stat-lbl{font-family:var(--font-mono);font-size:.625rem;text-transform:uppercase;letter-spacing:.14em;color:var(--text-muted);font-weight:600}
.s-ink .stat-card .stat-lbl{color:var(--text-invert-muted)}
.stat-card p{font-size:.8125rem;color:var(--text-dim);margin-top:.85rem;line-height:1.55}
.s-ink .stat-card p{color:var(--text-invert-dim)}

/* ---------- feature split ---------- */
.fsplit{display:grid;grid-template-columns:1fr 1fr;gap:clamp(2.5rem,6vw,5.5rem);align-items:center}
.fsplit-text h2{font-family:var(--font-display);font-size:clamp(1.55rem,3vw,2.3rem);font-weight:600;line-height:1.12;letter-spacing:-.03em;margin-bottom:1.1rem}
.fsplit-text p{font-size:1rem;color:var(--text-dim);line-height:1.75;margin-bottom:.85rem}
.s-ink .fsplit-text p{color:var(--text-invert-dim)}
.fsplit-text ul{list-style:none;margin-top:1.25rem;display:grid;gap:.55rem}
.fsplit-text ul li{position:relative;padding-left:1.6rem;font-size:.9375rem;color:var(--text-dim);line-height:1.6}
.s-ink .fsplit-text ul li{color:var(--text-invert-dim)}
.fsplit-text ul li::before{content:'';position:absolute;left:0;top:.62em;width:9px;height:9px;border:1.5px solid var(--orange);border-radius:50%}
.fsplit-text ul li span{color:var(--orange);font-weight:600;margin-right:.25rem}
.fsplit-img{position:relative}
.fsplit-img::before{content:'';position:absolute;inset:-6% -4% -8% 4%;background:radial-gradient(circle at 60% 40%,rgba(255,106,0,.16),transparent 62%);z-index:-1;filter:blur(6px)}
.fsplit-img img{width:100%;border-radius:var(--radius);border:1px solid var(--line);box-shadow:var(--shadow-lg)}
/* Application stills: two source shapes, so two treatments. The wide scenes are
   4:3 and fill the column. The tote and pallet scenes were shot 9:16, and at
   full column width they would run about a thousand pixels tall and dwarf the
   copy beside them, so they cap by height and centre. Capping by height rather
   than cropping keeps the mast and the full machine in frame. */
/* The glow keeps its vertical bleed but loses the horizontal 4%: at 1024 the
   split collapses to one column, and a 4% bleed on each side is wider than the
   page gutter - it showed up as 11 px of horizontal scroll. */
.fsplit-img--app::before{inset:-6% 0 -8% 0}
.fsplit-img--app img{display:block}
.fsplit-img--app.is-portrait img{width:auto;max-width:100%;max-height:min(600px,74vh);margin:0 auto}
/* A portrait has no natural bottom edge of its own, so the name sits directly
   under it rather than floating at the foot of the column. */
.fsplit-portrait img{margin:0 auto;display:block}
.fsplit-cap{font-family:var(--font-mono);font-size:.625rem;letter-spacing:.06em;
  text-transform:uppercase;color:var(--text-muted);padding:.85rem 0 0;text-align:center}
/* The structure row under the founder: same two-column rhythm, separated by a
   rule instead of a gap, because it is the argument's second half and not a
   new section. */
.fsplit-row2{margin-top:clamp(3rem,6vw,4.5rem);padding-top:clamp(2.5rem,5vw,3.5rem);
  border-top:1px solid var(--line);align-items:start}
/* The four sites: label left, place right, one row each. Reads as a list of
   facts, which is what it is - a paragraph of bolded labels made the reader
   parse a sentence to get an address.
   Reset from the generic `.fsplit-text ul`: that rule is a bulleted list, and
   its ring marker was landing in the gutter beside every row. */.loc-list{list-style:none;display:block;margin:0;padding:0;border-top:1px solid var(--line)}
.loc-list li{display:grid;grid-template-columns:minmax(6.5rem,auto) 1fr;gap:1.25rem;
  align-items:baseline;padding:.95rem 0;border-bottom:1px solid var(--line);
  padding-left:0;font-size:.9375rem}
.loc-list li::before{content:none;display:none}
.loc-list .loc-k{font-family:var(--font-mono);font-size:.625rem;letter-spacing:.11em;
  text-transform:uppercase;color:var(--text-muted);font-weight:600;white-space:nowrap}
.loc-list .loc-v{font-size:.9375rem;color:var(--text);line-height:1.45}
/* ---------- the X22 safety clip's feature list ----------
   The clip carries its own caption cards, burned into the footage. At 1144 px
   they read; at 350 px - a phone - the body text is roughly 8 px and does not.
   So the same seven behaviours are also set as text: readable at any width,
   selectable, translatable, and reachable by a screen reader, which a video
   frame is not. Two columns, because seven rows in one column is a scroll. */
.safety-feats{list-style:none;margin:clamp(2rem,4vw,2.75rem) 0 0;padding:0;
  display:grid;grid-template-columns:1fr 1fr;gap:0 2.5rem}
.safety-feats li{display:grid;gap:.3rem;padding:.95rem 0;border-top:1px solid var(--line)}
.safety-feats li::before{content:none}
.sf-k{font-family:var(--font-display);font-size:.9375rem;font-weight:600;
  letter-spacing:-.01em;color:var(--text)}
.sf-v{font-size:.875rem;line-height:1.55;color:var(--text-dim)}
@media(max-width:700px){.safety-feats{grid-template-columns:1fr;gap:0}}
/* ---------- the footprint photographs ----------
   One wide plate for the office (it is the address the US buyer cares about)
   and a pair under it. Captions sit outside the frame, not on it: the frames
   are hairlined like the rest of the site, and a scrim would fight the dusk
   shot's own light. */
.loc-hero{margin:0}
.loc-hero img,.loc-pair img{width:100%;display:block;border-radius:var(--radius);
  border:1px solid var(--line);box-shadow:var(--shadow-lg);background:transparent}
.loc-hero figcaption,.loc-pair figcaption{margin-top:1rem;font-size:.9375rem;
  line-height:1.6;color:var(--text-dim);max-width:62ch}
.loc-hero figcaption strong,.loc-pair figcaption strong{color:var(--text);font-weight:600}
.loc-pair{display:grid;grid-template-columns:1fr 1fr;gap:1.25rem;margin-top:2.5rem}
.loc-pair figure{margin:0}
@media(max-width:820px){
  .loc-pair{grid-template-columns:1fr;gap:2rem}
}
@media(max-width:900px){
  .fsplit-img--app.is-portrait img{max-height:none;width:100%}
}
/* Except the founder portrait. Full column width in single-column mode made it
   955 px tall at 820 - a face filling the screen between the copy and the next
   section. Capped, it stays a portrait.
   Specificity, not order: `.fsplit-img--app.is-portrait img` is two classes
   deep, so a bare `.fsplit-portrait img` lost to it however late it came.
   Matching that depth is what lets the cap apply. */
@media(max-width:900px){
  .fsplit-img.fsplit-portrait img{width:auto;max-width:min(100%,26rem)}
}
.s-ink .fsplit-img img{border-color:var(--line-dark)}
.fsplit-alt{direction:rtl}
.fsplit-alt .fsplit-text,.fsplit-alt .fsplit-img{direction:ltr}

/* ---------- cards ---------- */
.card-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1.25rem}
.card-grid.cols-2{grid-template-columns:repeat(2,1fr)}
.card{
  position:relative;overflow:hidden;border:1px solid var(--line);border-radius:var(--radius);
  padding:2rem;background:var(--paper);
  transition:transform .35s var(--ease),border-color .35s var(--ease),box-shadow .35s var(--ease);
}
.s-cream .card{background:var(--paper)}
.s-ink .card{background:var(--ink-2)}
.card::before{content:'';position:absolute;inset:0;background:radial-gradient(300px circle at var(--mx,50%) var(--my,50%),var(--orange-soft),transparent 60%);opacity:0;transition:opacity .35s var(--ease);pointer-events:none}
.card:hover{transform:translateY(-5px);border-color:var(--orange-line);box-shadow:var(--shadow)}
.card:hover::before{opacity:1}
.card h3{font-family:var(--font-display);font-size:1.1875rem;font-weight:600;letter-spacing:-.02em;margin-bottom:.6rem}
.card p{font-size:.875rem;color:var(--text-dim);line-height:1.68}
.s-ink .card p{color:var(--text-invert-dim)}
.card .metric{display:inline-block;margin-top:1rem;font-family:var(--font-mono);font-size:.625rem;text-transform:uppercase;letter-spacing:.12em;color:var(--orange);font-weight:600}
.card ul{list-style:none;margin-top:.85rem}
.card ul li{padding:.25rem 0;font-size:.8125rem;color:var(--text-dim)}
.card ul li span{color:var(--orange);margin-right:.35rem}

/* ---------- spec table ---------- */
.spec-table{width:100%;border-collapse:separate;border-spacing:0;font-size:.875rem;border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;background:var(--paper)}
.spec-table th{
  text-align:left;font-family:var(--font-mono);font-size:.625rem;text-transform:uppercase;letter-spacing:.12em;
  color:var(--text-muted);padding:1rem 1.1rem;background:var(--cream);border-bottom:1px solid var(--line);font-weight:600;white-space:nowrap;
}
.spec-table td{padding:.95rem 1.1rem;border-bottom:1px solid var(--line);color:var(--text-dim);white-space:nowrap}
.spec-table tr:last-child td{border-bottom:none}
.spec-table td:first-child{font-family:var(--font-display);font-weight:600;color:var(--text);letter-spacing:-.01em}
.spec-table tbody tr{transition:background .2s var(--ease)}
.spec-table tbody tr:hover{background:var(--orange-soft)}

/* ---------- image grid ---------- */
.img-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1.25rem}
.img-grid figure{position:relative;overflow:hidden;border:1px solid var(--line);border-radius:var(--radius);background:var(--paper)}
.img-grid img{width:100%;aspect-ratio:4/3;object-fit:cover;transition:transform .7s var(--ease)}
.img-grid figure:hover img{transform:scale(1.06)}
/* All eight renders share a 1200x900 canvas, but the platform art fills 77-84%
   of the frame width while the fork art fills only 37-57%. At one box width an
   S130 therefore reads about twice the size of an FX33. Scaling the four
   platform renders inside their frames evens out the visual weight without
   touching the files - a crop would shift the 8x8 block grid and destroy the
   L1 provenance payload. The hover zoom stays, offset by the same factor. */
.img-grid figure.is-platform img{transform:scale(.82)}
.img-grid figure.is-platform:hover img{transform:scale(.86)}
.img-grid figcaption{font-family:var(--font-mono);font-size:.625rem;letter-spacing:.04em;color:var(--text-dim);padding:.85rem 1rem 1.1rem;line-height:1.5}

/* ---------- 2x subject zoom ----------
   The application scenes are wide 16:9 renders where the robot is a small part
   of the frame. Scaling the image inside its existing frame doubles the
   subject without touching the file. That matters here: these JPEGs carry the
   L1 provenance watermark, and watermark.py is explicit that re-encoding a
   published file cannot be reversed - a crop shifts the 8x8 block grid and
   destroys the payload, and the pristine originals are not in the repo. So the
   zoom is presentational and the watermarked bytes stay exactly as published.

   `--zy` is the vertical anchor, chosen per scene. With scale(2) the visible
   source band is [zy/2, zy/2 + 50%]. The low AMR platforms sit in the bottom
   half of their frame, so they anchor at 100% and show exactly that half. The
   stackers are tall enough that no 2x window holds the whole machine - 30% of
   the frame is mast, 52% is machine - so 72% is the compromise: the base, forks
   and carriage stay in frame and the mast runs past the top edge, which reads
   as height rather than as a mistake. A gentler zoom (~1.75x) is the only way
   to keep the full mast, and it gives up half the size gain. */
.zoom-2x{transform:scale(2);transform-origin:50% var(--zy,100%)}
.app-card img.zoom-2x{transform:scale(2)}
.app-card:hover img.zoom-2x{transform:scale(2.1)}
/* The frame moves to the clipping wrapper when the image is scaled, otherwise
   a 1px border would render 2px thick and the drop shadow would scale with
   the picture. */
.fsplit-zoom{overflow:hidden;border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow-lg)}
.fsplit-zoom img{border:0;border-radius:0;box-shadow:none;transform:scale(2);transform-origin:50% var(--zy,100%)}
.s-ink .fsplit-zoom{border-color:var(--line-dark)}

/* ---------- the four criteria, in detail ----------
   Three photographs carry the argument: the form factors standing on one
   floor, a row of bodies ordered by placement height, and five process
   scenes. Text sits beside the first two and above the third, because the
   process strip is 3.8:1 and needs the full measure to stay legible. */
.crit-detail{display:grid;grid-template-columns:1fr 1fr;gap:clamp(2rem,5vw,4.25rem);align-items:center;padding:clamp(2.5rem,5vw,4rem) 0;border-top:1px solid var(--line)}
.crit-detail:first-of-type{border-top:none;padding-top:0}
.crit-detail-alt .crit-detail-figure{order:2}
.crit-detail-figure{margin:0}
.crit-detail-figure img{width:100%;height:auto;border-radius:var(--radius);border:1px solid var(--line);box-shadow:var(--shadow)}
.crit-detail-figure figcaption{margin-top:.85rem;font-family:var(--font-mono);font-size:.625rem;letter-spacing:.04em;line-height:1.6;color:var(--text-dim)}
.crit-detail-label{font-family:var(--font-mono);font-size:.5625rem;letter-spacing:.16em;text-transform:uppercase;color:var(--orange);font-weight:600;margin-bottom:.8rem}
.crit-detail-label span{color:var(--text-muted);margin:0 .4rem}
.crit-detail-text h3{font-family:var(--font-display);font-size:clamp(1.5rem,2.7vw,2.1rem);font-weight:600;line-height:1.1;letter-spacing:-.03em;margin-bottom:1rem}
.crit-detail-text p{font-size:.9375rem;color:var(--text-dim);line-height:1.75;margin-bottom:.9rem}
.crit-detail-text p:last-of-type{margin-bottom:0}
.crit-detail .ff-strip{grid-column:1/-1;margin-top:.5rem;padding-top:1.75rem;border-top:1px solid var(--line)}
.crit-detail-wide{display:block}
.crit-detail-wide .crit-detail-text{max-width:760px}
.crit-detail-wide .crit-detail-figure{margin-top:1.75rem}
/* On a phone the five-panel strip shrinks until its baked captions are
   illegible. Below 620px it keeps a readable width and scrolls sideways
   instead — the strip is five scenes, not a compression test. */
.crit-figure-scroll{display:block;border-radius:var(--radius)}
.crit-figure-scroll:focus-visible{outline:2px solid var(--orange);outline-offset:3px}
@media(max-width:620px){
  .crit-figure-scroll{overflow-x:auto;overscroll-behavior-x:contain;-webkit-overflow-scrolling:touch;padding-bottom:.35rem}
  .crit-figure-scroll img{min-width:760px;border-radius:0}
}
.proc-levels{display:grid;grid-template-columns:repeat(4,1fr);gap:1.25rem;margin-top:2rem}
.proc-level{border-top:2px solid var(--line-strong);padding-top:1rem;display:flex;flex-direction:column}
.proc-level:last-child{border-top-color:var(--orange)}
.proc-n{font-family:var(--font-mono);font-size:.5625rem;letter-spacing:.16em;color:var(--text-muted);font-weight:600}
.proc-level h4{font-family:var(--font-display);font-size:1rem;font-weight:600;letter-spacing:-.015em;margin:.5rem 0 .4rem}
.proc-level p{font-size:.8125rem;color:var(--text-dim);line-height:1.65}
/* The requirement line sits on the floor of every card, the way the range
   line does in a spec block: without this the four cards read as four
   unrelated paragraphs because the lines start at four different heights. */
.proc-needs{display:block;margin-top:auto;padding-top:.75rem;font-family:var(--font-mono);font-size:.625rem;letter-spacing:.02em;color:var(--text-dim);line-height:1.5}

/* Form-factor strip. The five renders were normalised to one transparent
   canvas before watermarking, so they sit on cream or paper without a plate. */
.ff-strip{display:grid;grid-template-columns:repeat(5,1fr);gap:1rem;margin-top:2.25rem;align-items:end}
.ff{text-align:center}
.ff img{width:100%;height:120px;object-fit:contain;margin:0 auto .55rem;filter:drop-shadow(0 12px 18px rgba(8,9,12,.10))}
.ff span{font-family:var(--font-mono);font-size:.5625rem;letter-spacing:.12em;text-transform:uppercase;color:var(--text-dim)}

/* ---------- specification matrix ----------
   A table is the honest form for this: the whole point is comparing four
   attributes across six rows. Below 820px it collapses to cards rather than
   scrolling sideways. */
.spec-matrix{width:100%;border-collapse:collapse;font-size:.875rem}
.spec-matrix caption{text-align:left;font-size:.8125rem;color:var(--text-dim);padding-bottom:1rem}
.spec-matrix th{text-align:left;font-family:var(--font-mono);font-size:.5625rem;letter-spacing:.13em;text-transform:uppercase;color:var(--text-muted);padding:.85rem 1rem;border-bottom:1px solid var(--line-strong);font-weight:600;vertical-align:bottom}
.spec-matrix td{padding:1.05rem 1rem;border-bottom:1px solid var(--line);vertical-align:top;color:var(--text-dim);line-height:1.5}
.spec-matrix td:first-child{color:var(--text);font-weight:600}
.spec-matrix td:first-child a{color:inherit;text-decoration:underline;text-decoration-color:var(--orange-line);text-decoration-thickness:1px;text-underline-offset:3px}
.spec-matrix td:first-child a:hover{text-decoration-color:var(--orange)}
.spec-matrix tbody tr{transition:background .25s var(--ease)}
.spec-matrix tbody tr:hover{background:var(--cream)}
.spec-matrix .num{font-family:var(--font-mono);font-size:.8125rem;color:var(--text);white-space:nowrap}

/* ---------- payload × elevation selection ----------
   Same table as the application matrix, but the first cell is a row header,
   so it has to read as a model name rather than as a column label. The two
   group rows carry the only real insight in the chart: platforms lift a few
   hundred millimetres, pallet machines trade that for reach. */
.sel-table th[scope="row"]{text-align:left;font-family:var(--font-display);font-size:.9375rem;font-weight:600;letter-spacing:-.01em;text-transform:none;color:var(--text);padding:1.05rem 1rem;border-bottom:1px solid var(--line)}
.sel-table .sel-grp th{font-family:var(--font-mono);font-size:.5625rem;letter-spacing:.13em;text-transform:uppercase;color:var(--orange);font-weight:600;padding:1.75rem 1rem .5rem;border-bottom:1px solid var(--line-strong)}
.sel-table tbody tr.sel-grp:first-child th{padding-top:.35rem}
.sel-table tbody tr.sel-grp:hover{background:none}
.sel-note{max-width:680px;margin-top:1.6rem;padding-top:1.25rem;border-top:1px solid var(--line);font-size:.8125rem;color:var(--text-dim);line-height:1.75}
/* The chart is drawn on white, the section is cream. A plate and a hairline
   make the edge deliberate instead of looking like a pasted screenshot. */
.sel-figure{margin:0 0 2.5rem;background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:1.1rem;box-shadow:var(--shadow)}
.sel-figure img{width:100%;height:auto;display:block}
.sel-figure figcaption a{color:var(--orange);text-decoration:underline;text-underline-offset:2px}
.sel-figure figcaption{margin-top:.9rem;padding-top:.85rem;border-top:1px solid var(--line);font-family:var(--font-mono);font-size:.625rem;letter-spacing:.04em;line-height:1.6;color:var(--text-dim)}

/* ---------- per-application spec block ---------- */
.spec-list{display:grid;grid-template-columns:1fr 1fr;gap:1.05rem 1.75rem;margin:1.5rem 0 0;padding:1.3rem 0 0;border-top:1px solid var(--line)}
.spec-list dt{font-family:var(--font-mono);font-size:.5625rem;letter-spacing:.13em;text-transform:uppercase;color:var(--text-muted);margin-bottom:.22rem}
.spec-list dd{font-size:.8125rem;color:var(--text-dim);line-height:1.5}
.spec-list dd strong{color:var(--text);font-weight:600}

@media(max-width:1024px){
  .ff-strip{grid-template-columns:repeat(3,1fr)}
  .proc-levels{grid-template-columns:repeat(2,1fr);gap:1.5rem 1.25rem}
}
@media(max-width:900px){
  .crit-detail{grid-template-columns:1fr;gap:1.75rem;padding:2.5rem 0}
  .crit-detail-alt .crit-detail-figure{order:0}
  .crit-detail .ff-strip{margin-top:0}
}
@media(max-width:620px){
  .proc-levels{grid-template-columns:1fr}
}
@media(max-width:820px){
  .ff-strip{grid-template-columns:repeat(3,1fr);gap:.75rem}
  .ff img{height:84px}
  .spec-matrix thead{display:none}
  .spec-matrix tr{display:block;border:1px solid var(--line);border-radius:var(--radius-sm);margin-bottom:.85rem;padding:.3rem .95rem;background:var(--paper)}
  .spec-matrix td{display:block;padding:.55rem 0;border:0;border-bottom:1px solid var(--line)}
  .spec-matrix td:last-child{border-bottom:0}
  .spec-matrix td::before{content:attr(data-label);display:block;font-family:var(--font-mono);font-size:.5625rem;letter-spacing:.13em;text-transform:uppercase;color:var(--text-muted);margin-bottom:.12rem}
  .spec-matrix td:first-child::before{content:none}
  .spec-matrix td:first-child{font-size:1rem;padding-top:.65rem}
  .spec-list{grid-template-columns:1fr;gap:.9rem}
  /* The selection table's row header is a th, and its group rows are labels
     rather than data cards. Neither should get the data-label treatment. */
  .sel-table th[scope="row"]{display:block;padding:.7rem 0 .15rem;border:0;font-size:1rem}
  .sel-table tr.sel-grp{display:block;border:0;background:none;padding:.2rem 0 0;margin:1.1rem 0 0}
  .sel-table tr.sel-grp th{display:block;padding:0;border:0;font-size:.625rem}
  .sel-table td{padding:.5rem 0}
}

/* ---------- before / after ---------- */
.ba{display:grid;grid-template-columns:1fr 1fr;border:1px solid var(--line);border-radius:var(--radius-lg);overflow:hidden;background:var(--paper)}
.ba-before{padding:3rem 2.5rem;background:var(--cream);position:relative}
.ba-before::after{content:'';position:absolute;inset:0;background:repeating-linear-gradient(45deg,transparent 0 12px,rgba(8,9,12,.02) 12px 13px);pointer-events:none}
.ba-before h3{font-family:var(--font-display);font-size:1.1875rem;font-weight:600;margin-bottom:.85rem;color:var(--text-dim)}
.ba-after{padding:3rem 2.5rem;border-left:1px solid var(--line);background:linear-gradient(160deg,var(--ink),var(--ink-3));color:var(--text-invert);position:relative}
.ba-after h3{font-family:var(--font-display);font-size:1.1875rem;font-weight:600;margin-bottom:.85rem;color:var(--orange-2)}
.ba ul{list-style:none;font-size:.875rem;position:relative;z-index:1}
.ba ul li{padding:.42rem 0;color:var(--text-dim);display:flex;gap:.6rem;align-items:flex-start}
.ba-before ul li::before{content:'—';color:var(--text-muted);flex-shrink:0}
.ba-after ul li{color:var(--text-invert-dim)}
.ba-after ul li::before{content:'→';color:var(--orange);flex-shrink:0;font-weight:700}
.ba-after ul li{font-weight:500}

/* ---------- pipeline ---------- */
.pipe{display:grid;grid-template-columns:repeat(4,1fr);gap:0;border-top:1px solid var(--line);position:relative}
.pipe.steps-3{grid-template-columns:repeat(3,1fr)}
.pipe-step{position:relative;padding:2rem 1.5rem 0 0}
.pipe-step::before{content:'';position:absolute;top:-4px;left:0;width:7px;height:7px;border-radius:50%;background:var(--orange);box-shadow:0 0 0 4px var(--orange-soft)}
.pipe-step .step-num{font-family:var(--font-mono);font-size:.6875rem;font-weight:600;color:var(--orange);margin-bottom:.85rem;letter-spacing:.1em}
.pipe-step h3{font-family:var(--font-display);font-size:1.0625rem;font-weight:600;letter-spacing:-.02em;margin-bottom:.5rem}
.pipe-step p{font-size:.875rem;color:var(--text-dim);line-height:1.65;max-width:260px}
.s-ink .pipe-step p{color:var(--text-invert-dim)}

/* ---------- FAQ ---------- */
.faq{border-top:1px solid var(--line)}
.faq-item{border-bottom:1px solid var(--line)}
.faq-q{
  width:100%;display:flex;justify-content:space-between;align-items:center;gap:1rem;
  padding:1.6rem 0;background:none;border:none;text-align:left;
  font-family:var(--font-display);font-size:1.0625rem;font-weight:500;letter-spacing:-.015em;color:var(--text);
  transition:color .25s var(--ease);
}
.faq-q:hover{color:var(--orange)}
.faq-q .faq-icon{font-family:var(--font-mono);font-size:1.375rem;color:var(--orange);transition:transform .35s var(--ease);flex-shrink:0;line-height:1}
.faq-item.open .faq-icon{transform:rotate(135deg)}
.faq-a{max-height:0;overflow:hidden;transition:max-height .45s var(--ease),opacity .35s var(--ease);opacity:0}
.faq-item.open .faq-a{max-height:600px;opacity:1;padding-bottom:1.5rem}
.faq-a p{font-size:.9375rem;color:var(--text-dim);line-height:1.78;max-width:760px}

/* ---------- CTA ---------- */
.cta{
  position:relative;text-align:center;padding:7rem 1.75rem;overflow:hidden;isolation:isolate;
  background:linear-gradient(160deg,var(--ink),var(--ink-3));color:var(--text-invert);
}
.cta::before{
  content:'';position:absolute;z-index:-1;top:-40%;left:50%;width:120%;aspect-ratio:1;transform:translateX(-50%);
  background:radial-gradient(circle,rgba(255,106,0,.22),transparent 58%);
  animation:pulse 8s ease-in-out infinite;
}
@keyframes pulse{0%,100%{opacity:.6;transform:translateX(-50%) scale(1)}50%{opacity:1;transform:translateX(-50%) scale(1.08)}}
.cta h2{font-family:var(--font-display);font-size:clamp(2.1rem,5vw,3.6rem);font-weight:600;line-height:1.04;letter-spacing:-.035em;margin-bottom:1rem}
.cta p{color:var(--text-invert-dim);margin:0 auto 2rem;max-width:560px;font-size:1.0625rem}
.cta-actions{display:flex;gap:.85rem;justify-content:center;flex-wrap:wrap}
.cta .btn-outline{color:var(--text-invert);border-color:var(--line-dark-strong)}

/* ---------- footer ---------- */
.ft{background:var(--ink);color:var(--text-invert-muted);padding:4.5rem 0 2rem;border-top:1px solid var(--line-dark)}
.ft-grid{display:grid;grid-template-columns:1.8fr 1fr 1fr;gap:3rem;margin-bottom:2.75rem}
.ft h4{font-family:var(--font-mono);color:var(--text-invert);font-weight:600;margin-bottom:1rem;font-size:.6875rem;text-transform:uppercase;letter-spacing:.14em}
.ft p{font-size:.875rem;line-height:1.7}
.ft a{color:var(--text-invert-muted);font-size:.875rem;display:block;margin-bottom:.5rem;transition:color .2s var(--ease),transform .2s var(--ease)}
.ft a:hover{color:var(--orange);transform:translateX(3px)}
/* Postal addresses in the footer. Deliberately not links: the pointer is a
   navigation cue in this column, and an address that looks clickable but is not
   is worse than one that reads as text. */
.ft-addr{display:block;font-style:normal;font-size:.8125rem;line-height:1.55;color:var(--text-invert-muted);margin-bottom:.75rem}
.ft-addr:last-child{margin-bottom:0}
.ft-bottom{border-top:1px solid var(--line-dark);padding-top:1.5rem;display:flex;justify-content:space-between;flex-wrap:wrap;gap:.75rem;font-family:var(--font-mono);font-size:.625rem;letter-spacing:.06em;text-transform:uppercase}

/* ---------- page hero (sub-pages) ---------- */
.page-hero{
  position:relative;padding:9rem 0 4.5rem;color:var(--text-invert);overflow:hidden;isolation:isolate;
  background:linear-gradient(165deg,#0a0b0f 0%,#0d0f14 55%,#12141a 100%);
}
.page-hero::before{
  content:'';position:absolute;inset:0;z-index:-1;
  background:
    radial-gradient(700px 380px at 12% 8%,rgba(255,106,0,.16),transparent 60%),
    radial-gradient(600px 400px at 88% 100%,rgba(120,90,255,.10),transparent 62%);
}
.page-hero::after{
  content:'';position:absolute;inset:0;z-index:-1;opacity:.5;pointer-events:none;
  background-image:linear-gradient(var(--line-dark) 1px,transparent 1px),linear-gradient(90deg,var(--line-dark) 1px,transparent 1px);
  background-size:72px 72px;
  mask-image:radial-gradient(circle at 30% 20%,#000 0%,transparent 72%);
  -webkit-mask-image:radial-gradient(circle at 30% 20%,#000 0%,transparent 72%);
}
.page-hero .kicker{color:var(--orange-2)}
.page-hero h1{font-family:var(--font-display);font-size:clamp(2.4rem,6vw,4.4rem);font-weight:600;line-height:1.02;letter-spacing:-.04em;margin-bottom:1rem}
.page-hero p{font-size:1.125rem;color:var(--text-invert-dim);max-width:640px;line-height:1.7}
.breadcrumb{padding:0 0 1.25rem;font-family:var(--font-mono);font-size:.6875rem;letter-spacing:.06em;text-transform:uppercase;color:var(--text-invert-muted)}
.breadcrumb a{color:var(--text-invert-muted)}
.breadcrumb a:hover{color:var(--orange)}
.breadcrumb span{margin:0 .5rem;opacity:.5}

/* ---------- products hero: the family arrives with the h1 ----------
   The line-up is the argument of the page, so it comes in with the headline
   instead of waiting below the stat cards. The cut-out carries its own
   transparency, so it sits straight on the hero ground - no card, no frame -
   and the group reads as one object at every width. */
.page-hero-family .w{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.06fr);
  gap:3rem;align-items:center;
}
.page-hero-family .w > *{min-width:0}
/* The two-column hero gives the headline half a page instead of the full
   measure, so it takes its own step: one line for the body count, one for the
   claim. At the shared 6vw it broke into three lines and read as a stack. */
.page-hero-family h1{font-size:clamp(2.1rem,3.7vw,3.4rem)}
.ph-note{margin-top:1.15rem;max-width:520px;font-size:.9375rem;line-height:1.65}
.ph-family{
  position:relative;margin:0;
  background:radial-gradient(closest-side at 52% 46%,rgba(255,106,0,.13),transparent 74%);
}
.ph-family img{display:block;width:100%;height:auto;filter:drop-shadow(0 24px 44px rgba(0,0,0,.5))}
.ph-family figcaption{
  margin-top:.9rem;padding-top:.85rem;border-top:1px solid var(--line-dark);
  font-family:var(--font-mono);font-size:.625rem;letter-spacing:.13em;text-transform:uppercase;
  color:var(--text-invert-muted);
}
@media(max-width:900px){
  .page-hero-family .w{grid-template-columns:1fr;gap:2.25rem}
  .ph-family{max-width:none}
  .ph-family figcaption{margin-top:.5rem}
}

/* ---------- page hero: the four questions ----------
   The hero carries the page's argument rather than a slogan. Payload, form
   factor and height answer in one row; process takes the full width because
   it names the four levels the rest of the page builds on. One bordered
   panel with hairline rules, so it reads as a specification sheet. */
.page-hero-questions{padding:7rem 0 4rem}
.hq-list{
  list-style:none;display:grid;grid-template-columns:repeat(3,1fr);
  margin:2rem 0 0;border:1px solid var(--line-dark);border-radius:var(--radius);
  background:rgba(255,255,255,.025);overflow:hidden;
}
.hq-item{padding:1.2rem 1.5rem 1.3rem;border-right:1px solid var(--line-dark);transition:background .3s var(--ease)}
.hq-item:hover{background:rgba(255,106,0,.05)}
.hq-item:nth-child(3){border-right:none}
.hq-item-wide{grid-column:1/-1;border-top:1px solid var(--line-dark);border-right:none;background:rgba(255,255,255,.015)}
.hq-item-wide:hover{background:rgba(255,255,255,.015)}
.hq-num{display:block;font-family:var(--font-mono);font-size:.5625rem;letter-spacing:.16em;color:var(--orange);font-weight:600;margin-bottom:.7rem}
.hq-item h2{font-family:var(--font-display);font-size:1.0625rem;font-weight:600;letter-spacing:-.015em;color:var(--text-invert);margin-bottom:.35rem}
.hq-item > p{font-size:.875rem;max-width:none;line-height:1.65}
.hq-levels{list-style:none;display:grid;grid-template-columns:repeat(4,1fr);gap:1.25rem;margin-top:1.1rem;padding-top:1.1rem;border-top:1px solid var(--line-dark)}
.hq-levels h3{font-family:var(--font-display);font-size:.8125rem;font-weight:600;letter-spacing:-.01em;color:var(--text-invert);margin-bottom:.3rem}
.hq-levels p{font-size:.75rem;line-height:1.6;color:var(--text-invert-dim);max-width:none}
.page-hero p.hero-close{
  margin-top:1.5rem;padding-left:1rem;border-left:2px solid var(--orange);
  font-size:1rem;line-height:1.6;color:var(--text-invert);max-width:660px;
}
.hero-close span{color:var(--text-invert-dim)}
@media(max-width:860px){
  .hq-list{grid-template-columns:1fr}
  .hq-item{border-right:none}
  .hq-item + .hq-item{border-top:1px solid var(--line-dark)}
  .hq-item-wide{grid-column:auto}
  .hq-levels{grid-template-columns:1fr 1fr}
}
@media(max-width:620px){
  .hq-levels{grid-template-columns:1fr;gap:1rem}
}

/* ---------- quote ---------- */
.quote{position:relative;padding:2rem 2.5rem;margin:2.5rem 0;border-radius:var(--radius);background:var(--cream);border:1px solid var(--line);overflow:hidden}
.quote::before{content:'“';position:absolute;top:-1.5rem;left:1rem;font-family:var(--font-serif);font-size:7rem;color:var(--orange);opacity:.16;line-height:1}
.quote p{position:relative;font-family:var(--font-display);font-size:clamp(1.15rem,2.2vw,1.6rem);font-weight:500;line-height:1.4;letter-spacing:-.02em;color:var(--text);margin:0}
.quote p em{font-family:var(--font-serif);font-style:italic;color:var(--orange);background:none;-webkit-text-fill-color:currentColor}

/* ---------- pillar grid ---------- */
.pillar-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:1px;background:var(--line);border:1px solid var(--line);border-radius:var(--radius-lg);overflow:hidden}
.pillar{position:relative;padding:2.5rem 2rem;background:var(--paper);transition:background .3s var(--ease)}
.s-ink .pillar-grid{background:var(--line-dark);border-color:var(--line-dark)}
.s-ink .pillar{background:var(--ink-2)}
.pillar::before{content:'';position:absolute;inset:0;background:radial-gradient(280px circle at var(--mx,50%) var(--my,50%),var(--orange-soft),transparent 60%);opacity:0;transition:opacity .35s var(--ease);pointer-events:none}
.pillar:hover::before{opacity:1}
.pillar .pillar-num{font-family:var(--font-mono);font-size:.6875rem;font-weight:600;color:var(--orange);margin-bottom:.85rem;letter-spacing:.12em}
.pillar h3{font-family:var(--font-display);font-size:1.125rem;font-weight:600;letter-spacing:-.02em;margin-bottom:.6rem}
.pillar p{font-size:.875rem;color:var(--text-dim);line-height:1.68;position:relative;z-index:1}
.s-ink .pillar p{color:var(--text-invert-dim)}

/* ---------- application cards ---------- */
.app-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1.25rem}
/* Four cards, not six: three columns leave the fourth alone on its own row with
   two empty slots beside it. Two columns make it a clean 2x2, and the wider
   card suits the 4:3 stills. */
.app-grid.app-grid--four{grid-template-columns:repeat(2,1fr)}
@media(max-width:768px){.app-grid.app-grid--four{grid-template-columns:1fr}}
.app-card{
  position:relative;overflow:hidden;display:flex;flex-direction:column;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--paper);
  transition:transform .35s var(--ease),border-color .35s var(--ease),box-shadow .35s var(--ease);
}
.app-card:hover{transform:translateY(-5px);border-color:var(--orange-line);box-shadow:var(--shadow)}
.app-card img{width:100%;aspect-ratio:16/9;object-fit:cover;transition:transform .7s var(--ease)}
.app-card:hover img{transform:scale(1.05)}
.app-card .app-body{padding:1.65rem;display:flex;flex-direction:column;flex:1}
.app-card .app-tag{font-family:var(--font-mono);font-size:.5625rem;text-transform:uppercase;letter-spacing:.14em;color:var(--text-muted);font-weight:600;margin-bottom:.5rem}
.app-card h3{font-family:var(--font-display);font-size:1.1875rem;font-weight:600;letter-spacing:-.02em;margin-bottom:.5rem}
.app-card p{font-size:.875rem;color:var(--text-dim);line-height:1.65;flex:1}
.app-meta{display:flex;align-items:center;justify-content:space-between;gap:.75rem;margin-top:1.25rem;padding-top:1.25rem;border-top:1px solid var(--line)}
.app-metric{font-family:var(--font-mono);font-size:.625rem;text-transform:uppercase;letter-spacing:.1em;color:var(--orange);font-weight:600;white-space:nowrap}
.app-models{font-family:var(--font-mono);font-size:.625rem;color:var(--text-muted);text-align:right;letter-spacing:.04em}

/* ---------- application list ---------- */
.app-list{display:flex;flex-direction:column;border-top:1px solid var(--line)}
.app-row{display:grid;grid-template-columns:auto 1fr auto;gap:1.75rem;align-items:center;padding:2rem .5rem;border-bottom:1px solid var(--line);transition:background .25s var(--ease),padding .25s var(--ease)}
.app-row:hover{background:var(--orange-soft);padding-left:1.25rem}
.app-row .app-row-num{font-family:var(--font-mono);font-size:1.125rem;font-weight:600;color:var(--orange);width:2.75rem;letter-spacing:.04em}
.app-row h3{font-family:var(--font-display);font-size:1.375rem;font-weight:600;letter-spacing:-.025em;margin-bottom:.4rem}
.app-row p{font-size:.9375rem;color:var(--text-dim);line-height:1.65;max-width:660px}

/* ---------- tag ---------- */
.tag{display:inline-block;font-family:var(--font-mono);font-size:.5625rem;text-transform:uppercase;letter-spacing:.1em;padding:.3rem .7rem;border:1px solid var(--line-strong);font-weight:600;border-radius:999px}
.tag-orange{border-color:var(--orange);color:var(--orange)}

/* ---------- contact ---------- */
.contact-grid{display:grid;grid-template-columns:1.35fr 1fr;gap:3.5rem;align-items:start}
.form-card{border:1px solid var(--line);border-radius:var(--radius-lg);background:var(--paper);padding:2.5rem;box-shadow:var(--shadow)}
.form-field{margin-bottom:1.35rem}
.form-field label{display:block;font-family:var(--font-mono);font-size:.625rem;font-weight:600;margin-bottom:.5rem;color:var(--text);text-transform:uppercase;letter-spacing:.1em}
.form-field input,.form-field select,.form-field textarea{
  width:100%;padding:.85rem 1rem;font:inherit;font-size:.9375rem;
  border:1px solid var(--line-strong);border-radius:var(--radius-sm);background:var(--paper);color:var(--text);
  transition:border-color .2s var(--ease),box-shadow .2s var(--ease),background .2s var(--ease);
}
.form-field input::placeholder,.form-field textarea::placeholder{color:var(--text-muted)}
.form-field input:focus,.form-field select:focus,.form-field textarea:focus{outline:none;border-color:var(--orange);box-shadow:0 0 0 4px var(--orange-soft)}
.form-field textarea{resize:vertical;min-height:130px}
.form-row{display:grid;grid-template-columns:1fr 1fr;gap:1rem}
/* `hidden` is a UA rule, so any layout declaration on the same element beats
   it - .form-row{display:grid} kept a "hidden" row on screen. This restores the
   attribute's meaning for the elements that carry a display rule. */
.form-row[hidden],.form-field[hidden]{display:none}
.form-note{font-size:.75rem;color:var(--text-muted);margin-top:.85rem;line-height:1.55}
.form-note a{color:var(--orange);text-decoration:none;border-bottom:1px solid var(--orange-line)}
.form-alert{margin:0 0 1.35rem;padding:.9rem 1.05rem;border-radius:var(--radius-sm);font-size:.8125rem;line-height:1.55;border:1px solid var(--line);background:var(--cream);color:var(--text-dim)}
.form-alert[hidden]{display:none}
.form-alert.is-ok{border-color:rgba(20,120,70,.28);background:rgba(20,120,70,.07);color:#145a37}
.form-alert.is-bad{border-color:rgba(180,40,30,.3);background:rgba(180,40,30,.06);color:#8f2419}
.form-alert.is-wait{color:var(--text-muted)}
.hp-field{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
/* Set when the page is opened from a specific call to action, e.g. the media
   kit button. Says which request this is before the visitor types anything, so
   they are not left wondering whether the generic form is the right place. */
.form-topic{
  display:inline-block;margin:0 0 1.35rem;padding:.4rem .7rem;border-radius:999px;
  font-family:var(--font-mono);font-size:.625rem;letter-spacing:.08em;text-transform:uppercase;
  color:var(--orange);background:var(--orange-soft);border:1px solid var(--orange-line);
}
.form-topic[hidden]{display:none}
.form-sent{display:none;scroll-margin-top:7rem}
.form-sent:target{display:block}
.form-sent p{margin:0 0 .4rem}
.form-sent p:last-child{margin-bottom:0}
.form-sent a{color:inherit;text-decoration:underline}
.contact-info h3{font-family:var(--font-display);font-size:1.375rem;font-weight:600;letter-spacing:-.02em;margin-bottom:1.5rem}
.contact-info .ci{margin-bottom:1.5rem;padding-bottom:1.5rem;border-bottom:1px solid var(--line)}
.contact-info .ci:last-of-type{border-bottom:none}
.contact-info .ci-label{font-family:var(--font-mono);font-size:.625rem;text-transform:uppercase;letter-spacing:.12em;color:var(--text-muted);font-weight:600;margin-bottom:.4rem}
.contact-info .ci-value{font-size:1rem;color:var(--text)}
.contact-info .ci-value a{color:var(--text)}
.contact-info .ci-value a:hover{color:var(--orange)}
.contact-trust{list-style:none;display:grid;gap:.6rem}
.contact-trust li{position:relative;padding-left:1.7rem;font-size:.875rem;color:var(--text-dim)}
.contact-trust li::before{content:'';position:absolute;left:0;top:.35em;width:14px;height:8px;border-left:2px solid var(--orange);border-bottom:2px solid var(--orange);transform:rotate(-45deg)}

/* ---------- reveal / motion ---------- */
/* Hidden only once main.js has said it is running (`reveal-ready`). The old
   rule keyed off `html.js`, which the inline head script sets whether or not
   main.js ever arrives - so a blocked or 404'd script left every .reveal block
   at opacity 0 with nothing able to clear it. Content must not depend on a
   script that might not load. A blocking script at the end of <body> runs
   before first paint, so this costs no flash of unstyled content. */
html.reveal-ready .reveal{opacity:0;transform:translateY(26px);transition:opacity .8s var(--ease-out),transform .8s var(--ease-out);transition-delay:var(--d,0ms)}
html.reveal-ready .reveal.visible{opacity:1;transform:none}
@media(prefers-reduced-motion:reduce){
  html.reveal-ready .reveal{opacity:1;transform:none;transition:none}
  .hero-center::after,.hero-center::before,.ticker-inner,.cta::before{animation:none}
  html{scroll-behavior:auto}
}

/* ---------- polish ---------- */
:root{--nav-h:72px}
[id]{scroll-margin-top:calc(var(--nav-h) + 20px)}
body{-webkit-tap-highlight-color:transparent}
h1,h2,h3,h4,.h2,.hero-center h1,.page-hero h1,.cta h2,.fsplit-text h2{text-wrap:balance}
p,li,figcaption{text-wrap:pretty}
/* Images carry no background: most of the art is transparent (product
   renders, technical diagrams, the nav mark). A blanket placeholder tint
   painted a cream box behind every one of them, which showed as a hard-edged
   rectangle wherever the art did not fill the frame. */
img{background:transparent}
@media(max-width:768px){:root{--nav-h:64px}}

/* ---------- responsive ---------- */
@media(max-width:1024px){
  .fsplit{grid-template-columns:1fr;gap:2.75rem}
  .fsplit-alt{direction:ltr}
  .stats-grid{grid-template-columns:repeat(2,1fr)}
  .card-grid,.app-grid,.img-grid{grid-template-columns:repeat(2,1fr)}
  .pillar-grid{grid-template-columns:1fr}
  .pipe,.pipe.steps-3{grid-template-columns:repeat(2,1fr);gap:2rem 1.5rem}
  .pipe-step p{max-width:none}
  .ft-grid{grid-template-columns:1fr 1fr}
}
@media(max-width:768px){
  body{padding-top:64px}
  .nav{height:64px}
  .s{padding:4rem 0}
  .w,.w-narrow{padding:0 1.25rem}
  .hero-center{min-height:auto;padding:4.5rem 0 3.5rem}
  .hero-center h1{font-size:clamp(2.5rem,12vw,3.6rem)}
  .stats-grid{grid-template-columns:1fr}
  .card-grid,.card-grid.cols-2,.app-grid,.img-grid{grid-template-columns:1fr}
  .contact-grid{grid-template-columns:1fr;gap:2.5rem}
  .form-row{grid-template-columns:1fr}
  .form-card{padding:1.75rem}
  .ba{grid-template-columns:1fr}
  .ba-after{border-left:none;border-top:1px solid var(--line)}
  .pipe,.pipe.steps-3{grid-template-columns:1fr}
  .app-row{grid-template-columns:auto 1fr;gap:1rem;padding:1.5rem .25rem}
  .app-row .app-metric{grid-column:2;text-align:left}
  .ft-grid{grid-template-columns:1fr;gap:2rem}
  .page-hero{padding:7rem 0 3.25rem}
  .quote{padding:1.5rem 1.5rem}
}

/* ---------- video facade ----------
   The poster is what gets painted, so no video bytes are fetched until the
   visitor asks for them. One <img> plus a real <button>: keyboard and screen
   reader users get the same affordance as a mouse user. */
.video-facade{
  position:relative;display:block;width:100%;aspect-ratio:16/9;
  overflow:hidden;border:1px solid var(--line);border-radius:var(--radius);
  background:var(--ink-2);
}
.s-ink .video-facade{border-color:var(--line-dark)}
/* The TOF capture is a 2.1:1 tool window, not 16:9. Matching the container to
   the media keeps poster and playback identical: `cover` on the poster and
   `contain` on the video would otherwise crop one and letterbox the other, and
   the frame would jump the moment playback started. */
.video-facade.is-wide{aspect-ratio:40/19}
.video-facade img{
  width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .7s var(--ease-out),filter .4s var(--ease);
}
.video-facade:hover img{transform:scale(1.035)}
.video-facade::after{
  content:'';position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(8,9,12,0) 45%,rgba(8,9,12,.55) 100%);
  transition:opacity .4s var(--ease);
}
/* Screen recordings are content, not mood: a cinematic scrim darkens half the
   interface and the duration badge already has its own background. Keep just
   enough gradient to seat the play button. */
.video-facade.is-ui::after{
  background:linear-gradient(180deg,rgba(8,9,12,0) 60%,rgba(8,9,12,.28) 100%);
}
.video-play{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  z-index:2;display:grid;place-items:center;
  width:74px;height:74px;padding:0;border:none;border-radius:50%;
  background:var(--orange);color:#fff;cursor:pointer;
  box-shadow:0 18px 40px -14px rgba(255,106,0,.75);
  transition:transform .3s var(--ease),background .25s var(--ease);
}
.video-play:hover{transform:translate(-50%,-50%) scale(1.08);background:var(--orange-2)}
.video-play svg{width:26px;height:26px;margin-left:3px;fill:currentColor}
.video-duration{
  position:absolute;right:.9rem;bottom:.85rem;z-index:2;
  font-family:var(--font-mono);font-size:.6875rem;letter-spacing:.06em;
  color:var(--text-invert);background:rgba(8,9,12,.72);
  padding:.2rem .5rem;border-radius:6px;pointer-events:none;
}
/* The X22 safety clip ships with a Dallas Roboter mark burned into its own
   bottom-right corner. Our duration badge lives in exactly that corner, so the
   two stacked - "0:40" sitting on the wordmark. The footage keeps its mark; the
   badge moves to the other side. */
.video-facade.has-corner-mark .video-duration{right:auto;left:.9rem}
.video-facade.is-playing::after,
.video-facade.is-playing .video-play,
.video-facade.is-playing .video-duration{display:none}
/* The poster must go too. Both it and the <video> are display:block at 100%
   height, so leaving the image in place pushed the playing video below the
   container, where overflow:hidden clipped it. The clock advanced while the
   visitor watched a frozen poster - which is exactly what "the video does not
   play" looked like. */
.video-facade.is-playing img{display:none}
.video-facade video{
  width:100%;height:100%;display:block;object-fit:contain;background:#000;
}
/* Shown only when a media host fails to load. Deliberately visible: a black
   rectangle with no message is the failure mode this replaced. */
.video-fallback{
  font-family:var(--font-mono);font-size:.6875rem;line-height:1.6;
  color:var(--text-dim);padding:.75rem 0 0;
}
.video-fallback a{color:var(--orange);text-decoration:underline}
.s-ink .video-fallback{color:var(--text-invert-dim)}
.video-caption{
  font-family:var(--font-mono);font-size:.625rem;letter-spacing:.04em;
  color:var(--text-dim);padding:.85rem 0 0;line-height:1.5;
}
/* Two clips side by side under a lead video. Collapses before the posters
   get small enough that the node labels stop being readable. */
.video-duo{display:grid;grid-template-columns:1fr 1fr;gap:1.25rem;margin-top:1.25rem}
@media(max-width:820px){.video-duo{grid-template-columns:1fr}}
/* Two films of different shapes. The MMU cut is 4:5 — a social vertical — and a
   16:9 box would letterbox it to a strip with black wings either side. So the
   portrait facade takes its own aspect and the columns go uneven: the wide clip
   gets the width, the portrait one the height. Capped, because at full column
   width the portrait runs half again as tall as the landscape beside it. */
.video-duo--mixed{grid-template-columns:1.35fr 1fr;align-items:start}
.video-duo--mixed .video-facade.is-portrait{aspect-ratio:4/5;max-width:min(100%,17.5rem);margin:0 auto}
@media(max-width:820px){
  .video-duo--mixed{grid-template-columns:1fr}
  .video-duo--mixed .video-facade.is-portrait{max-width:min(100%,20rem)}
}
.s-ink .video-caption{color:var(--text-invert-dim)}

/* ---------- in short ----------
   The extractable summary on the homepage. A plain paragraph, visually quiet but
   not hidden: a reader who wants facts before scrolling gets them, and a model
   gets a self-contained passage with entities, numbers, and places in one
   breath. No scrim, no gradient, no scroll-triggered reveal - content written to
   be quoted should not depend on an intersection observer firing. */
.in-short{padding:3.25rem 0;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.in-short-kicker{
  font-family:var(--font-mono);font-size:.625rem;font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;color:var(--orange);
  margin:0 0 .9rem;
}
.in-short-text{
  max-width:78ch;font-size:1.0625rem;line-height:1.75;color:var(--text-dim);margin:0;
}
.in-short-text strong{color:var(--text);font-weight:600}
@media(max-width:620px){.in-short{padding:2.5rem 0}.in-short-text{font-size:1rem;line-height:1.7}}

/* ---------- youtube grid ----------
   Every film on the media page comes from the channel, so the page stores
   posters and links, not files. The thumbnail is a real <a> to YouTube: with
   no JavaScript that is the whole experience and it works. initYouTube() turns
   the click into an inline player, which is why the iframe only ever lands
   inside a <div> - never inside the anchor it replaced, and never nested in a
   link that a stray keystroke could re-fire. */
/* The films section's visible heading moved to the page hero, but the cards are
   <h3>s - without an <h2> above them the document outline jumps h1 -> h3. This
   keeps the level for screen readers and the visual design for everyone else. */
.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}

/* The channel link used to sit under a heading in the section header. The
   heading moved to the page hero, so this is now the section's first line and
   needs its own breathing room above the filters. */
.yt-channel{margin:0 0 1.6rem}
.yt-channel a{
  font-family:var(--font-mono);font-size:.6875rem;letter-spacing:.08em;
  text-transform:uppercase;color:var(--orange);text-decoration:none;
  border-bottom:1px solid var(--orange-line);padding-bottom:2px;
  transition:border-color .2s var(--ease),color .2s var(--ease);
}
.yt-channel a:hover{border-bottom-color:var(--orange);color:var(--orange-2)}

.yt-filters{display:flex;flex-wrap:wrap;gap:.45rem;margin:0 0 1.9rem}
.yt-chip{
  font-family:var(--font-mono);font-size:.625rem;letter-spacing:.08em;text-transform:uppercase;
  color:var(--text-dim);background:transparent;border:1px solid var(--line-strong);
  border-radius:999px;padding:.5rem .9rem;cursor:pointer;
  transition:color .2s var(--ease),border-color .2s var(--ease),background .2s var(--ease);
}
.yt-chip:hover{color:var(--text);border-color:var(--text-dim)}
.yt-chip.is-on{background:var(--ink);border-color:var(--ink);color:var(--paper)}
.yt-chip:focus-visible{outline:2px solid var(--orange);outline-offset:2px}

.yt-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:2.1rem 1.35rem;align-items:start}
.yt-card{display:flex;flex-direction:column}
.yt-card.is-hidden{display:none}
.yt-thumb{
  position:relative;display:block;width:100%;aspect-ratio:16/9;overflow:hidden;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--ink-2);
}
.yt-thumb img{
  width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .7s var(--ease-out);
}
.yt-thumb:hover img{transform:scale(1.035)}
.yt-play{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  z-index:2;display:grid;place-items:center;width:54px;height:54px;border-radius:50%;
  background:rgba(8,9,12,.62);color:#fff;
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  transition:background .25s var(--ease),transform .3s var(--ease);
}
.yt-thumb:hover .yt-play{background:var(--orange);transform:translate(-50%,-50%) scale(1.08)}
.yt-play svg{width:20px;height:20px;margin-left:2px;fill:currentColor}
.yt-dur{
  position:absolute;right:.6rem;bottom:.55rem;z-index:2;
  font-family:var(--font-mono);font-size:.625rem;letter-spacing:.06em;
  color:var(--text-invert);background:rgba(8,9,12,.78);
  padding:.15rem .4rem;border-radius:5px;pointer-events:none;
}
.yt-thumb iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.yt-thumb.is-playing img,
.yt-thumb.is-playing .yt-play,
.yt-thumb.is-playing .yt-dur{display:none}

.yt-body{padding:.95rem 0 0}
.yt-body h3{
  font-family:var(--font-display);font-size:.9375rem;font-weight:600;
  letter-spacing:-.01em;line-height:1.35;margin:0 0 .45rem;
}
.yt-body h3 a{color:var(--text);text-decoration:none;transition:color .2s var(--ease)}
.yt-body h3 a:hover{color:var(--orange)}
.yt-body p{font-size:.8125rem;line-height:1.6;color:var(--text-dim);margin:0 0 .6rem;max-width:none}
.yt-meta{
  font-family:var(--font-mono);font-size:.625rem;letter-spacing:.06em;
  color:var(--text-muted);text-transform:uppercase;
}

/* A Short is 9:16, and nothing else in the grid is. Stretched to the column it
   would run two and a half times the height of the landscape cards beside it and
   drag the whole row with it, so the vertical card is narrowed instead and
   centred in its cell, with the text aligned to the same narrow measure. The
   grid is align-items:start so its neighbours keep their own height rather than
   padding themselves out to match - a tall row with white space below two cards
   is honest; two cards with a third of their body empty is not. */
.yt-card.is-vertical{max-width:16rem;margin-inline:auto}
.yt-card.is-vertical .yt-thumb{aspect-ratio:9/16}
.yt-card.is-vertical .yt-play{width:48px;height:48px}
.yt-card.is-vertical .yt-play svg{width:18px;height:18px}

@media(max-width:1024px){.yt-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:620px){
  .yt-grid{grid-template-columns:1fr;gap:1.9rem}
  .yt-card.is-vertical{max-width:min(100%,20rem)}
}
@media(prefers-reduced-motion:reduce){
  .yt-thumb img{transition:none}
  .yt-thumb:hover img{transform:none}
}

@media(max-width:768px){
  .video-play{width:60px;height:60px}
  .video-play svg{width:21px;height:21px}
}

@media(prefers-reduced-motion:reduce){
  .video-facade img{transition:none}
  .video-facade:hover img{transform:none}
}

/* ---------- consent banner ----------
   Reject and Accept are the same size and the same weight, one click each.
   Refusal must never cost more effort than acceptance. */
.consent{
  position:fixed;left:1.25rem;bottom:1.25rem;z-index:9999;
  width:min(480px,calc(100vw - 2.5rem));
  max-height:calc(100vh - 2.5rem);overflow-y:auto;
  background:var(--paper);color:var(--text);
  border:1px solid var(--line-strong);border-radius:var(--radius);
  box-shadow:var(--shadow-lg);
  opacity:0;transform:translateY(14px);
  transition:opacity .26s var(--ease),transform .26s var(--ease);
}
.consent.is-open{opacity:1;transform:none}
.consent-inner{padding:1.5rem 1.5rem 1.375rem}
.consent-title{
  font-family:var(--font-display);font-size:1.0625rem;font-weight:600;
  letter-spacing:-.01em;margin:0 0 .625rem;color:var(--text);
}
.consent-desc{
  font-size:.8125rem;line-height:1.65;color:var(--text-dim);margin:0 0 1.1rem;
}
.consent-desc a{color:var(--orange);text-decoration:underline;text-underline-offset:2px}

.consent-panel{
  border:1px solid var(--line);border-radius:var(--radius-sm);
  padding:.25rem 1rem;margin:0 0 1.1rem;max-height:44vh;overflow-y:auto;
  background:var(--cream);
}
.consent-row{padding:.95rem 0;border-bottom:1px solid var(--line)}
.consent-row:last-child{border-bottom:none}
.consent-row-head{display:flex;align-items:center;justify-content:space-between;gap:1rem}
.consent-row-label{font-size:.8125rem;font-weight:600;color:var(--text);cursor:pointer}
.consent-row-body{font-size:.75rem;line-height:1.6;color:var(--text-dim);margin:.375rem 0 0}
.consent-row-vendors{font-size:.6875rem;line-height:1.5;color:var(--text-muted);margin:.375rem 0 0}

/* switch */
.consent-switch{position:relative;display:inline-flex;flex:none;cursor:pointer}
.consent-switch input{
  position:absolute;inset:0;z-index:2;opacity:0;margin:0;cursor:pointer;
}
.consent-slider{
  width:38px;height:22px;border-radius:999px;background:var(--line-strong);
  position:relative;transition:background .25s var(--ease);
}
.consent-slider::after{
  content:'';position:absolute;top:3px;left:3px;width:16px;height:16px;
  border-radius:50%;background:#fff;transition:transform .25s var(--ease);
  box-shadow:0 1px 3px rgba(8,9,12,.35);
}
.consent-switch input:checked + .consent-slider{background:var(--orange)}
.consent-switch input:checked + .consent-slider::after{transform:translateX(16px)}
.consent-switch input:disabled + .consent-slider{background:var(--text-muted);opacity:.6;cursor:not-allowed}
.consent-switch input:focus-visible + .consent-slider{
  outline:2px solid var(--orange);outline-offset:3px;
}

.consent-actions{display:flex;flex-wrap:wrap;gap:.5rem}
.consent-btn{
  /* Equal basis, not content-based: refusal and acceptance must occupy the
     same width, so neither reads as the easier path. */
  flex:1 1 0;min-width:0;min-height:40px;padding:.6rem .75rem;
  font-family:var(--font-display);font-size:.8125rem;font-weight:600;
  border-radius:var(--radius-sm);border:1px solid transparent;cursor:pointer;
  transition:background .22s var(--ease),border-color .22s var(--ease),color .22s var(--ease);
  white-space:nowrap;
}
.consent-btn-solid{background:var(--orange);color:#fff}
.consent-btn-solid:hover{background:var(--orange-2)}
.consent-btn-ghost{background:transparent;color:var(--text);border-color:var(--line-strong)}
.consent-btn-ghost:hover{border-color:var(--text-dim);background:var(--cream)}
/* Refusal is a primary button too. Same size, same row, one click. */
.consent-btn-dark{background:var(--ink);color:#fff}
.consent-btn-dark:hover{background:var(--ink-3)}
.consent-btn[hidden]{display:none}

@media(max-width:768px){
  .consent{left:.75rem;right:.75rem;bottom:.75rem;width:auto;
           max-height:calc(100vh - 1.5rem);overflow-y:auto}
  .consent-inner{padding:1.25rem 1.25rem 1.125rem}
  .consent-actions{flex-direction:column-reverse}
  .consent-btn{width:100%;flex:1 1 auto}
}

@media(prefers-reduced-motion:reduce){
  .consent{transition:none}
  .consent-slider,.consent-slider::after{transition:none}
}

/* footer link that reopens preferences */
.ft-cookies{
  background:none;border:none;padding:0;margin:0;cursor:pointer;
  font:inherit;color:inherit;text-decoration:underline;
  text-underline-offset:2px;opacity:.85;
}
.ft-cookies:hover{opacity:1}
