/* ============================================================
   SpotNet - spotnet.co.il
   Same design language as SpotGroup ("Leo" edition):
   black canvas, huge light typography, orange gradient emphasis,
   rounded media cards, clip-path reveals.
   Bi-directional: English (LTR, default) + Hebrew (RTL).
   ============================================================ */

:root {
  /* Brand */
  --orange: #F37021;
  --orange-bright: #FF8A3D;
  --orange-deep: #FF9A52;
  --orange-glow: rgba(243, 112, 33, 0.35);
  --orange-soft: rgba(243, 112, 33, 0.16);
  --orange-50: rgba(243, 112, 33, 0.13);

  /* Emphasis gradient - saturated to cream, flipped for RTL below */
  --grad-word: linear-gradient(to right, #FF7A1E 0%, #FFB26B 55%, #FFE3C4 100%);

  /* Dark scale - warm charcoal, no blue cast */
  --bg: #000000;
  --bg-soft: #0C0A08;
  --card: #12100D;
  --card-2: #191512;
  --line: rgba(255, 255, 255, 0.10);
  --line-soft: rgba(255, 255, 255, 0.06);

  /* Text */
  --text-1: #FFFFFF;
  --text-2: rgba(255, 255, 255, 0.75);
  --text-3: rgba(255, 255, 255, 0.55);
  --muted: rgba(255, 255, 255, 0.60);

  /* Effects */
  --shadow-md: 0 10px 30px -10px rgba(0,0,0,0.6);
  --shadow-lg: 0 30px 80px -20px rgba(0,0,0,0.75);
  --shadow-orange: 0 16px 44px -12px rgba(243,112,33,0.5);

  /* Radii */
  --r-sm: 10px;
  --r-md: 16px;
  --r-lg: 24px;
  --r-xl: 32px;
  --r-pill: 999px;

  /* Type */
  --font-display: 'Rubik', system-ui, sans-serif;
  --font-body: 'Inter', 'Rubik', system-ui, sans-serif;

  /* Motion - the Leo curve */
  --ease-leo: cubic-bezier(0.165, 0.84, 0.44, 1);
  --dur-leo: 1.2s;

  /* pointer position, written by the effects engine */
  --mx: 50%;
  --my: 50%;
}

[dir="rtl"] {
  --grad-word: linear-gradient(to left, #FF7A1E 0%, #FFB26B 55%, #FFE3C4 100%);
  --font-body: 'Assistant', 'Rubik', system-ui, sans-serif;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; }

html, body {
  font-family: var(--font-body);
  background: var(--bg);
  color: var(--text-2);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  line-height: 1.6;
  overflow-x: clip;
}

::selection { background: rgba(243,112,33,0.35); color: #fff; }

a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; border: none; background: none; color: inherit; }
img { display: block; max-width: 100%; }

/* language visibility - JS sets the html[data-lang] attribute */
[data-lang="en"] .only-he { display: none !important; }
[data-lang="he"] .only-en { display: none !important; }

/* ============================================================
   Layout
   ============================================================ */
.container { width: min(1320px, 92%); margin-inline: auto; }
.container-narrow { width: min(1040px, 92%); margin-inline: auto; }

section { padding: 130px 0; position: relative; }
@media (max-width: 768px) { section { padding: 84px 0; } }

.glow-spot {
  position: absolute;
  width: 70vw; height: 70vw;
  max-width: 900px; max-height: 900px;
  border-radius: 50%;
  background: radial-gradient(circle at center, rgba(243,112,33,0.16) 0%, rgba(243,112,33,0.05) 40%, transparent 70%);
  filter: blur(40px);
  pointer-events: none;
  z-index: 0;
}

/* ============================================================
   Eyebrows
   ============================================================ */
/* Kept only where a label genuinely earns its place - a partner
   status, a section that needs naming. Never above every heading. */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 14px;
  letter-spacing: 0.01em;
  color: var(--orange-bright);
}
.eyebrow::before {
  content: "";
  width: 24px; height: 1px;
  background: var(--orange);
  opacity: .7;
}
.eyebrow.on-dark { color: var(--orange-bright); }

/* ============================================================
   Typography - huge & light
   ============================================================ */
.display-1 {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(44px, 7vw, 104px);
  line-height: 1.04;
  letter-spacing: -0.01em;
  color: var(--text-1);
}
.display-2 {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(36px, 5vw, 76px);
  line-height: 1.08;
  letter-spacing: -0.005em;
  color: var(--text-1);
}
.display-3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(26px, 3vw, 42px);
  line-height: 1.15;
  color: var(--text-1);
}

.gradient-text,
.display-1 strong, .display-2 strong, .display-3 strong,
h1 strong, h2 strong {
  font-weight: inherit;
  background: var(--grad-word);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.lede {
  font-size: clamp(16.5px, 1.35vw, 20px);
  line-height: 1.75;
  color: var(--text-3);
  font-weight: 300;
  max-width: 62ch;
}
.lede.on-dark { color: var(--text-2); }

/* ============================================================
   Buttons
   ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 15px 30px;
  border-radius: var(--r-pill);
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 15.5px;
  letter-spacing: 0.01em;
  transition: transform .45s var(--ease-leo), box-shadow .45s var(--ease-leo),
              background .3s, color .3s, border-color .3s;
  white-space: nowrap;
}
.btn-primary {
  /* bright to base, the same way round as the group's pill */
  background: linear-gradient(135deg, var(--orange-bright), var(--orange));
  color: #fff;
  box-shadow: var(--shadow-orange);
}
.btn-primary:hover { transform: translateY(-3px); box-shadow: 0 24px 60px -12px rgba(243,112,33,0.65); }

.btn-ghost {
  border: 1px solid rgba(255,255,255,0.25);
  color: #fff;
  background: transparent;
}
.btn-ghost:hover { background: #fff; color: #000; border-color: #fff; }
.btn-ghost.on-dark { color: #fff; border-color: rgba(255,255,255,0.25); background: transparent; }
.btn-ghost.on-dark:hover { background: #fff; color: #000; border-color: #fff; }

.btn-light { background: #fff; color: #000; }
.btn-light:hover { transform: translateY(-3px); }

.btn .arrow { width: 18px; height: 18px; transition: transform .45s var(--ease-leo); flex-shrink: 0; }
.btn:hover .arrow { transform: translateX(4px); }
[dir="rtl"] .btn .arrow { transform: scaleX(-1); }
[dir="rtl"] .btn:hover .arrow { transform: scaleX(-1) translateX(4px); }

/* ============================================================
   Header - floating white card (Leo nav)
   Every rule here is the group's rule, verbatim: the pill, the nav,
   the language chip and the drawer are one component shared by
   spot-group.co.il and spotnet.co.il. Only the logo width differs.
   ============================================================ */
.site-header {
  position: fixed;
  inset-inline: 0;
  top: 22px;
  z-index: 900;
  pointer-events: none;
  transition: top .5s var(--ease-leo);
}
.site-header.scrolled { top: 12px; }

/* The unified group header: glass pill, 72px tall */
.header-pill {
  pointer-events: auto;
  width: min(1320px, 94%);
  margin-inline: auto;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 20px;
  background: rgba(255,255,255,0.94);
  backdrop-filter: blur(22px);
  -webkit-backdrop-filter: blur(22px);
  color: #0A0A0E;
  border: 1px solid rgba(0,0,0,0.06);
  border-radius: 999px;
  min-height: 72px;
  padding: 0 18px;
  box-shadow: 0 10px 40px -14px rgba(0,0,0,0.5);
  transition: box-shadow .5s var(--ease-leo), min-height .5s var(--ease-leo), background .5s var(--ease-leo);
}
.site-header.scrolled .header-pill {
  background: rgba(255,255,255,0.98);
  box-shadow: 0 14px 50px -14px rgba(0,0,0,0.55);
  min-height: 64px;
}

.brand-link {
  display: flex;
  align-items: center;
  /* No horizontal padding.

     The pill pads its own edges, so the brand box and the call to action
     both start 19px in - but the button's padding sits inside its coloured
     background, and the brand's sat outside the ink. The button's visible
     edge landed at 19px and the wordmark's at 33px, and the eye compares
     the two things it can see, not the two boxes. Vertical padding stays:
     that is the tap target, and it costs nothing across. */
  padding: 10px 0;
}
/* Two very different marks: SpotGroup is a 13.7:1 wordmark, SpotNet is
   a 4.5:1 shield-plus-wordmark. Matching their heights would make one of
   them twice the width of the other, so they are matched on the width
   they actually occupy in the pill instead. */
.brand-link img { width: 168px; height: auto; max-width: none; display: block; flex-shrink: 0; }

.primary-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-width: 0;
}
.primary-nav a {
  padding: 10px 15px;
  border-radius: var(--r-pill);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 15px;
  color: #26262E;
  white-space: nowrap;
  transition: background .25s, color .25s;
}
.primary-nav a:hover { background: rgba(243,112,33,0.10); color: #C2570E; }
.primary-nav a.active {
  background: #0A0A0E;
  color: #fff;
}

/* ---- Services, as a disclosure ------------------------------
   Open on hover for a pointer, on :focus-within for a keyboard (no
   script needed for either), and on the caret for a touch screen.
   The panel is adjacent to the item and the whole item stays hovered
   while the pointer travels into it, which is what 1.4.13 asks for. */
.nav-item { position: relative; display: flex; align-items: center; }
.nav-item > a { padding-inline-end: 8px; }
/* On a service page the pill has to hold the caret too. With the
   background on the link, the pill stopped at the word and the caret
   floated beside it as a second, unrelated thing. */
.nav-item.active-branch {
  background: #0A0A0E;
  border-radius: var(--r-pill);
  padding-inline-end: 9px;
}
.nav-item.active-branch > a.active { background: none; }
.nav-item.active-branch .sub-toggle { color: #fff; opacity: .7; }
.nav-item.active-branch:hover .sub-toggle,
.nav-item.active-branch:focus-within .sub-toggle { color: #fff; opacity: 1; }
.sub-toggle {
  display: flex; align-items: center; justify-content: center;
  width: 22px; height: 26px;
  margin-inline-start: -6px;
  border-radius: var(--r-pill);
  color: #26262E;
  opacity: .65;
  transition: transform .3s var(--ease-leo), opacity .25s, color .25s;
}
.nav-item:hover .sub-toggle,
.nav-item:focus-within .sub-toggle { opacity: 1; color: #C2570E; }
.sub-toggle[aria-expanded="true"] { transform: rotate(180deg); }

.subnav {
  position: absolute;
  top: calc(100% + 14px);
  inset-inline-start: 50%;
  transform: translateX(-50%) translateY(-6px);
  min-width: 232px;
  padding: 8px;
  list-style: none;
  border-radius: var(--r-md);
  border: 1px solid rgba(0,0,0,0.07);
  background: rgba(255,255,255,0.98);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  box-shadow: 0 18px 50px -16px rgba(0,0,0,0.35);
  opacity: 0;
  visibility: hidden;
  transition: opacity .28s var(--ease-leo), transform .28s var(--ease-leo), visibility .28s;
}
/* the gap between the pill and the panel would drop the hover, so the
   item's own hitbox is extended across it */
.nav-item.has-sub::after {
  content: "";
  position: absolute;
  top: 100%; inset-inline: -10px;
  height: 16px;
}
.nav-item:hover .subnav,
.nav-item:focus-within .subnav,
.subnav.open {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
}
[dir="rtl"] .nav-item:hover .subnav,
[dir="rtl"] .nav-item:focus-within .subnav,
[dir="rtl"] .subnav.open { transform: translateX(50%) translateY(0); }

[dir="rtl"] .subnav { transform: translateX(50%) translateY(-6px); }

.subnav a {
  display: block;
  padding: 9px 13px;
  border-radius: var(--r-sm);
  font-family: var(--font-display);
  font-size: 14.5px;
  font-weight: 400;
  color: #26262E;
  white-space: nowrap;
  transition: background .2s, color .2s;
}
.subnav a:hover { background: rgba(243,112,33,0.10); color: #C2570E; }
/* Where you are, not a second black pill. A filled slab inside a white
   card is the heaviest thing on the panel and it repeats the treatment
   the nav item above is already using - two of them, stacked, for one
   piece of information. This is the accent doing the job it does
   everywhere else on the site: a warm ground, the brand colour at a
   weight that passes AA on it, and a mark down the leading edge. */
.subnav a.here {
  background: rgba(243,112,33,0.13);
  color: #B04E0A;
  font-weight: 500;
}
.subnav a.here::before {
  content: "";
  position: absolute;
  inset-inline-start: 8px;
  top: 50%;
  width: 3px;
  height: 17px;
  border-radius: 2px;
  background: var(--orange);
  transform: translateY(-50%);
}
.subnav li { position: relative; }
.subnav a.here:hover { background: rgba(243,112,33,0.18); color: #B04E0A; }
.subnav-all { margin-top: 6px; padding-top: 6px; border-top: 1px solid rgba(0,0,0,0.07); }
.subnav-all a { color: var(--orange); font-weight: 500; }

/* dismissed with Escape - held shut until the pointer or the focus leaves,
   so returning focus to the caret cannot re-open it through :focus-within */
.nav-item.hushed .subnav { opacity: 0 !important; visibility: hidden !important; }

/* a coarse pointer has no hover to open it with, so only the caret does */
@media (hover: none), (pointer: coarse) {
  .nav-item:hover .subnav { opacity: 0; visibility: hidden; }
  .subnav.open { opacity: 1 !important; visibility: visible !important; }
}

/* the drawer folds them behind a caret, indented under Services */
.mobile-drawer .drawer-sub {
  font-size: 17px;
  opacity: .72;
  padding-inline-start: 22px;
}
.mobile-drawer .drawer-head { display: flex; align-items: center; }
.mobile-drawer .drawer-head > a { flex: 1; min-width: 0; }

/* the caret is its own control, so the label beside it can stay a link.
   It takes the drawer link's padding rather than the header caret's,
   which makes it a 45px target - a finger, not a pointer. */
.mobile-drawer .drawer-toggle {
  padding: 15px 16px;
  border-radius: 14px;
  color: #0A0A0E;
  transition: background .25s, color .25s;
}
.mobile-drawer .drawer-toggle svg {
  width: 15px; height: 15px;
  transition: transform .38s var(--ease-leo);
}
.mobile-drawer .drawer-toggle:hover { background: rgba(243,112,33,0.10); color: #C2570E; }
.mobile-drawer .drawer-group.open .drawer-toggle svg { transform: rotate(180deg); }

/* Folded by height rather than by display, so it slides rather than
   jumps - 0fr to 1fr, which needs no measuring in script. The inner
   wrapper carries the overflow (which is also what lets the row
   collapse past its content) and the visibility, so the seven links
   leave the tab order while they are folded away: a link you cannot
   see but can still tab into is a trap for the one person who has no
   way of telling where the focus went. */
.mobile-drawer .drawer-subs {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .38s var(--ease-leo);
}
.mobile-drawer .drawer-subs > div {
  overflow: hidden;
  visibility: hidden;
  display: flex;
  flex-direction: column;
  gap: 2px;
  transition: visibility .38s;
}
.mobile-drawer .drawer-group.open .drawer-subs { grid-template-rows: 1fr; }
.mobile-drawer .drawer-group.open .drawer-subs > div { visibility: visible; }

@media (prefers-reduced-motion: reduce) {
  .mobile-drawer .drawer-subs,
  .mobile-drawer .drawer-subs > div,
  .mobile-drawer .drawer-toggle svg { transition: none; }
}

.header-cta { display: flex; gap: 10px; align-items: center; justify-self: end; min-width: 0; }
.header-cta .btn { padding: 11px 22px; font-size: 14.5px; white-space: nowrap; }

/* language switch (en <-> he) - lives in the header pill and in the drawer */
.lang-switch {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-family: var(--font-display);
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: .02em;
  color: #12100D;
  white-space: nowrap;
  transition: border-color .25s, color .25s, background .25s;
}
.lang-switch:hover {
  color: #000;
  border-color: rgba(243,112,33,0.55);
  background: rgba(243,112,33,0.08);
}
.lang-switch svg { flex-shrink: 0; opacity: .75; }
.lang-switch:hover svg { opacity: 1; }

.menu-toggle { display: none; color: #0A0A0E; padding: 10px; border-radius: 12px; }
.menu-toggle:hover { background: rgba(0,0,0,0.06); }

/* the nav needs a little more room before it hands over to the drawer */
@media (max-width: 1400px) {
  .primary-nav { gap: 0; }
  .primary-nav a { padding-inline: 11px; font-size: 14.5px; }
}
@media (max-width: 1260px) {
  .primary-nav a { padding-inline: 9px; font-size: 14px; }
  .header-pill { gap: 12px; }
}
@media (max-width: 1180px) {
  .primary-nav { display: none; }
  .menu-toggle { display: inline-flex; }
}
@media (max-width: 1100px) {
  /* Between 560 and 1100 the drawer carries it; below 560 the header
     takes it back. That rule sits earlier in this file, so the range is
     closed here - same specificity means the last one wins. */
  .header-cta .lang-switch { display: none; }
@media (max-width: 560px) {
  .header-cta .lang-switch { display: inline-flex; }
}   /* drawer carries it below this */
}
@media (max-width: 560px) {
  .header-cta .btn-primary { display: none; }
  .site-header { top: 12px; }

  /* On a phone the pill holds the mark and the burger and nothing else.
     Laid out as "mark, then everything else" the mark sits hard against
     the reading edge while the burger drifts to the far side, and the
     gap between them grows with the screen - two items sharing a bar
     rather than a header. Centred, it reads as one.

     Three columns, mark in the middle, burger in the last, and the two
     outer columns take an equal share of what is left - so the mark is
     centred on the pill rather than on whatever happens to sit beside
     it. RTL flows the grid the other way and the burger stays on the
     far side, which is where it already was in both languages.

     The mark keeps its full 168px down to about 345px of viewport and
     gives back only what a narrower screen cannot spare: the width left
     for it is the pill less its 36px of padding, less the burger's 42px
     mirrored on the empty side, less the two 12px gaps and its own 12px
     of padding. The gap is 12 because a max-width:1260px rule above
     sets it - matching that is steadier than racing it. */
  .header-pill { grid-template-columns: 1fr auto 1fr; }
  .brand-link { grid-column: 2; padding-inline: 6px; }
  .brand-link img { width: min(168px, calc(94vw - 156px)); }
  /* The mark is centred, and it did not look it: the two side columns
     were the same width, but one held the menu button and the other
     held nothing, and the eye weighs ink rather than columns. So the
     pair is split, one to each side, matched in size.

     display:contents dissolves the wrapper so its children become grid
     items and can take a column each. Each names its row as well: auto
     placement only moves forward, so an item asking for column 1 after
     the mark has taken column 2 opens a second row instead, and the
     pill grows to twice its height. */
  .header-cta { display: contents; }
  .header-pill .brand-link { grid-row: 1; grid-column: 2; }
  .header-cta .lang-switch { display: inline-flex; grid-row: 1; grid-column: 1; justify-self: start; }
  .header-cta .menu-toggle { grid-row: 1; grid-column: 3; justify-self: end; }

  /* Matched to the menu button so the two sides carry the same weight.
     The globe goes - at this size it is a smudge, and the label already
     says the whole thing. */
  .header-cta .lang-switch {
    width: 42px; height: 42px; padding: 0;
    justify-content: center; gap: 0;
    font-size: 12.5px; letter-spacing: .04em;
  }
  .header-cta .lang-switch svg { display: none; }
}

/* Mobile drawer - white card, Leo-style */
.mobile-drawer {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.6);
  backdrop-filter: blur(8px);
  z-index: 999;
  opacity: 0;
  pointer-events: none;
  transition: opacity .4s var(--ease-leo);
}
.mobile-drawer.open { opacity: 1; pointer-events: auto; }
.mobile-drawer .panel {
  position: absolute;
  top: 12px; inset-inline: 3%;
  background: #fff;
  color: #0A0A0E;
  border-radius: 22px;
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  transform: translateY(-16px) scale(0.98);
  opacity: 0;
  transition: transform .5s var(--ease-leo), opacity .4s var(--ease-leo);
  box-shadow: 0 30px 80px -20px rgba(0,0,0,0.8);
  /* SpotNet carries two more links than the group - let a short screen scroll */
  max-height: calc(100dvh - 24px);
  overflow-y: auto;
}
.mobile-drawer.open .panel { transform: translateY(0) scale(1); opacity: 1; }
.mobile-drawer .panel a {
  padding: 15px 16px;
  border-radius: 14px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 19px;
  color: #0A0A0E;
}
.mobile-drawer .panel a:hover { background: rgba(243,112,33,0.10); color: #C2570E; }
.mobile-drawer .close { align-self: flex-end; padding: 10px; border-radius: 12px; color: #0A0A0E; }
.mobile-drawer .close:hover { background: rgba(0,0,0,0.06); }
.mobile-drawer .drawer-sep { height: 1px; background: rgba(0,0,0,0.08); margin: 10px 8px; }

/* the language chip sits in the drawer below 1100px. On the group it is an
   <a>, so it inherits the drawer's link styling; here it is a <button> and
   has to be told the same numbers to land in the same place. */
.mobile-drawer .lang-switch {
  margin-top: 18px;
  padding: 15px 16px;
  border-radius: 14px;
  border-color: var(--line-soft);
  font-size: 19px;
  font-weight: 400;
  color: #0A0A0E;
}
.mobile-drawer .lang-switch:hover { background: rgba(243,112,33,0.10); color: #C2570E; border-color: var(--line-soft); }

/* ============================================================
   Reveal engine
   ============================================================ */
.reveal, .fade-up, .lv {
  opacity: 0;
  transform: translateY(30px);
  transition: opacity var(--dur-leo) var(--ease-leo), transform var(--dur-leo) var(--ease-leo);
}
.reveal.in, .fade-up.in, .lv.in { opacity: 1; transform: none; }

.lv-card {
  clip-path: inset(14% 8% 14% 8% round var(--r-xl));
  opacity: 0;
  transition: clip-path 1.4s var(--ease-leo), opacity .9s var(--ease-leo);
}
.lv-card.in { clip-path: inset(0% 0% 0% 0% round var(--r-xl)); opacity: 1; }

.lv-words .w {
  display: inline-block;
  opacity: 0;
  transform: translateY(22px);
  transition: opacity .9s var(--ease-leo), transform .9s var(--ease-leo);
  transition-delay: calc(var(--wi) * 45ms);
}
.lv-words.in .w { opacity: 1; transform: none; }

.d1 { transition-delay: .12s; }
.d2 { transition-delay: .24s; }
.d3 { transition-delay: .38s; }
.d4 { transition-delay: .52s; }
.d5 { transition-delay: .66s; }

@media (prefers-reduced-motion: reduce) {
  .reveal, .fade-up, .lv, .lv-card, .lv-words .w {
    opacity: 1 !important; transform: none !important; clip-path: none !important;
    transition: none !important;
  }
  html { scroll-behavior: auto; }
}

/* ============================================================
   Hero
   ============================================================ */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  overflow: hidden;
  padding: 160px 0 120px;
}
.hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
  opacity: .92;
}
.hero-media video, .hero-media img {
  width: 100%; height: 100%;
  object-fit: cover;
  filter: brightness(0.4) saturate(0.6) contrast(1.18);
}
.hero::after {
  content: "";
  position: absolute; inset: 0;
  background:
    radial-gradient(ellipse at 50% 45%, transparent 20%, rgba(0,0,0,0.55) 78%),
    linear-gradient(to bottom, rgba(0,0,0,0.55) 0%, transparent 28%, transparent 55%, #000 100%);
  z-index: 1;
  pointer-events: none;
}
.hero-content {
  position: relative;
  z-index: 2;
  width: min(1000px, 92%);
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 26px;
}
.hero-content .eyebrow { justify-content: center; }
.hero-sub { color: var(--text-2); font-size: clamp(16.5px, 1.35vw, 20px); font-weight: 300; max-width: 64ch; }
.hero-ctas { display: flex; gap: 14px; flex-wrap: wrap; justify-content: center; }

.scroll-cue {
  position: absolute;
  bottom: 34px;
  inset-inline: 0;
  z-index: 3;
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  color: var(--text-3);
  font-size: 13px;
  font-family: var(--font-display);
  font-weight: 400;
}
.scroll-cue .line {
  width: 1px; height: 46px;
  background: linear-gradient(to bottom, rgba(255,255,255,0.5), transparent);
  animation: cueDrop 2.4s var(--ease-leo) infinite;
}
@keyframes cueDrop {
  0% { transform: scaleY(0); transform-origin: top; }
  50% { transform: scaleY(1); transform-origin: top; }
  51% { transform: scaleY(1); transform-origin: bottom; }
  100% { transform: scaleY(0); transform-origin: bottom; }
}

/* group ribbon above the hero headline */
.group-tag {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 8px 16px 8px 10px;
  border-radius: var(--r-pill);
  border: 1px solid rgba(255,255,255,0.16);
  background: rgba(255,255,255,0.05);
  backdrop-filter: blur(10px);
  color: var(--text-2);
  font-size: 13.5px;
  transition: all .4s var(--ease-leo);
}
[dir="rtl"] .group-tag { padding: 8px 10px 8px 16px; }
.group-tag:hover { border-color: rgba(243,112,33,0.5); background: rgba(243,112,33,0.10); color: #fff; }
.group-tag img { height: 13px; width: auto; filter: brightness(0) invert(1); opacity: .9; }
.group-tag .gt-sep { width: 1px; height: 15px; background: rgba(255,255,255,0.22); }

@media (max-width: 560px) {
  .hero { padding: 140px 0 100px; }
  .group-tag { font-size: 12px; padding: 7px 13px; gap: 8px; }
  .group-tag img { height: 10px; }
  .group-tag .gt-sep { height: 12px; }
  .hero .display-1 { font-size: clamp(34px, 9vw, 46px); }
  .hero-ctas { width: 100%; flex-direction: column; align-items: stretch; }
  .hero-ctas .btn { justify-content: center; }
}

/* ============================================================
   Sub-page hero
   ============================================================ */
.subpage-hero {
  position: relative;
  padding: 210px 0 110px;
  overflow: hidden;
  background: var(--bg);
}
/* A page header with no film gets the same drawn horizon as the home
   hero, at a smaller scale - so the site never depends on footage. */
.subpage-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(50% 22% at 50% 100%, rgba(255,214,166,0.14) 0%, transparent 72%),
    radial-gradient(120% 52% at 50% 104%, rgba(243,112,33,0.28) 0%, rgba(243,112,33,0.06) 44%, transparent 74%);
}
.subpage-hero:not(.has-media)::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  height: 1px;
  background: linear-gradient(to right, transparent, rgba(255,178,107,0.35) 26%, rgba(255,214,166,0.5) 50%, rgba(255,178,107,0.35) 74%, transparent);
  pointer-events: none;
}
.subpage-hero.has-media::before { display: none; }
.subpage-hero .container { position: relative; z-index: 1; }
.subpage-hero-grid { display: grid; grid-template-columns: 1.15fr .85fr; gap: 60px; align-items: center; }
@media (max-width: 900px) { .subpage-hero-grid { grid-template-columns: 1fr; } }
.subpage-hero .display-1 { margin: 22px 0; font-size: clamp(38px, 5.4vw, 80px); }

.page-hero-media { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
.page-hero-media video, .page-hero-media img {
  width: 100%; height: 100%; object-fit: cover;
  filter: brightness(0.42) saturate(0.7) contrast(1.1);
}
/* two scrims: one down the page so the header clears, one across the
   reading side so a bright frame never swallows the headline */
.page-hero-media::after {
  content: "";
  position: absolute; inset: 0;
  background:
    linear-gradient(to right, rgba(0,0,0,0.86) 0%, rgba(0,0,0,0.62) 42%, rgba(0,0,0,0.25) 78%),
    linear-gradient(to bottom, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0.35) 40%, #000 100%);
}
[dir="rtl"] .page-hero-media::after {
  background:
    linear-gradient(to left, rgba(0,0,0,0.86) 0%, rgba(0,0,0,0.62) 42%, rgba(0,0,0,0.25) 78%),
    linear-gradient(to bottom, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0.35) 40%, #000 100%);
}
.subpage-hero.has-media { padding: 250px 0 130px; }
.subpage-hero.has-media .subpage-hero-grid { grid-template-columns: 1fr; max-width: 880px; }

.brand-logo-large { height: 40px; width: auto; margin-bottom: 22px; display: block; }

.breadcrumbs {
  display: flex; align-items: center; gap: 9px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 14px;
  color: var(--text-3); margin-bottom: 22px;
}
.breadcrumbs .sep { color: rgba(255,255,255,0.22); }
.breadcrumbs .crumb-here { color: var(--orange-bright); }
.breadcrumbs a:hover { color: var(--orange-bright); }

/* ============================================================
   Chips
   ============================================================ */
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  padding: 8px 16px;
  border-radius: var(--r-pill);
  border: 1px solid rgba(255,255,255,0.14);
  background: rgba(255,255,255,0.03);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 13.5px;
  color: var(--text-2);
  transition: all .35s var(--ease-leo);
}
.chip:hover { border-color: rgba(243,112,33,0.45); color: #fff; }

/* ============================================================
   Stats
   ============================================================ */
.stats-strip { padding: 84px 0; background: var(--card); border-block: 1px solid var(--line); }
.stats-strip .grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; }
@media (max-width: 860px) { .stats-strip .grid { grid-template-columns: repeat(2, 1fr); gap: 40px 24px; } }
.stat { text-align: center; }
.stat .num {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(40px, 4.4vw, 58px);
  line-height: 1;
  letter-spacing: -0.02em;
  background: linear-gradient(135deg, var(--orange), var(--orange-bright));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.stat .label { color: var(--text-3); font-size: 14.5px; margin-top: 14px; line-height: 1.55; }

/* ============================================================
   Section head
   ============================================================ */
.section-head { max-width: 780px; }
.section-head .display-2 { margin-top: 22px; }
.section-head .lede { margin-top: 24px; }
.section-head.center { margin-inline: auto; text-align: center; }
.section-head.center .lede { margin-inline: auto; }
.section-head.center .eyebrow { justify-content: center; }

/* ============================================================
   Service rail - numbered rows
   ============================================================ */
.service-rail { margin-top: 64px; border-top: 1px solid var(--line); }
.service-row {
  position: relative;
  display: grid;
  grid-template-columns: auto auto 1fr auto;
  align-items: center;
  gap: 28px;
  padding: 32px 20px;
  border-bottom: 1px solid var(--line);
  transition: all .5s var(--ease-leo);
}
.service-row::before {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(to right, rgba(243,112,33,0.08), transparent 62%);
  opacity: 0;
  transition: opacity .5s var(--ease-leo);
  pointer-events: none;
}
[dir="rtl"] .service-row::before { background: linear-gradient(to left, rgba(243,112,33,0.08), transparent 62%); }
.service-row:hover::before { opacity: 1; }
.service-row .idx {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 14px;
  color: var(--text-3);
  min-width: 30px;
  transition: color .4s var(--ease-leo);
}
.service-row:hover .idx { color: var(--orange-bright); }
.service-row .sr-tile {
  width: 78px; height: 78px;
  border-radius: 18px;
  overflow: hidden;
  flex-shrink: 0;
  border: 1px solid var(--line);
  background: var(--card-2);
  transition: transform .5s var(--ease-leo);
}
.service-row .sr-tile img { width: 100%; height: 100%; object-fit: cover; }
.service-row:hover .sr-tile { transform: translateY(-4px) scale(1.04); }
.service-row h3 { font-family: var(--font-display); font-size: clamp(20px, 2vw, 27px); font-weight: 400; color: var(--text-1); margin-bottom: 8px; }
.service-row p { color: var(--text-3); font-size: 15.5px; line-height: 1.7; max-width: 66ch; }
.service-row .sr-go {
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--orange-bright);
  font-family: var(--font-display); font-weight: 500; font-size: 15px;
  white-space: nowrap;
  opacity: .75;
  transition: all .4s var(--ease-leo);
}
.service-row:hover .sr-go { opacity: 1; gap: 12px; }
.service-row .sr-go svg { width: 16px; height: 16px; }
[dir="rtl"] .service-row .sr-go svg { transform: scaleX(-1); }
@media (max-width: 860px) {
  .service-row { grid-template-columns: auto auto 1fr; gap: 16px; padding: 26px 8px; }
  .service-row .sr-tile { width: 58px; height: 58px; border-radius: 14px; }
  .service-row .sr-go { grid-column: 1 / -1; }
}
@media (max-width: 560px) {
  .service-row { grid-template-columns: auto 1fr; }
  .service-row .sr-tile { display: none; }
}
.rail-cta {
  margin-top: 46px;
  display: flex; align-items: center; justify-content: space-between;
  gap: 24px; flex-wrap: wrap;
}
.rail-cta p { color: var(--text-3); font-size: 17px; font-weight: 300; }

/* ============================================================
   Feature / why cards
   ============================================================ */
.feature-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; margin-top: 64px; }
@media (max-width: 900px) { .feature-grid { grid-template-columns: 1fr; } }
.feature-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 34px 32px 38px;
  transition: all .5s var(--ease-leo);
}
.feature-card:hover { transform: translateY(-6px); border-color: rgba(243,112,33,0.3); }
.feature-card h3 { font-family: var(--font-display); font-size: 21px; font-weight: 500; margin: 22px 0 12px; color: var(--text-1); }
.feature-card p { color: var(--text-3); font-size: 15.5px; line-height: 1.75; }
.icon-wrap {
  width: 50px; height: 50px;
  border-radius: 14px;
  background: linear-gradient(135deg, var(--orange-bright), var(--orange));
  display: flex; align-items: center; justify-content: center;
  color: #fff;
}
.icon-wrap svg { width: 23px; height: 23px; }

.pillar-tile {
  width: 62px; height: 62px;
  border-radius: 16px;
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--card-2);
}
.pillar-tile img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--ease-leo); }
.feature-card:hover .pillar-tile img { transform: scale(1.08); }

/* ============================================================
   Media band - full-bleed film with content
   ============================================================ */
.media-band-wrap { padding: 0; }
/* The band runs the full width of the page. Inside a rounded 1320px card the
   film was cropped twice over - once by the card, once by the -6% overscan -
   and it read as a still photograph someone had trimmed. Full-bleed at the
   film's own 16:9 means the frame plays whole on a desktop screen, and the
   only crop left is the one the aspect ratio forces on a narrow phone. */
.media-band {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  min-height: 620px;
  max-height: 88vh;
  display: flex;
  align-items: center;
  overflow: hidden;
  border-radius: 0;
}
.band-media { position: absolute; inset: 0; z-index: 0; }
.band-media video, .band-media img {
  width: 100%; height: 100%; object-fit: cover;
  filter: brightness(0.55) saturate(0.8) contrast(1.1);
  /* the film dissolves into the page instead of ending on a cut edge */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 13%, #000 84%, transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0%, #000 13%, #000 84%, transparent 100%);
}
.media-band::after {
  content: "";
  position: absolute; inset: 0; z-index: 1;
  background:
    linear-gradient(to right, rgba(0,0,0,0.84) 0%, rgba(0,0,0,0.48) 46%, transparent 82%),
    linear-gradient(to bottom, rgba(0,0,0,0.5) 0%, transparent 22%, transparent 74%, rgba(0,0,0,0.72) 100%);
  pointer-events: none;
}
[dir="rtl"] .media-band::after {
  background:
    linear-gradient(to left, rgba(0,0,0,0.84) 0%, rgba(0,0,0,0.48) 46%, transparent 82%),
    linear-gradient(to bottom, rgba(0,0,0,0.5) 0%, transparent 22%, transparent 74%, rgba(0,0,0,0.72) 100%);
}
/* the copy keeps the page's own column so it lines up with every other
   section, even though the film behind it no longer does */
.media-band-content {
  position: relative; z-index: 2;
  width: min(1320px, 92%);
  margin-inline: auto;
  padding: 0;
  display: flex; flex-direction: column; gap: 20px;
  align-items: flex-start;
}
.media-band-content > * { max-width: 640px; }
.media-band-content h2 {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(32px, 4vw, 58px);
  line-height: 1.1;
  color: #fff;
}
.media-band-content p { color: var(--text-2); font-weight: 300; line-height: 1.75; font-size: 16.5px; }
@media (max-width: 768px) {
  .media-band { min-height: 560px; max-height: none; }
  .media-band-content { padding: 0; }
}

.starlink-badge {
  display: inline-flex; align-items: center; gap: 12px;
  padding: 9px 18px;
  border-radius: var(--r-pill);
  border: 1px solid rgba(255,255,255,0.22);
  background: rgba(255,255,255,0.07);
  backdrop-filter: blur(10px);
  color: #fff; font-size: 13.5px;
}
.starlink-badge .sl-logo { height: 20px; width: auto; display: block; }
.starlink-badge .sl-sep { width: 1px; height: 20px; background: rgba(255,255,255,0.35); }

/* ============================================================
   Client logo marquee
   ============================================================ */
.logo-strip { padding: 96px 0; overflow: hidden; background: var(--bg); }
.logo-strip-head { text-align: center; margin-bottom: 52px; }
.logo-strip-title {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(26px, 3vw, 40px);
  color: var(--text-1);
  margin-top: 18px;
}
.logo-strip-head .eyebrow { justify-content: center; }
.logo-marquee-wrap {
  position: relative;
  direction: ltr;              /* the loop is physical motion - never flip it */
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 9%, #000 91%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 9%, #000 91%, transparent);
}
.logo-marquee-wrap * { direction: ltr; }
.logo-marquee { display: flex; width: max-content; animation: marquee 62s linear infinite; }
.logo-marquee.rev { animation-direction: reverse; animation-duration: 74s; margin-top: 26px; }
.logo-marquee-wrap:hover .logo-marquee { animation-play-state: paused; }
@keyframes marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.logo-track { display: flex; align-items: center; gap: 56px; padding-inline: 28px; }
.logo-track img {
  height: 38px;
  width: auto;
  object-fit: contain;
}

/* ============================================================
   Partner wall - gradient frames
   ============================================================ */
.partners-logo-grid {
  --logo-cols: 4;
  display: grid;
  grid-template-columns: repeat(var(--logo-cols), 1fr);
  gap: 18px;
  margin-top: 56px;
}
@media (max-width: 1180px) { .partners-logo-grid { --logo-cols: 3; } }
@media (max-width: 760px)  {
  .partners-logo-grid { --logo-cols: 2; }
  /* At two columns the cell is 135px of usable width, and a 8.6:1
     wordmark can only ever be 16px tall inside it. Nothing gives a wide
     mark more area there, so the square ones come down to meet it -
     otherwise Cisco covers half its cell and Fortinet a seventh. */
  .partners-logo-grid { --lh-scale: 0.62; }
}

.partner-logo-cell {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: var(--card);
  display: flex; align-items: center; justify-content: center;
  /* the cell halves in width on a phone; a fixed 26px inset left the
     mark almost no room inside it */
  padding: clamp(13px, 8%, 26px);
  overflow: hidden;
  transition: all .5s var(--ease-leo);
}

.partner-logo-cell:hover { transform: translateY(-5px); border-color: rgba(255,255,255,0.2); background: var(--card-2); }
/* --lh is written per logo by build/blocks.js from the mark's own
   proportions, so every mark covers the same optical area whatever its
   shape. min(...,100%) keeps a tall mark inside the cell once the grid
   drops to two columns and the cell is wider than it is high. */
.partner-logo-cell img {
  max-height: min(calc(var(--lh, 46px) * var(--lh-scale, 1)), 100%);
  max-width: 100%;
  width: auto;
  object-fit: contain;
}

/* ============================================================
   Vendor rows (service detail pages)
   ============================================================ */
.vendor-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; margin-top: 56px; }
@media (max-width: 900px) { .vendor-grid { grid-template-columns: 1fr; } }
.vendor-card {
  display: grid;
  grid-template-columns: 128px 1fr;
  align-items: center;
  gap: 26px;
  padding: 26px 30px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--card);
  transition: all .5s var(--ease-leo);
}
.vendor-card:hover { transform: translateY(-5px); border-color: rgba(243,112,33,0.32); background: var(--card-2); }
.vendor-card .v-logo {
  height: 48px;
  display: flex; align-items: center; justify-content: center;
}
/* the same derived cap as the wall, scaled to this smaller band */
.vendor-card .v-logo img {
  max-height: min(calc(var(--lh, 46px) * 0.62), 100%);
  max-width: 150px;
  width: auto;
  object-fit: contain;
}
.vendor-card p { color: var(--text-3); font-size: 14.8px; line-height: 1.7; }
@media (max-width: 560px) {
  .vendor-card { grid-template-columns: 1fr; gap: 16px; }
  .vendor-card .v-logo { justify-content: flex-start; }
}

/* ============================================================
   Split feature (why-us quad)
   ============================================================ */
.split-grid { display: grid; grid-template-columns: 0.9fr 1.1fr; gap: 64px; align-items: center; }
@media (max-width: 900px) { .split-grid { grid-template-columns: 1fr; gap: 48px; } }
.quad { display: grid; grid-template-columns: 1fr 1fr; gap: 30px 26px; }
@media (max-width: 520px) { .quad { grid-template-columns: 1fr; } }
.quad h3, .quad h4 { font-family: var(--font-display); font-size: 19px; font-weight: 500; margin: 18px 0 8px; color: var(--text-1); }
.quad p { color: var(--muted); font-size: 14.5px; line-height: 1.65; }

/* ============================================================
   FAQ
   ============================================================ */
.faq-grid { display: grid; grid-template-columns: .8fr 1.2fr; gap: 60px; align-items: start; }
@media (max-width: 900px) { .faq-grid { grid-template-columns: 1fr; gap: 40px; } }
.faq-list { display: grid; gap: 0; border-top: 1px solid var(--line); }
.faq-item {
  border-bottom: 1px solid var(--line);
  padding: 24px 18px;
  transition: background .4s var(--ease-leo);
}
.faq-item:hover { background: linear-gradient(to right, rgba(243,112,33,0.06), transparent 60%); }
[dir="rtl"] .faq-item:hover { background: linear-gradient(to left, rgba(243,112,33,0.06), transparent 60%); }
.faq-item summary {
  font-family: var(--font-display);
  font-size: 17.5px;
  font-weight: 400;
  color: var(--text-1);
  cursor: pointer;
  list-style: none;
  display: flex; align-items: center; justify-content: space-between; gap: 18px;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
  content: "+";
  font-weight: 300;
  font-size: 24px;
  color: var(--orange-bright);
  transition: transform .4s var(--ease-leo);
  line-height: 1;
}
.faq-item[open] summary::after { transform: rotate(45deg); }
.faq-item .answer { color: var(--text-3); font-size: 15.5px; line-height: 1.75; margin-top: 14px; max-width: 70ch; }

.faq-cats { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 44px; }
.filter-btn {
  padding: 10px 20px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  color: var(--text-3);
  font-family: var(--font-display);
  font-size: 14.5px;
  font-weight: 500;
  transition: all .35s var(--ease-leo);
}
.filter-btn:hover { color: #fff; border-color: rgba(255,255,255,0.35); }
.filter-btn.active { background: linear-gradient(135deg, var(--orange), var(--orange-bright)); color: #fff; border-color: transparent; }

/* ============================================================
   News cards
   ============================================================ */
.blog-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; margin-top: 60px; }
@media (max-width: 900px) { .blog-grid { grid-template-columns: 1fr; } }
.blog-card {
  display: flex; flex-direction: column;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  transition: all .5s var(--ease-leo);
}
.blog-card:hover { transform: translateY(-6px); border-color: rgba(243,112,33,0.3); }
.blog-card .thumb {
  aspect-ratio: 16/9;
  overflow: hidden;
  background: radial-gradient(120% 100% at 50% 0%, rgba(243,112,33,0.14), transparent 62%), var(--card-2);
  display: flex; align-items: center; justify-content: center;
  padding: 34px;
}
.blog-card .thumb img { max-height: 54px; max-width: 62%; width: auto; object-fit: contain; }
.blog-card:hover .thumb img { transform: scale(1.06); }
.blog-card .body { padding: 26px 28px 30px; display: flex; flex-direction: column; gap: 12px; flex: 1; }
.blog-card .meta { display: flex; gap: 8px; font-size: 13.5px; color: var(--text-3); }
.blog-card h3 { font-family: var(--font-display); font-size: 19px; font-weight: 500; line-height: 1.4; color: var(--text-1); }
.blog-card p { color: var(--text-3); font-size: 14.5px; line-height: 1.65; flex: 1; }
.read-more { display: inline-flex; align-items: center; gap: 8px; color: var(--orange-bright); font-family: var(--font-display); font-weight: 500; font-size: 15px; }
.read-more svg { width: 15px; height: 15px; }
[dir="rtl"] .read-more svg { transform: scaleX(-1); }

/* ============================================================
   Jobs
   ============================================================ */
.jobs-list { margin-top: 56px; border-top: 1px solid var(--line); }
.job-row {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 28px;
  padding: 30px 20px;
  border-bottom: 1px solid var(--line);
  transition: background .5s var(--ease-leo);
}
.job-row:hover { background: rgba(243,112,33,0.05); }
.job-row .idx { font-family: var(--font-display); font-weight: 400; font-size: 14px; color: var(--text-3); min-width: 30px; }
.job-row h3 { font-family: var(--font-display); font-size: 21px; font-weight: 400; color: var(--text-1); margin-bottom: 6px; }
.job-row p { color: var(--text-3); font-size: 15px; }
@media (max-width: 760px) {
  .job-row { grid-template-columns: auto 1fr; gap: 16px; padding: 24px 6px; }
  .job-row .btn { grid-column: 2; justify-self: start; }
}

/* ============================================================
   CTA banner
   ============================================================ */
.cta-banner {
  display: grid;
  grid-template-columns: 1.1fr .9fr;
  gap: 56px;
  align-items: center;
  background:
    radial-gradient(90% 130% at 0% 0%, rgba(243,112,33,0.18) 0%, transparent 58%),
    var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  padding: 64px 60px;
}
@media (max-width: 900px) { .cta-banner { grid-template-columns: 1fr; padding: 44px 30px; gap: 36px; } }
.cta-banner h2 { color: #fff; }
.cta-banner p { color: var(--text-2); margin: 20px 0 28px; max-width: 48ch; font-weight: 300; }

/* Visually hidden, still announced. Not display:none and not
   visibility:hidden - both of those take the element out of the
   accessibility tree, which is the opposite of what a hidden label is
   for. Absolute, so it takes no cell in the form's grid. */
.sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

.cta-form { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.cta-form .full { grid-column: 1 / -1; }
.cta-form input, .cta-form textarea, .cta-form select {
  width: 100%;
  padding: 14px 18px;
  border-radius: 14px;
  border: 1px solid rgba(255,255,255,0.14);
  background: rgba(255,255,255,0.05);
  color: #fff;
  font-family: inherit;
  font-size: 15px;
  transition: all .35s var(--ease-leo);
}
.cta-form textarea { min-height: 110px; resize: vertical; }
.cta-form input::placeholder, .cta-form textarea::placeholder { color: rgba(255,255,255,0.42); }
.cta-form input:focus, .cta-form textarea:focus, .cta-form select:focus {
  outline: none;
  border-color: rgba(243,112,33,0.6);
  background: rgba(243,112,33,0.07);
}
.cta-form button { grid-column: 1 / -1; justify-content: center; }
@media (max-width: 560px) { .cta-form { grid-template-columns: 1fr; } }

/* ============================================================
   Contact
   ============================================================ */
.contact-grid { display: grid; grid-template-columns: .9fr 1.1fr; gap: 56px; align-items: start; }
@media (max-width: 900px) { .contact-grid { grid-template-columns: 1fr; } }
.contact-pill {
  display: flex; align-items: center; gap: 16px;
  padding: 18px 22px;
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: var(--card);
  transition: all .4s var(--ease-leo);
}
.contact-pill:hover { border-color: rgba(243,112,33,0.35); transform: translateY(-3px); }
.contact-pill .icon {
  width: 44px; height: 44px; flex-shrink: 0;
  border-radius: 13px;
  background: linear-gradient(135deg, var(--orange-bright), var(--orange));
  display: flex; align-items: center; justify-content: center;
  color: #fff;
}
.contact-pill .icon svg { width: 20px; height: 20px; }
.contact-pill .ct-label { display: block; font-size: 13.5px; color: var(--text-3); }
.contact-pill .ct-val { display: block; color: var(--text-1); font-family: var(--font-display); font-size: 17px; font-weight: 400; margin-top: 3px; }
.map-card { border-radius: var(--r-lg); overflow: hidden; border: 1px solid var(--line); margin-top: 24px; }
.map-card iframe { width: 100%; height: 300px; border: 0; display: block; filter: grayscale(1) invert(0.92) contrast(0.85); }

/* ============================================================
   Footer
   ============================================================ */
.site-footer { background: #050403; border-top: 1px solid var(--line); padding: 84px 0 34px; }
.footer-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: 44px; }
@media (max-width: 900px) { .footer-grid { grid-template-columns: 1fr 1fr; gap: 40px 24px; } }
@media (max-width: 560px) { .footer-grid { grid-template-columns: 1fr; } }
.footer-brand img { height: 38px; width: auto; }
.footer-brand p { margin-top: 18px; color: #5C5C66; font-size: 15px; max-width: 36ch; line-height: 1.7; }
.site-footer h3, .site-footer h4 { font-family: var(--font-display); font-size: 17px; font-weight: 500; color: var(--text-1); letter-spacing: -0.005em; margin-bottom: 20px; }
.site-footer ul { list-style: none; display: flex; flex-direction: column; gap: 11px; }
.site-footer ul a, .site-footer ul li { color: #5C5C66; font-size: 15px; }
.site-footer ul a:hover { color: var(--orange-bright); }
.socials { display: flex; gap: 10px; margin-top: 24px; }
.socials a {
  width: 38px; height: 38px;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,0.12);
  display: flex; align-items: center; justify-content: center;
  color: #5C5C66;
  transition: all .4s var(--ease-leo);
}
.socials a:hover { background: var(--orange); color: #fff; border-color: transparent; }

/* the group ribbon in the footer */
.footer-group {
  margin-top: 56px;
  padding: 26px 30px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: radial-gradient(90% 140% at 0% 0%, rgba(243,112,33,0.10) 0%, transparent 60%), var(--card);
  display: flex; align-items: center; justify-content: space-between;
  gap: 22px; flex-wrap: wrap;
}
.footer-group .fg-text { color: var(--text-3); font-size: 15px; }
.footer-group .fg-brands { display: flex; align-items: center; gap: 26px; flex-wrap: wrap; }
.footer-group .fg-brands img { height: 19px; width: auto; }

.footer-bottom {
  margin-top: 44px;
  padding-top: 26px;
  border-top: 1px solid var(--line);
  display: flex; justify-content: space-between; gap: 20px; flex-wrap: wrap;
  color: #46464E; font-size: 14px;
}
.footer-bottom a:hover { color: var(--orange-bright); }

/* The legal row on a phone.

   It was a space-between pair that wrapped once it ran out of width, so
   whether the links landed under the copyright or out at the opposite
   edge depended on how wide the copyright string happened to render -
   and Hebrew and English disagree about that, as do two phones with
   different font fallbacks. With three links here rather than two it
   runs out sooner.

   Below the width where the footer's columns stack, this stacks too:
   one column, both lines starting at the same reading edge the rest of
   the footer already uses, and spacing set once instead of being
   whatever the tap padding adds to the gap. */
/* The legal links row.

   This used to carry style="display:flex; gap:24px" inline on every page.
   An inline declaration outranks any selector, so the stylesheet's attempt
   to tighten the gap on a phone was inert - the rule looked live, and half
   of it (flex-wrap) took effect while the other half silently did not.
   The row is a class now, and the base has to sit ABOVE the media query
   that narrows it: same specificity means source order decides. */
.footer-legal { display: flex; gap: 24px; }

@media (max-width: 560px) {
  .footer-bottom {
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    row-gap: 0;
  }
  .footer-bottom > :first-child { margin-bottom: 3px; }
  .footer-legal { gap: 20px; flex-wrap: wrap; }
}

/* ============================================================
   Misc
   ============================================================ */
.dark-section { background: var(--bg); }
.card-section { background: var(--card); }

.testimonial-card {
  position: relative;
  max-width: 860px;
  margin-inline: auto;
  text-align: center;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  padding: 64px 56px 54px;
}
.testimonial-card .stars { display: flex; justify-content: center; gap: 5px; color: var(--orange-bright); margin-bottom: 26px; }
.testimonial-card .quote { font-family: var(--font-display); font-weight: 300; font-size: clamp(19px, 2vw, 27px); line-height: 1.55; color: var(--text-1); }
.testimonial-card .who { display: flex; align-items: center; justify-content: center; gap: 14px; margin-top: 34px; }
.testimonial-card .name { color: var(--text-1); font-weight: 500; font-family: var(--font-display); }
.testimonial-card .role { color: var(--text-3); font-size: 14px; }
@media (max-width: 640px) { .testimonial-card { padding: 44px 26px 40px; } }

/* skip link */
.skip-link {
  position: absolute;
  inset-inline-start: -9999px;
  top: 0;
  z-index: 1000;
  background: #fff; color: #000;
  padding: 12px 20px; border-radius: 0 0 12px 0;
}
.skip-link:focus { inset-inline-start: 0; }

:focus-visible { outline: 2px solid var(--orange-bright); outline-offset: 3px; border-radius: 4px; }

/* ============================================================
   INSTRUMENTATION LAYER
   The parts that make the site read as an engineering company:
   a live network canvas, pointer-lit surfaces, fiber hairlines,
   scroll-drawn routes and monospace readouts.
   ============================================================ */

/* ---- film grain -------------------------------------------
   A single fixed layer at very low opacity. Kills the flatness
   of large black areas and stops gradients from banding.       */
.grain {
  position: fixed;
  inset: -50%;
  z-index: 1;
  pointer-events: none;
  opacity: 0.035;
  background-image: var(--grain-src);
  background-size: 180px 180px;
  will-change: transform;
  animation: grainShift 6s steps(6) infinite;
}
@keyframes grainShift {
  0%   { transform: translate(0, 0); }
  16%  { transform: translate(-2%, -3%); }
  33%  { transform: translate(3%, 1%); }
  50%  { transform: translate(-1%, 2%); }
  66%  { transform: translate(2%, -2%); }
  83%  { transform: translate(-3%, 1%); }
  100% { transform: translate(0, 0); }
}

/* ---- hero network canvas ----------------------------------
   Nodes and links drawn over the film, with packets running the
   edges. Sits under the copy, above the video.                 */
.scene-canvas {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0;
  transition: opacity 2.2s var(--ease-leo) .25s;
}
.scene-canvas.lit { opacity: 1; }
.subpage-hero .scene-canvas { opacity: 0; }
.subpage-hero .scene-canvas.lit { opacity: .85; }
.hero .hero-content { z-index: 3; }
.hero::after { z-index: 2; }

/* ---- pointer-lit surfaces ---------------------------------
   Each card writes its own --mx/--my, so the highlight tracks
   the cursor across the surface rather than the whole page.    */
.lit-surface { position: relative; isolation: isolate; }
.lit-surface::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: radial-gradient(340px circle at var(--mx) var(--my), rgba(243,112,33,0.13), transparent 62%);
  opacity: 0;
  transition: opacity .55s var(--ease-leo);
  pointer-events: none;
  z-index: 0;
}
.lit-surface:hover::before { opacity: 1; }
.lit-surface > * { position: relative; z-index: 1; }

/* the border catches the light too - a hairline that brightens
   only where the cursor is */
.lit-edge::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: radial-gradient(260px circle at var(--mx) var(--my), rgba(255,178,107,0.65), transparent 60%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  opacity: 0;
  transition: opacity .55s var(--ease-leo);
  pointer-events: none;
  z-index: 2;
}
.lit-edge:hover::after { opacity: 1; }

/* ---- fiber hairline ---------------------------------------
   A section divider with a light packet running down it.       */
.fiber-rule {
  position: relative;
  height: 1px;
  background: var(--line-soft);
  overflow: hidden;
}
.fiber-rule::after {
  content: "";
  position: absolute;
  top: 0;
  inset-inline-start: -22%;
  width: 22%;
  height: 100%;
  background: linear-gradient(to right, transparent, var(--orange-bright), transparent);
  animation: fiberRun 5.5s linear infinite;
}
[dir="rtl"] .fiber-rule::after { animation-name: fiberRunRtl; }
@keyframes fiberRun { to { transform: translateX(555%); } }
@keyframes fiberRunRtl { to { transform: translateX(-555%); } }

/* ---- scroll-drawn route -----------------------------------
   An SVG spine down a section that draws itself as you pass.   */
.route {
  position: absolute;
  inset-block: 0;
  inset-inline-start: 50%;
  width: 2px;
  transform: translateX(-50%);
  pointer-events: none;
  z-index: 0;
}
.route svg { width: 100%; height: 100%; overflow: visible; }
/* the stroke is a per-instance gradient set on the element itself */
.route path {
  fill: none;
  stroke-width: 1;
  stroke-dasharray: var(--len);
  stroke-dashoffset: var(--len);
  vector-effect: non-scaling-stroke;
}
@media (max-width: 1180px) { .route { display: none; } }

/* ---- monospace readout ------------------------------------ */
.readout {
  font-family: var(--font-display);
  font-size: 13.5px;
  color: var(--text-3);
}
.readout .val { color: var(--orange-bright); }

/* ---- the NOC panel ----------------------------------------
   A signal trace with monospace annotations. It is a drawing of
   what the operations centre watches, not a live feed.         */
.noc-panel {
  position: relative;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background:
    linear-gradient(rgba(255,255,255,0.018) 1px, transparent 1px) 0 0 / 100% 34px,
    linear-gradient(90deg, rgba(255,255,255,0.018) 1px, transparent 1px) 0 0 / 34px 100%,
    var(--card);
  overflow: hidden;
}
.noc-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  padding: 18px 24px;
  border-bottom: 1px solid var(--line-soft);
}
.noc-head .tag {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--font-display); font-size: 13.5px; color: var(--text-3);
}
.noc-head .tag .live {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--orange-bright);
  box-shadow: 0 0 0 0 rgba(255,138,61,0.6);
  animation: livePing 2.6s var(--ease-leo) infinite;
}
@keyframes livePing {
  0% { box-shadow: 0 0 0 0 rgba(255,138,61,0.55); }
  70%, 100% { box-shadow: 0 0 0 9px rgba(255,138,61,0); }
}
.noc-canvas { display: block; width: 100%; height: 190px; }
.noc-foot {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border-top: 1px solid var(--line-soft);
}
.noc-foot > div {
  padding: 20px 24px;
  border-inline-end: 1px solid var(--line-soft);
}
.noc-foot > div:last-child { border-inline-end: 0; }
.noc-foot .k {
  font-family: var(--font-display); font-size: 13.5px; color: var(--text-3);
}
.noc-foot .v {
  font-family: var(--font-display); font-weight: 300;
  font-size: 30px; line-height: 1.1; margin-top: 8px;
  color: var(--text-1); letter-spacing: -0.01em;
}
.noc-foot .v em { font-style: normal; color: var(--orange-bright); }
@media (max-width: 760px) {
  .noc-foot { grid-template-columns: 1fr 1fr; }
  .noc-foot > div:nth-child(2) { border-inline-end: 0; }
  .noc-foot > div:nth-child(-n+2) { border-bottom: 1px solid var(--line-soft); }
  .noc-canvas { height: 140px; }
}

/* ---- service row technical tag ----------------------------- */
.service-row .sr-spec { display: none; }

/* ---- magnetic buttons -------------------------------------- */
.btn.mag { will-change: transform; }

/* ---- decode-on-reveal for mono labels ---------------------- */
.decode { white-space: pre-wrap; }

/* ---- hairline grid backdrop -------------------------------- */
.grid-bg::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, rgba(255,255,255,0.02) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255,255,255,0.02) 1px, transparent 1px);
  background-size: 148px 148px;
  -webkit-mask-image: radial-gradient(ellipse 62% 48% at 50% 40%, #000 0%, transparent 72%);
  mask-image: radial-gradient(ellipse 62% 48% at 50% 40%, #000 0%, transparent 72%);
  /* sits with the network canvas: over the film, under the scrim */
  z-index: 1;
}

/* ---- reduced motion ---------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .grain, .eyebrow::before, .fiber-rule::after, .noc-head .tag .live { animation: none; }
  .net-canvas { opacity: .5; transition: none; }
  .route path { stroke-dashoffset: 0 !important; }
}

/* ---- staggered reveals ------------------------------------
   Grids come in cell by cell rather than as one block, so the
   eye tracks across the wall instead of being handed all of it. */
.partners-logo-grid .reveal:nth-child(1)  { transition-delay: .00s; }
.partners-logo-grid .reveal:nth-child(2)  { transition-delay: .05s; }
.partners-logo-grid .reveal:nth-child(3)  { transition-delay: .10s; }
.partners-logo-grid .reveal:nth-child(4)  { transition-delay: .15s; }
.partners-logo-grid .reveal:nth-child(5)  { transition-delay: .08s; }
.partners-logo-grid .reveal:nth-child(6)  { transition-delay: .13s; }
.partners-logo-grid .reveal:nth-child(7)  { transition-delay: .18s; }
.partners-logo-grid .reveal:nth-child(8)  { transition-delay: .23s; }
.partners-logo-grid .reveal:nth-child(9)  { transition-delay: .16s; }
.partners-logo-grid .reveal:nth-child(10) { transition-delay: .21s; }
.partners-logo-grid .reveal:nth-child(11) { transition-delay: .26s; }
.partners-logo-grid .reveal:nth-child(12) { transition-delay: .31s; }
.partners-logo-grid .reveal:nth-child(n+13) { transition-delay: .3s; }

.service-rail .service-row:nth-child(1) { transition-delay: .00s; }
.service-rail .service-row:nth-child(2) { transition-delay: .06s; }
.service-rail .service-row:nth-child(3) { transition-delay: .12s; }
.service-rail .service-row:nth-child(4) { transition-delay: .18s; }
.service-rail .service-row:nth-child(n+5) { transition-delay: .24s; }

/* ---- section seams ----------------------------------------
   Instead of a hard colour change between sections, a lit
   hairline the packets run along.                             */
.seam {
  position: relative;
  height: 1px;
  margin: 0;
  background: linear-gradient(to right, transparent, var(--line), transparent);
  overflow: hidden;
}
.seam::after {
  content: "";
  position: absolute;
  top: 0;
  inset-inline-start: 0;
  width: 18%;
  height: 100%;
  background: linear-gradient(to right, transparent, var(--orange-bright), transparent);
  opacity: .8;
  animation: seamRun 9s linear infinite;
}
@keyframes seamRun {
  0%   { transform: translateX(-120%); }
  100% { transform: translateX(680%); }
}
[dir="rtl"] .seam::after { animation-name: seamRunRtl; }
@keyframes seamRunRtl {
  0%   { transform: translateX(120%); }
  100% { transform: translateX(-680%); }
}
@media (prefers-reduced-motion: reduce) { .seam::after { animation: none; opacity: 0; } }

/* ---- cursor ------------------------------------------------
   Two parts moving at different rates: a dot that keeps up with
   the pointer, and a frame that lags behind it. Over anything
   interactive the frame stops following the pointer and takes the
   shape of the element instead - so the page appears to
   acknowledge what you are about to click.
   ------------------------------------------------------------ */
.cur-dot, .cur-frame {
  position: fixed;
  top: 0; left: 0;
  pointer-events: none;
  z-index: 9999;
  opacity: 0;
  transition: opacity .35s var(--ease-leo);
  will-change: transform;
}
.cur-dot {
  width: 5px; height: 5px;
  margin: -2.5px 0 0 -2.5px;
  border-radius: 50%;
  background: rgba(255,255,255,0.85);
}
.cur-frame {
  width: 34px; height: 34px;
  margin: -17px 0 0 -17px;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,0.28);
  transition: opacity .35s var(--ease-leo),
              width .5s var(--ease-leo), height .5s var(--ease-leo),
              margin .5s var(--ease-leo), border-radius .5s var(--ease-leo),
              border-color .5s var(--ease-leo), background-color .5s var(--ease-leo);
}
.cur-on .cur-dot, .cur-on .cur-frame { opacity: 1; }

/* locked on to a target: the frame becomes the target's outline */
.cur-frame.locked {
  border-color: rgba(255,178,107,0.55);
  background: rgba(243,112,33,0.05);
}
.cur-lock-dot .cur-dot { opacity: 0; }
.cur-press .cur-frame { border-color: rgba(255,178,107,0.9); }

@media (hover: none), (prefers-reduced-motion: reduce) {
  .cur-dot, .cur-frame { display: none; }
}

/* ---- page transition ---------------------------------------
   A short black wipe between pages, so a static multi-page site
   moves like one application.                                  */
.page-veil {
  position: fixed;
  inset: 0;
  z-index: 9998;
  background: #000;
  pointer-events: none;
  opacity: 1;
  transition: opacity .5s var(--ease-leo);
}
.page-veil.clear { opacity: 0; }
.page-veil.leaving { opacity: 1; transition-duration: .26s; }
@media (prefers-reduced-motion: reduce) { .page-veil { display: none; } }


/* ============================================================
   Icon marks
   One drawn set, framed the same way everywhere. Restrained by
   default; the accent element lights when the card is engaged.
   ============================================================ */
.ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 62px; height: 62px;
  flex-shrink: 0;
  border-radius: 17px;
  border: 1px solid rgba(255,255,255,0.10);
  background: linear-gradient(160deg, rgba(255,255,255,0.055), rgba(255,255,255,0.012));
  color: rgba(255,255,255,0.82);
  transition: border-color .5s var(--ease-leo), background .5s var(--ease-leo), color .5s var(--ease-leo);
}
.ico svg { width: 30px; height: 30px; display: block; }
.ico .ic-hot { color: var(--orange-bright); stroke: var(--orange-bright); transition: opacity .5s var(--ease-leo); }

.feature-card:hover .ico,
.service-row:hover .ico,
.quad-item:hover .ico {
  border-color: rgba(255,255,255,0.2);
  background: linear-gradient(160deg, rgba(255,255,255,0.09), rgba(255,255,255,0.02));
  color: #fff;
}

/* larger mark for the service rail */
.service-row .ico { width: 68px; height: 68px; border-radius: 19px; }
.service-row .ico svg { width: 33px; height: 33px; }
@media (max-width: 860px) {
  .service-row .ico { width: 54px; height: 54px; border-radius: 15px; }
  .service-row .ico svg { width: 27px; height: 27px; }
}

/* small mark, used inside prose columns */
.ico.sm { width: 50px; height: 50px; border-radius: 14px; }
.ico.sm svg { width: 25px; height: 25px; }

/* the old orange square and photo tile are retired */
.icon-wrap, .pillar-tile, .sr-tile { display: none !important; }

/* ============================================================
   Phone numbers keep Latin order inside Hebrew text
   ============================================================ */
.ltr-num { direction: ltr; unicode-bidi: embed; display: inline-block; }


/* ============================================================
   Hero as a reel
   Three films that dissolve into one another - the racks, the hands
   at the gear, the office at night. The drawn network still runs over
   them, at half strength, so the third element is drawn rather than
   filmed and stays quiet. js/spotnet.js drives the cross-dissolve.
   ============================================================ */
.hero.hero-reel { background: var(--bg); }
.hero.hero-reel .hero-film { position: absolute; inset: 0; z-index: 0; opacity: .94; }
/* Which clip is showing is decided at runtime, as an inline opacity set
   by setupReel(). Until that happens nothing decided it at all: eight
   clips painted at full opacity, stacked, and the last one in the markup
   won - so the page opened on the reel's CLOSING shot. It was invisible
   while the clips had no poster, because eight blank rectangles stack to
   the same black; giving them stills is what made it show.

   Two visitors never get that inline value: one whose script has not run
   yet, and one who has asked for reduced motion, for whom the reel never
   starts at all. Both should see the opening shot, so the opening shot is
   the resting state. The inline value still wins once it lands, which is
   what lets the reel play. */
.hero.hero-reel .hero-film video { opacity: 0; }
.hero.hero-reel .hero-film video:first-of-type { opacity: 1; }

.hero.hero-reel .hero-film video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  /* The one grade every clip shares - this is what makes six separately
     generated shots read as one film.

     No contrast term here, deliberately. A contrast() above 1 pivots
     around mid-grey, so on footage this dark it drags the shadows below
     zero and clips them: measured on the page, brightness(.68) with
     contrast(1.14) rendered the aisle shot at a mean luminance of 4.8
     out of 255 and the NOC shot at 6.6 - it was both crushing the reel
     and pulling the clips apart again after they had been matched frame
     by frame at encode time. Brightness and saturation only; each clip
     was already balanced to the same luminance in ffmpeg. */
  filter: brightness(0.72) saturate(0.85);
}

/* the warm horizon stays, softened: the film carries the light now */
.hero.hero-reel .hero-glow {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    radial-gradient(58% 24% at 50% 100%, rgba(255,214,166,0.11) 0%, transparent 70%),
    radial-gradient(130% 56% at 50% 104%, rgba(243,112,33,0.20) 0%, rgba(243,112,33,0.05) 42%, transparent 72%);
}
.hero.hero-reel .scene-canvas.lit { opacity: .5; }
/* The stock hero scrim ramps to solid #000 across the bottom 45% of the
   frame, which is fine over a drawn gradient but throws away real footage:
   the operator and his screens sit low in the NOC shot and were being
   crushed to nothing. The page underneath is already black, so the scrim
   only has to reach near-black to blend - it does not have to reach it
   early, and it does not have to get all the way there. */
.hero.hero-reel::after {
  background:
    radial-gradient(ellipse at 50% 44%, transparent 26%, rgba(0,0,0,0.42) 82%),
    linear-gradient(to bottom, rgba(0,0,0,0.5) 0%, transparent 26%, transparent 72%, rgba(0,0,0,0.88) 100%);
}

/* ============================================================
   Hero, without borrowed footage
   A drawn horizon instead of a film: black, one warm band low in
   the frame, and the network laid over it. Nothing to license,
   nothing to download, and it never competes with the headline.
   ============================================================ */
.hero.hero-drawn { background: var(--bg); }
.hero.hero-drawn .hero-glow {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(58% 26% at 50% 100%, rgba(255,214,166,0.22) 0%, transparent 70%),
    radial-gradient(130% 58% at 50% 104%, rgba(243,112,33,0.42) 0%, rgba(243,112,33,0.10) 42%, transparent 72%),
    radial-gradient(90% 46% at 50% -6%, rgba(255,255,255,0.05) 0%, transparent 64%);
}
/* a single hairline horizon, the only hard edge in the composition */
.hero.hero-drawn .hero-glow::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  bottom: 21%;
  height: 1px;
  background: linear-gradient(to right, transparent, rgba(255,178,107,0.4) 22%, rgba(255,214,166,0.6) 50%, rgba(255,178,107,0.4) 78%, transparent);
}
.hero.hero-drawn::after {
  /* leave the low band alone - that warm horizon is the composition */
  background: linear-gradient(to bottom, rgba(0,0,0,0.6) 0%, transparent 24%, transparent 88%, rgba(0,0,0,0.55) 100%);
}

/* ============================================================
   Credential badge - replaces the small caption above headings
   ============================================================ */
.cred-badge {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 9px 18px;
  margin-bottom: 26px;
  border-radius: var(--r-pill);
  border: 1px solid rgba(255,255,255,0.16);
  background: rgba(255,255,255,0.04);
  backdrop-filter: blur(10px);
  color: var(--text-2);
  font-size: 14.5px;
}
.cred-badge img { height: 17px; width: auto; filter: brightness(0) invert(1); opacity: .92; }

/* ============================================================
   Quad - the four-up value grid, drawn marks and a hairline
   ============================================================ */
.quad-item { padding-top: 26px; border-top: 1px solid var(--line); }
.quad-item .ico { margin-bottom: 20px; }


/* ============================================================
   PANEL LAYOUT
   Sections all sit on the same black ground. What separates them
   is a bordered slab, the way a rack separates equipment - so the
   page reads as assembled hardware rather than striped bands.
   ============================================================ */
:root { --panel: #0A0908; --panel-2: #100E0C; }

.dark-section, .card-section, .stats-strip { background: var(--bg); border: 0; }
section { padding: 58px 0; }
@media (max-width: 768px) { section { padding: 34px 0; } }

.card-section > .container,
.card-section > .container-narrow,
.stats-strip > .container {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 30px;
  padding: 76px 60px;
  position: relative;
}
@media (max-width: 768px) {
  .card-section > .container,
  .card-section > .container-narrow,
  .stats-strip > .container { padding: 48px 26px; border-radius: 22px; }
}
/* the panel that carries the operations readout has no inner padding */
.stats-strip > .container:has(.noc-panel) { background: transparent; border: 0; padding: 0; }

/* cards inside a panel step up one tone, never down */
.card-section .feature-card,
.card-section .vendor-card,
.card-section .blog-card,
.card-section .noc-panel { background: var(--panel-2); }

/* the seam is redundant once every section has an edge */
.seam { display: none; }

/* The hero owns its own spacing; page headers must keep theirs, or the
   floating header pill lands on the H1. */
main > section.hero:first-child { padding-top: 0; }

/* That last line holds while the viewport is tall. The hero centres its
   content in 100svh, and with no top padding the centring has no floor -
   so as the viewport gets shorter the block rises until the group tag is
   behind the header pill. It is not a phone-only fault: the tag is under
   the pill at 1440x800 as surely as at 390x700, because a laptop with
   browser chrome has the same height a phone does. English reaches it
   first, its strings running to more lines than the Hebrew.

   Reserving the pill's room gives the centring the floor it was missing.
   The reserve only appears where the height is short enough to need it,
   so the tall-screen composition is untouched, and the seam is quiet:
   just above the query the natural gap is around 39px, just below it the
   reserved one is 42px.

   The scroll cue goes with it. Between pill and cue a 756px viewport has
   about 53px of slack for the whole hero, so room taken at the top comes
   out of the bottom - and the cue is the piece that can be spared when
   the screen is already too short to need telling there is more below. */
@media (max-height: 820px) {
  main > section.hero:first-child { padding-top: 104px; }
  /* auto margins centre while there is room and collapse to the padding
     edge when there is not, so an overflow spills down, never up. */
  .hero > .hero-content { margin-block: auto; }
  .hero > .scroll-cue { display: none; }
}
main > section:last-child { padding-bottom: 96px; }
.subpage-hero { padding: 200px 0 96px; }
.subpage-hero.has-media { padding: 230px 0 120px; }
@media (max-width: 768px) {
  .subpage-hero { padding: 150px 0 64px; }
  .subpage-hero.has-media { padding: 170px 0 80px; }
}

/* ============================================================
   LOGOS IN THEIR OWN COLOURS
   Muted at rest so the wall stays quiet, full brand colour on
   approach. Nothing is ever tinted orange - a vendor mark is not
   ours to repaint.
   ============================================================ */
.partner-logo-cell img,
.vendor-card .v-logo img,
.logo-track img,
.blog-card .thumb img,
.footer-group .fg-brands img {
  filter: grayscale(1) brightness(1.9) contrast(0.92);
  opacity: .48;
  transition: filter .55s var(--ease-leo), opacity .55s var(--ease-leo), transform .55s var(--ease-leo);
}
.partner-logo-cell:hover img,
.vendor-card:hover .v-logo img,
.logo-track img:hover,
.blog-card:hover .thumb img,
.footer-group .fg-brands a:hover img {
  filter: none;
  opacity: 1;
}
.partner-logo-cell:hover img { transform: scale(1.05); }
/* ------------------------------------------------------------
   ...and on a touch screen, where there is no approach to detect.
   js/glow.js decides when a mark has been reached; everything below
   is what that means. A mark that has been reached stays lit - the
   wall a visitor has scrolled past is a wall they can read.
   ------------------------------------------------------------ */
@media (hover: none), (pointer: coarse) {
  .partner-logo-cell,
  .vendor-card { --lit: var(--near, 0); }
  /* a deliberate press still lights a card outright */
  .partner-logo-cell:active,
  .vendor-card:active { --lit: 1; }
  /* the marquee is written per frame from where its travel has
     carried each mark */
  .logo-track img { --lit: var(--near, 0); }

  .partner-logo-cell img,
  .vendor-card .v-logo img,
  .logo-track img {
    filter:
      grayscale(calc(1 - var(--lit)))
      brightness(calc(1 + 0.9 * (1 - var(--lit))))
      contrast(calc(1 - 0.08 * (1 - var(--lit))));
    opacity: calc(0.44 + 0.56 * var(--lit));
  }
  /* all of it is written per frame from where the light is */
  .partner-logo-cell img,
  .vendor-card .v-logo img,
  .logo-track img { transition: none; }

  /* the card comes with it, so the light reads as landing on the card
     and not as the logo changing its mind. The lift stays off the cell
     itself: .reveal.in already owns its transform, and a second rule
     for the same property is a fight one of them has to lose. */
  .partner-logo-cell img {
    position: relative;
    z-index: 1;
    transform: scale(calc(1 + 0.045 * var(--lit)));
  }
  .partner-logo-cell {
    border-color: rgba(255, 255, 255, calc(0.10 + 0.16 * var(--lit)));
    transition: none;
  }
  /* the light itself. Taking the grey out of a mark is a change in the
     mark; a warm bloom landing on the card is light arriving on it, and
     that is the half the eye actually reads. */
  .partner-logo-cell::after {
    content: "";
    position: absolute;
    inset: -24%;
    z-index: 0;
    pointer-events: none;
    opacity: var(--lit);
    background: radial-gradient(
      50% 50% at 50% 50%,
      rgba(255, 178, 107, 0.17) 0%,
      rgba(243, 112, 33, 0.07) 46%,
      transparent 72%);
  }
  .vendor-card {
    border-color: rgba(243, 112, 33, calc(0.12 + 0.22 * var(--lit)));
    transition: none;
  }

  /* the group's own marks are not a hover state - they arrive, in
     order, and they stay */
  .footer-group .fg-brands a img { transition: filter .7s var(--ease-leo), opacity .7s var(--ease-leo); }
  .footer-group .fg-brands.lit a img { filter: none; opacity: 1; }
  .footer-group .fg-brands.lit a:nth-child(2) img { transition-delay: .16s; }
  .footer-group .fg-brands.lit a:nth-child(3) img { transition-delay: .32s; }
}

/* ============================================================
   ICON MOTION
   Each mark animates the one element that means something, and
   only while the card is engaged. At rest the accent breathes so
   slowly it reads as a state light rather than an animation.
   ============================================================ */
.ico svg { overflow: visible; }
.ico .ic-hot { transform-box: fill-box; transform-origin: center; }

/* resting state - a slow, near-invisible breath on the accent */
.ico .ic-hot { animation: icoBreathe 5.2s var(--ease-leo) infinite; }
@keyframes icoBreathe { 0%,100% { opacity: .82; } 50% { opacity: 1; } }

/* engaged: the card or row is hovered */
.feature-card:hover .ico .a-pulse,
.service-row:hover .ico .a-pulse,
.quad-item:hover .ico .a-pulse { animation: icoPulse 1.5s var(--ease-leo) infinite; }
@keyframes icoPulse {
  0%, 100% { transform: scale(1); opacity: .85; }
  45%      { transform: scale(1.18); opacity: 1; }
}

.feature-card:hover .ico .a-travel,
.service-row:hover .ico .a-travel,
.quad-item:hover .ico .a-travel { animation: icoTravel 1.9s cubic-bezier(.5,0,.5,1) infinite; }
@keyframes icoTravel {
  0%   { transform: translateX(-7px); opacity: 0; }
  22%  { opacity: 1; }
  78%  { opacity: 1; }
  100% { transform: translateX(7px); opacity: 0; }
}

.feature-card:hover .ico .a-fall,
.service-row:hover .ico .a-fall,
.quad-item:hover .ico .a-fall { animation: icoFall 1.7s cubic-bezier(.5,0,.5,1) infinite; }
@keyframes icoFall {
  0%   { transform: translateY(-6px); opacity: 0; }
  30%  { opacity: 1; }
  75%  { opacity: 1; }
  100% { transform: translateY(5px); opacity: 0; }
}

.feature-card:hover .ico .a-rise,
.service-row:hover .ico .a-rise,
.quad-item:hover .ico .a-rise { animation: icoRise 1.8s var(--ease-leo) infinite; }
@keyframes icoRise {
  0%   { transform: translateY(5px) scaleY(.86); opacity: 0; }
  35%  { opacity: 1; }
  100% { transform: translateY(-3px) scaleY(1); opacity: 0; }
}

.feature-card:hover .ico .a-emit,
.service-row:hover .ico .a-emit,
.quad-item:hover .ico .a-emit { animation: icoEmit 1.8s var(--ease-leo) infinite; }
@keyframes icoEmit {
  0%   { transform: scale(.72); opacity: 0; }
  35%  { opacity: 1; }
  100% { transform: scale(1.12); opacity: 0; }
}

.feature-card:hover .ico .a-blink,
.service-row:hover .ico .a-blink,
.quad-item:hover .ico .a-blink { animation: icoBlink 1.6s steps(1) infinite; }
@keyframes icoBlink { 0%,55% { opacity: 1; } 62%,72% { opacity: .25; } 79%,100% { opacity: 1; } }

.feature-card:hover .ico .a-sweep,
.service-row:hover .ico .a-sweep,
.quad-item:hover .ico .a-sweep { animation: icoSweep 3.2s linear infinite; transform-origin: 20px 20px; }
@keyframes icoSweep { to { transform: rotate(360deg); } }

.feature-card:hover .ico .a-close,
.service-row:hover .ico .a-close,
.quad-item:hover .ico .a-close { animation: icoClose 1.9s var(--ease-leo) infinite; }
@keyframes icoClose {
  0%, 100% { transform: translateY(0); }
  40%      { transform: translateY(-2.2px); }
  70%      { transform: translateY(0); }
}

/* draw-on: the stroke redraws itself */
.ico .a-draw { stroke-dasharray: 42; stroke-dashoffset: 0; }
.feature-card:hover .ico .a-draw,
.service-row:hover .ico .a-draw,
.quad-item:hover .ico .a-draw { animation: icoDraw 1.9s var(--ease-leo) infinite; }
@keyframes icoDraw {
  0%   { stroke-dashoffset: 42; opacity: .3; }
  35%  { opacity: 1; }
  70%, 100% { stroke-dashoffset: 0; opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .ico .ic-hot, .ico .a-draw { animation: none !important; stroke-dashoffset: 0 !important; }
}

/* ============================================================
   PEPLINK - product catalogue, sector map and video rail
   ============================================================ */

/* ---- sector map --------------------------------------------
   Where the hardware actually goes. Nodes on a field, joined to
   a centre, each one lighting on approach.                     */
.sector-map {
  position: relative;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 26px 18px;
  margin-top: 56px;
}
@media (max-width: 900px) { .sector-map { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 520px) { .sector-map { grid-template-columns: repeat(2, 1fr); } }

.sector {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 14px;
  padding: 26px 14px 22px;
  border: 1px solid var(--line-soft);
  border-radius: 20px;
  background: linear-gradient(160deg, rgba(255,255,255,0.03), transparent 70%);
  transition: border-color .5s var(--ease-leo), background .5s var(--ease-leo), transform .5s var(--ease-leo);
}
.sector:hover { border-color: rgba(243,112,33,0.35); transform: translateY(-4px); }
.sector .ico { width: 54px; height: 54px; border-radius: 15px; }
.sector .ico svg { width: 27px; height: 27px; }
.sector span {
  font-family: var(--font-display);
  font-size: 14.5px;
  font-weight: 500;
  color: var(--text-2);
  line-height: 1.35;
}
.sector:hover span { color: #fff; }

/* ---- category navigation ----------------------------------- */

/* ---- product cards ----------------------------------------- */
.prod-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  margin-top: 34px;
}
@media (max-width: 1100px) { .prod-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px)  { .prod-grid { grid-template-columns: 1fr; } }

.prod-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--panel-2);
  overflow: hidden;
  transition: transform .5s var(--ease-leo), border-color .5s var(--ease-leo);
}
.prod-card:hover { transform: translateY(-5px); border-color: rgba(255,255,255,0.2); }

.prod-shot {
  position: relative;
  aspect-ratio: 16 / 10;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 26px 30px;
  background:
    radial-gradient(70% 58% at 50% 42%, rgba(255,255,255,0.05) 0%, transparent 70%),
    #080706;
  border-bottom: 1px solid var(--line-soft);
}
.prod-shot img {
  max-width: 84%;
  max-height: 100%;
  width: auto;
  object-fit: contain;
  transition: transform .6s var(--ease-leo);
  /* the renders are lit for white; lift them for a dark ground */
  filter: brightness(1.08) contrast(1.02);
}
.prod-card:hover .prod-shot img { transform: scale(1.05); }

.prod-body { padding: 24px 26px 26px; display: flex; flex-direction: column; gap: 10px; flex: 1; }
.prod-body h3 { font-family: var(--font-display); font-size: 19px; font-weight: 500; color: var(--text-1); }
.prod-body p { color: var(--text-3); font-size: 14.5px; line-height: 1.65; flex: 1; }

.prod-sku {
  display: inline-block;
  align-self: flex-start;
  padding: 4px 11px;
  border-radius: 7px;
  border: 1px solid var(--line);
  background: rgba(255,255,255,0.03);
  color: var(--text-3);
  font-size: 12.5px;
  letter-spacing: .02em;
  direction: ltr;
  unicode-bidi: embed;
}
.prod-specs { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 2px; }
.prod-specs span {
  padding: 5px 12px;
  border-radius: var(--r-pill);
  background: rgba(243,112,33,0.09);
  border: 1px solid rgba(243,112,33,0.2);
  color: var(--orange-bright);
  font-size: 12.5px;
}

/* ---- video rail --------------------------------------------
   Thumbnails only until clicked, so the page never loads a
   YouTube player - or sets a YouTube cookie - unasked.          */
.video-rail-wrap { position: relative; margin-top: 44px; }
.video-rail {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(330px, 33%);
  gap: 20px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  padding-bottom: 14px;
  scrollbar-width: thin;
  scrollbar-color: rgba(255,255,255,0.18) transparent;
}
@media (max-width: 700px) { .video-rail { grid-auto-columns: minmax(272px, 84%); } }
.video-rail::-webkit-scrollbar { height: 6px; }
.video-rail::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.16); border-radius: 999px; }

.vid {
  scroll-snap-align: start;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--panel-2);
  display: flex;
  flex-direction: column;
  transition: transform .5s var(--ease-leo), border-color .5s var(--ease-leo);
}
.vid:hover { transform: translateY(-4px); border-color: rgba(255,255,255,0.2); }
.vid-shot { position: relative; aspect-ratio: 16/9; background: #000; cursor: pointer; border: 0; padding: 0; width: 100%; display: block; }
.vid-shot img { width: 100%; height: 100%; object-fit: cover; opacity: .78; transition: opacity .5s var(--ease-leo), transform .8s var(--ease-leo); }
.vid:hover .vid-shot img { opacity: 1; transform: scale(1.04); }
.vid-shot iframe { width: 100%; height: 100%; border: 0; display: block; }
.vid-play {
  position: absolute;
  inset: 0;
  display: flex; align-items: center; justify-content: center;
  pointer-events: none;
}
.vid-play span {
  width: 58px; height: 58px;
  border-radius: 50%;
  background: rgba(243,112,33,0.92);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 12px 40px -8px rgba(0,0,0,0.8);
  transition: transform .45s var(--ease-leo);
}
.vid:hover .vid-play span { transform: scale(1.1); }
.vid-play svg { width: 20px; height: 20px; fill: #fff; margin-inline-start: 3px; }
.vid-meta { padding: 20px 22px 22px; display: flex; flex-direction: column; gap: 8px; flex: 1; }
.vid-meta h3, .vid-meta h4 { font-family: var(--font-display); font-size: 16px; font-weight: 500; color: var(--text-1); line-height: 1.4; }
.vid-meta .kind { color: var(--orange-bright); font-size: 13px; }

.rail-nav { display: flex; gap: 10px; margin-top: 22px; }
.rail-nav button {
  width: 44px; height: 44px;
  border-radius: 50%;
  border: 1px solid var(--line);
  color: var(--text-2);
  display: flex; align-items: center; justify-content: center;
  transition: all .35s var(--ease-leo);
}
.rail-nav button:hover { background: #fff; color: #000; border-color: #fff; }
.rail-nav svg { width: 17px; height: 17px; }

/* ---- licensing ---------------------------------------------- */
.lic-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 48px; }
@media (max-width: 900px) { .lic-grid { grid-template-columns: 1fr; } }
.lic-card {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--panel-2);
  padding: 32px 30px 34px;
}
.lic-card h3 { font-family: var(--font-display); font-size: 19px; font-weight: 500; color: var(--text-1); margin: 18px 0 12px; }
.lic-card p { color: var(--text-3); font-size: 14.8px; line-height: 1.7; }
.lic-card ul { list-style: none; margin-top: 16px; display: flex; flex-direction: column; gap: 10px; }
.lic-card li { color: var(--text-2); font-size: 14.5px; padding-inline-start: 22px; position: relative; line-height: 1.55; }
.lic-card li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0; top: 8px;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--orange);
}

/* ============================================================
   BRAND THEME - Peplink
   The page keeps our layout and typography but borrows the
   partner's accent, so every effect already on the page - scenes,
   icon accents, buttons, chips - turns yellow without any of them
   knowing a partner exists.
   ============================================================ */
[data-brand="peplink"] {
  --orange: #FFB81C;
  --orange-bright: #FFCB4D;
  --orange-deep: #FFD97A;
  --orange-glow: rgba(255, 184, 28, 0.35);
  --orange-soft: rgba(255, 184, 28, 0.16);
  --orange-50: rgba(255, 184, 28, 0.13);
  --grad-word: linear-gradient(to right, #FFB81C 0%, #FFCF63 55%, #FFF0C4 100%);
  --shadow-orange: 0 16px 44px -12px rgba(255, 184, 28, 0.45);
}
[data-brand="peplink"][dir="rtl"] {
  --grad-word: linear-gradient(to left, #FFB81C 0%, #FFCF63 55%, #FFF0C4 100%);
}
[data-brand="peplink"] .btn-primary { color: #171208; }
[data-brand="peplink"] .btn-primary:hover { box-shadow: 0 24px 60px -12px rgba(255,184,28,0.6); }

/* ============================================================
   Partner hero - a lockup and the hardware itself
   ============================================================ */
.brand-hero { position: relative; padding: 178px 0 72px; overflow: hidden; }
.brand-hero-blend { overflow: visible; }
.brand-hero .container { position: relative; z-index: 2; }
/* the headline shares the row with the hardware, so it runs smaller
   here than it does on a page that owns the full width */
.brand-hero .display-1 { font-size: clamp(36px, 4vw, 62px); }
.brand-hero-grid { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 48px; align-items: center; }
@media (max-width: 1000px) { .brand-hero-grid { grid-template-columns: 1fr; gap: 34px; } }

.brand-lockup {
  display: inline-flex;
  align-items: center;
  gap: 18px;
  padding: 13px 24px;
  margin-bottom: 30px;
  border-radius: var(--r-pill);
  border: 1px solid rgba(255,184,28,0.3);
  background: rgba(255,184,28,0.07);
  backdrop-filter: blur(12px);
}
.brand-lockup img { height: 28px; width: auto; }
.brand-lockup .lk-sep { width: 1px; height: 22px; background: rgba(255,255,255,0.22); }
.brand-lockup span { color: var(--text-2); font-size: 14.5px; }

/* the flat-lay, bled off the edge of the frame */
.brand-hero-shot {
  position: relative;
  border-radius: var(--r-xl);
  overflow: hidden;
  border: 1px solid var(--line);
}
.brand-hero-shot img { width: 100%; height: auto; display: block; }
.brand-hero-shot::after {
  content: "";
  position: absolute; inset: 0;
  background:
    linear-gradient(to top, rgba(0,0,0,0.55), transparent 46%),
    radial-gradient(70% 60% at 50% 50%, transparent 40%, rgba(0,0,0,0.35));
  pointer-events: none;
}
@media (max-width: 1000px) { .brand-hero { padding-top: 150px; } }

/* the strip of statements under the hero */
.brand-facts {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  margin-top: 64px;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  background: var(--line-soft);
}
@media (max-width: 800px) { .brand-facts { grid-template-columns: 1fr 1fr; } }
.brand-facts > div { background: var(--bg); padding: 26px 8px 28px; text-align: center; }
.brand-facts .k {
  font-family: var(--font-display); font-weight: 300;
  font-size: 30px; line-height: 1;
  background: linear-gradient(135deg, var(--orange), var(--orange-bright));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.brand-facts .v { color: var(--text-3); font-size: 14px; margin-top: 10px; }

/* ============================================================
   Category switcher - a real control, not a row of pills
   ============================================================ */
.cat-shell {
  position: relative;
  margin: 44px 0 4px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: rgba(255,255,255,0.02);
  padding: 6px;
}
.cat-shell::after,
.cat-shell::before {
  content: "";
  position: absolute; top: 6px; bottom: 6px; width: 46px;
  pointer-events: none; opacity: 0;
  transition: opacity .3s var(--ease-leo);
  z-index: 2;
}
.cat-shell::before { inset-inline-start: 6px; background: linear-gradient(to right, var(--panel), transparent); border-radius: var(--r-pill) 0 0 var(--r-pill); }
.cat-shell::after  { inset-inline-end: 6px;  background: linear-gradient(to left,  var(--panel), transparent); border-radius: 0 var(--r-pill) var(--r-pill) 0; }
.cat-shell.scroll-start::after { opacity: 1; }
.cat-shell.scroll-end::before  { opacity: 1; }
[dir="rtl"] .cat-shell::before { background: linear-gradient(to left, var(--panel), transparent); }
[dir="rtl"] .cat-shell::after  { background: linear-gradient(to right, var(--panel), transparent); }

.cat-nav {
  display: flex;
  flex-wrap: nowrap;
  gap: 4px;
  margin: 0;
  overflow-x: auto;
  scrollbar-width: none;
  scroll-behavior: smooth;
}
.cat-nav::-webkit-scrollbar { display: none; }
.cat-btn {
  flex: 1 0 auto;
  white-space: nowrap;
  padding: 13px 20px;
  border: 0;
  border-radius: var(--r-pill);
  color: var(--text-3);
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 500;
  transition: color .35s var(--ease-leo), background .35s var(--ease-leo);
}
.cat-btn:hover { color: #fff; background: rgba(255,255,255,0.05); }
.cat-btn.active {
  background: linear-gradient(135deg, var(--orange), var(--orange-bright));
  color: #171208;
}
.cat-btn.active .cat-count { opacity: .7; }
.cat-count { margin-inline-start: 8px; font-size: 13.5px; opacity: .5; }

/* the row of category names scrolls on small screens - say so */
.cat-hint {
  display: none;
  align-items: center;
  gap: 8px;
  margin-top: 14px;
  color: var(--text-3);
  font-size: 13.5px;
}
.cat-hint svg { width: 15px; height: 15px; }
@media (max-width: 900px) { .cat-hint { display: inline-flex; } }

/* ============================================================
   Product detail dialog
   ============================================================ */
.prod-card { cursor: pointer; }
.prod-more {
  display: inline-flex; align-items: center; gap: 7px;
  color: var(--orange-bright);
  font-family: var(--font-display); font-weight: 500; font-size: 14px;
  margin-top: 4px;
}
.prod-more svg { width: 14px; height: 14px; }
[dir="rtl"] .prod-more svg { transform: scaleX(-1); }

.pmodal {
  position: fixed;
  inset: 0;
  z-index: 9990;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 28px;
  background: rgba(0,0,0,0.78);
  backdrop-filter: blur(14px);
  opacity: 0;
  pointer-events: none;
  transition: opacity .4s var(--ease-leo);
}
.pmodal.open { opacity: 1; pointer-events: auto; }
.pmodal-panel {
  width: min(1000px, 100%);
  max-height: 100%;
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  background: var(--panel);
  transform: translateY(18px) scale(.985);
  transition: transform .5s var(--ease-leo);
}
.pmodal.open .pmodal-panel { transform: none; }
.pmodal-close {
  position: sticky;
  top: 0;
  float: inline-end;
  margin: 14px 14px 0;
  width: 42px; height: 42px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: rgba(0,0,0,0.5);
  color: var(--text-2);
  display: flex; align-items: center; justify-content: center;
  z-index: 3;
  transition: all .3s var(--ease-leo);
}
.pmodal-close:hover { background: #fff; color: #000; border-color: #fff; }
.pmodal-close svg { width: 18px; height: 18px; }

.pmodal-head { display: grid; grid-template-columns: 1fr 1fr; gap: 0; }
@media (max-width: 780px) { .pmodal-head { grid-template-columns: 1fr; } }
.pmodal-shot {
  display: flex; align-items: center; justify-content: center;
  padding: 44px;
  min-height: 260px;
  background:
    radial-gradient(70% 60% at 50% 45%, rgba(255,255,255,0.06) 0%, transparent 70%),
    #080706;
}
.pmodal-shot img { max-width: 100%; max-height: 260px; width: auto; object-fit: contain; filter: brightness(1.08); }
.pmodal-intro { padding: 44px 42px; display: flex; flex-direction: column; gap: 14px; justify-content: center; }
.pmodal-intro h2 { font-family: var(--font-display); font-size: clamp(24px, 3vw, 34px); font-weight: 400; color: var(--text-1); }
.pmodal-intro p { color: var(--text-3); font-size: 15.5px; line-height: 1.7; }
@media (max-width: 780px) { .pmodal-intro { padding: 30px 26px 34px; } }

.pmodal-body { padding: 0 42px 44px; display: grid; grid-template-columns: 1.1fr .9fr; gap: 40px; }
@media (max-width: 780px) { .pmodal-body { grid-template-columns: 1fr; gap: 28px; padding: 0 26px 34px; } }
.pmodal-body h3 {
  font-family: var(--font-display); font-size: 15px; font-weight: 500;
  color: var(--text-1); margin-bottom: 16px;
}
.spec-table { width: 100%; border-collapse: collapse; }
.spec-table tr { border-bottom: 1px solid var(--line-soft); }
.spec-table tr:last-child { border-bottom: 0; }
.spec-table th {
  text-align: start; font-weight: 400; color: var(--text-3);
  font-size: 14px; padding: 11px 0; width: 42%;
}
.spec-table td {
  color: var(--text-1); font-size: 14.5px; padding: 11px 0;
  /* spec values are Latin with leading digits - isolate them so RTL
     never reorders "8-port 10G" into "port 10G-8" */
  direction: ltr;
  unicode-bidi: isolate;
  text-align: start;
}
[dir="rtl"] .spec-table td { text-align: left; }
.pmodal-use { color: var(--text-3); font-size: 14.8px; line-height: 1.75; }
.pmodal-cta { grid-column: 1 / -1; display: flex; gap: 12px; flex-wrap: wrap; padding-top: 8px; }

/* ============================================================
   Page header with a framed figure
   The Starlink and Peplink headers work because the copy has
   something to sit beside. Service pages have no photography, so
   the generative scene is promoted out of the background and into
   a panel of its own - same composition, drawn instead of shot.
   ============================================================ */
.subpage-hero.has-figure .subpage-hero-grid {
  grid-template-columns: 1.02fr 0.98fr;
  gap: 56px;
  align-items: center;
}
@media (max-width: 1000px) {
  .subpage-hero.has-figure .subpage-hero-grid { grid-template-columns: 1fr; gap: 40px; }
}

.hero-figure {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: var(--r-xl);
  overflow: hidden;
  border: 1px solid var(--line);
  background:
    radial-gradient(90% 70% at 50% 8%, rgba(255,255,255,0.035) 0%, transparent 64%),
    var(--panel);
}
@media (max-width: 1000px) { .hero-figure { aspect-ratio: 16 / 9; } }
/* inside the frame the scene is the subject, so it runs at full strength */
.hero-figure .scene-canvas { opacity: 0; }
.hero-figure .scene-canvas.lit { opacity: 1; }
.hero-figure::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(80% 70% at 50% 50%, transparent 45%, rgba(0,0,0,0.42));
}
/* the mark of the discipline, held quietly in the corner of the frame */
.hero-figure .fig-mark {
  position: absolute;
  inset-block-end: 26px;
  inset-inline-start: 26px;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 14px;
}
.hero-figure .fig-mark .ico { background: rgba(0,0,0,0.4); backdrop-filter: blur(8px); }
.hero-figure .fig-mark span {
  font-family: var(--font-display);
  font-size: 15px;
  color: var(--text-2);
}
@media (max-width: 560px) {
  .hero-figure .fig-mark { inset-block-end: 18px; inset-inline-start: 18px; gap: 11px; }
  .hero-figure .fig-mark .ico { width: 46px; height: 46px; border-radius: 13px; }
  .hero-figure .fig-mark .ico svg { width: 23px; height: 23px; }
}

/* with a figure present the page keeps its own background quiet */
.subpage-hero.has-figure::before { opacity: .55; }


/* ============================================================
   Cinematic scene hero
   The Starlink header works because the subject fills the frame
   and the copy sits over it. Scene pages now get exactly that:
   the drawing runs full-bleed at full strength, with the same
   scrim and the same single-column copy block.
   ============================================================ */
.subpage-hero .container { z-index: 2; }
.subpage-hero.has-scene { padding: 235px 0 135px; }
.subpage-hero.has-scene .subpage-hero-grid { grid-template-columns: 1fr; max-width: 880px; }
.subpage-hero.has-scene .scene-canvas { opacity: 0; z-index: 0; }
.subpage-hero.has-scene .scene-canvas.lit {
  opacity: 1;
  /* the motifs are painted at background strength - as the subject
     of the frame they are lifted, not repainted */
  filter: brightness(2.05) saturate(1.15);
}
.subpage-hero.has-scene::after {
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  z-index: 1;
  background: linear-gradient(to bottom, rgba(0,0,0,0.4) 0%, transparent 30%, transparent 76%, #000 100%);
}
@media (max-width: 768px) { .subpage-hero.has-scene { padding: 170px 0 90px; } }

/* the home hero gets the same lift */
.hero .scene-canvas.lit { filter: brightness(1.7) saturate(1.12); }
.brand-hero .scene-canvas.lit { filter: brightness(1.75) saturate(1.1); }

/* Starlink, English: the copy sits left, so the film is mirrored to
   put the satellite in the free right half. RTL keeps the original.
   The band films need the same flip for the same reason - the antenna
   is framed left, which is exactly where the English copy lands. */
[dir="ltr"] .subpage-hero.has-media .page-hero-media video,
[dir="ltr"] .media-band .band-media video { transform: scaleX(-1); }

/* ============================================================
   Enquiry dialog - a service-scoped form instead of a bare link
   ============================================================ */
.emodal .pmodal-panel { width: min(620px, 100%); }
.enq-head { padding: 44px 42px 6px; display: flex; flex-direction: column; gap: 14px; }
.enq-head img { height: 30px; width: auto; align-self: flex-start; }
.enq-head h2 { font-family: var(--font-display); font-size: 27px; font-weight: 400; color: var(--text-1); }
.enq-topic {
  display: inline-block;
  align-self: flex-start;
  padding: 6px 14px;
  border-radius: 9px;
  border: 1px solid rgba(243,112,33,0.3);
  background: rgba(243,112,33,0.08);
  color: var(--orange-bright);
  font-size: 13.5px;
}
[data-brand="peplink"] .enq-topic { border-color: rgba(255,184,28,0.3); background: rgba(255,184,28,0.08); }
.emodal form { padding: 24px 42px 44px; }
@media (max-width: 640px) {
  .enq-head { padding: 34px 26px 4px; }
  .emodal form { padding: 20px 26px 34px; }
}

/* scene-hero finish: a hairline horizon at the base and a quiet
   contrast bed under the copy on the reading side */
.subpage-hero.has-scene .subpage-hero-grid { position: relative; }
.subpage-hero.has-scene::before { opacity: .8; }
.subpage-hero.has-scene .container::before {
  content: "";
  position: absolute;
  inset: -60px -80px;
  pointer-events: none;
  z-index: -1;
  background: radial-gradient(58% 68% at 26% 50%, rgba(0,0,0,0.5) 0%, transparent 72%);
}
[dir="rtl"] .subpage-hero.has-scene .container::before {
  background: radial-gradient(58% 68% at 74% 50%, rgba(0,0,0,0.5) 0%, transparent 72%);
}
.subpage-hero.has-scene .container { position: relative; }


/* The wall and the vendor cards used to carry a list of per-file
   exceptions here - starlink and peplink, added when someone noticed
   they read small. The cap is derived per mark now (build/imgsize.js),
   so the list is gone and Siklu, Grafana and Cisco, which had the same
   problem and no exception, are fixed by the same rule.
   The marquee still needs one: it caps on height alone, by design. */
.logo-track img[src*="starlink"], .logo-track img[src*="peplink"] { height: 30px; }


/* ============================================================
   Peplink hero cluster
   The manufacturer's transparent renders, composed directly on
   the page: a dome standing behind, the rack unit carrying the
   middle, the rugged router up front. No card, no border - the
   floor glow is the only thing that grounds them.
   ============================================================ */
.brand-hero-stack {
  position: relative;
  min-height: 520px;
  z-index: 1;
  margin-inline-end: -4%;
}
@media (max-width: 1000px) { .brand-hero-stack { min-height: 340px; } }

/* the warm floor the hardware sits on */
.brand-hero-stack::before {
  content: "";
  position: absolute;
  inset: auto -14% -8%;
  height: 58%;
  background:
    radial-gradient(52% 42% at 50% 78%, rgba(255,184,28,0.22) 0%, rgba(255,184,28,0.06) 48%, transparent 74%);
  filter: blur(18px);
  pointer-events: none;
}
/* a single hairline under the composition - the same horizon the
   rest of the site uses */
.brand-hero-stack::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  bottom: 9%;
  height: 1px;
  background: linear-gradient(to right, transparent, rgba(255,207,99,0.4) 30%, rgba(255,240,196,0.55) 50%, rgba(255,207,99,0.4) 70%, transparent);
}

.brand-hero-stack img {
  position: absolute;
  height: auto;
  filter: brightness(1.06) drop-shadow(0 26px 44px rgba(0,0,0,0.65));
}
.brand-hero-stack .bhs-dome {
  width: 38%;
  right: 2%;
  bottom: 30%;
  z-index: 1;
  animation: bhsFloat 9s ease-in-out infinite;
}
.brand-hero-stack .bhs-rack {
  width: 100%;
  left: 0;
  bottom: 26%;
  z-index: 2;
  animation: bhsFloat 11s ease-in-out infinite reverse;
}
.brand-hero-stack .bhs-br1 {
  width: 58%;
  left: 4%;
  bottom: 6%;
  z-index: 3;
  animation: bhsFloat 10s ease-in-out 1.2s infinite;
}
@keyframes bhsFloat {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-9px); }
}
@media (prefers-reduced-motion: reduce) { .brand-hero-stack img { animation: none; } }


/* ============================================================
   Peplink hero media
   Same construction as the Starlink film header: the artwork is a
   layer of the section, cropped by the section's own edges. Nothing
   is masked into an oval and nothing is feathered into a rectangle -
   the only cut is the edge of the viewport, which reads as framing
   rather than as a border. A directional scrim protects the copy.
   ============================================================ */
.brand-hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
/* The plate is deliberately smaller than the section, so the whole lay
   reads rather than four enlarged units. Its outer edge leaves the
   viewport, so that side needs no treatment - it reads as framing.
   The other three do: the top and bottom dissolve, and so must the
   edge that faces the copy, because the plate ends there inside the
   viewport and the scrim alone never hid it - a bright unit sliced by
   a ruler-straight vertical line stayed perfectly legible through it.
   Two one-axis fades intersected, rather than one four-sided feather,
   so the artwork still never reads as a soft-cornered rectangle. */
.brand-hero-media img {
  position: absolute;
  top: 50%;
  inset-inline-end: -2%;
  transform: translateY(-50%);
  width: 70%;
  height: auto;
  max-width: none;
  filter: brightness(1.42) contrast(1.1) saturate(1.05);
  /* LTR: the plate runs off the right, so the copy meets its left edge */
  --bh-fade-h: linear-gradient(to left, #000 0%, #000 52%, transparent 94%);
  --bh-fade-v: linear-gradient(to bottom, transparent 0%, #000 24%, #000 76%, transparent 100%);
  -webkit-mask-image: var(--bh-fade-v), var(--bh-fade-h);
  mask-image: var(--bh-fade-v), var(--bh-fade-h);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}
/* RTL mirrors it: the plate runs off the left, copy meets its right edge */
[dir="rtl"] .brand-hero-media img {
  --bh-fade-h: linear-gradient(to right, #000 0%, #000 52%, transparent 94%);
}
/* the reading side is held down so the headline always wins */
.brand-hero-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to right, #000 22%, rgba(0,0,0,0.72) 42%, rgba(0,0,0,0.2) 66%, transparent 92%),
    linear-gradient(to bottom, rgba(0,0,0,0.55) 0%, transparent 22%, transparent 72%, #000 100%);
}
[dir="rtl"] .brand-hero-media::after {
  background:
    linear-gradient(to left, #000 22%, rgba(0,0,0,0.72) 42%, rgba(0,0,0,0.2) 66%, transparent 92%),
    linear-gradient(to bottom, rgba(0,0,0,0.55) 0%, transparent 22%, transparent 72%, #000 100%);
}

/* with the artwork behind everything, the hero is a single column */
.brand-hero-grid.single { grid-template-columns: minmax(0, 640px); }
@media (max-width: 1000px) {
  .brand-hero-grid.single { grid-template-columns: 1fr; }
  /* on a phone the plate is a full-bleed backdrop and its inner edge sits
     right against the bezel, so the fade only has to cover the last sliver */
  .brand-hero-media img {
    width: 116%; min-width: 0; inset-inline-end: -18%; opacity: .5;
    --bh-fade-h: linear-gradient(to left, #000 0%, #000 86%, transparent 100%);
  }
  [dir="rtl"] .brand-hero-media img {
    --bh-fade-h: linear-gradient(to right, #000 0%, #000 86%, transparent 100%);
  }
  .brand-hero-media::after {
    background: linear-gradient(to bottom, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0.55) 40%, #000 100%);
  }
}

/* the copy column simply sits above the artwork - the layers are already
   clear of it, so no scrim is needed and nothing dims the headline */
.brand-hero .brand-hero-grid > .reveal { position: relative; z-index: 3; }

/* ============================================================
   The page subject
   Every service hero gets what Peplink's has: something real
   floating opposite the copy. The subject is the discipline's
   drawn object - dark glass, warm core - hanging in the scene
   with a halo behind it, drifting the way the hardware stack
   drifts. The copy column stays untouched.
   ============================================================ */
.hero-subject {
  position: absolute;
  top: 50%;
  inset-inline-end: max(4vw, calc((100% - 1240px) / 2 - 40px));
  z-index: 1;
  width: clamp(300px, 29vw, 450px);
  aspect-ratio: 1;
  transform: translateY(-46%);
  pointer-events: none;
}
/* the halo blooms behind the object, and doubles as the seam-hider
   for the tile's square plate */
.hero-subject .hs-halo {
  position: absolute;
  inset: -34%;
  background:
    radial-gradient(50% 50% at 50% 50%, rgba(243,112,33,0.20) 0%, rgba(243,112,33,0.07) 46%, transparent 72%);
  opacity: 0;
  animation: hsBloom 2.2s var(--ease-leo) 0.7s forwards;
}
.hero-subject .hs-obj {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  /* one-axis dissolve, per the house rule: the plate melts top and
     bottom and the halo carries the sides */
  -webkit-mask-image: linear-gradient(to bottom, transparent 2%, #000 26%, #000 78%, transparent 98%);
  mask-image: linear-gradient(to bottom, transparent 2%, #000 26%, #000 78%, transparent 98%);
  filter: brightness(1.12) saturate(1.06) drop-shadow(0 30px 60px rgba(0,0,0,0.55));
  opacity: 0;
  transform: translateY(30px) scale(0.96);
  animation:
    hsEnter 1.5s var(--ease-leo) 0.4s forwards,
    hsFloat 9s ease-in-out 2.4s infinite alternate;
}
@keyframes hsEnter {
  to { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes hsBloom {
  to { opacity: 1; }
}
@keyframes hsFloat {
  from { transform: translateY(0) scale(1); }
  to   { transform: translateY(-14px) scale(1.015); }
}
/* pointer parallax writes these */
.hero-subject { --px: 0px; --py: 0px; }
.hero-subject .hs-halo { translate: calc(var(--px) * 0.4) calc(var(--py) * 0.4); }
.hero-subject .hs-obj  { translate: var(--px) var(--py); }

/* the subject shares the frame with a single-column copy block, so pull
   the copy to the start edge instead of centering it */
.subpage-hero.has-subject .subpage-hero-grid { margin-inline-start: 0; }

@media (max-width: 900px) {
  /* on a phone the object steps behind the copy, quiet, like the
     Peplink plate does */
  .hero-subject {
    width: min(72vw, 360px);
    inset-inline-end: -14%;
    top: 46%;
    opacity: 0.4;
  }
}
@media (prefers-reduced-motion: reduce) {
  .hero-subject .hs-obj { animation: hsEnter 0.01s forwards; }
  .hero-subject .hs-halo { animation: hsBloom 0.01s forwards; }
}

/* ============================================================
   The forge - a hero subject that assembles itself
   ------------------------------------------------------------
   js/forge.js measures the mark in .forge-src and animates a
   network of particles into it. The source <svg> has to stay
   rendered for getPointAtLength() to return geometry, so it is
   made invisible with opacity rather than display:none.
   ============================================================ */
.hero-forge .forge-src {
  position: absolute;
  top: 0;
  inset-inline-start: 0;
  width: 40px;
  height: 40px;
  opacity: 0;
  pointer-events: none;
  color: transparent;
}
.hero-forge .forge-src svg { width: 40px; height: 40px; display: block; }

.hero-forge .forge-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 1.4s var(--ease-leo);
}
.hero-forge .forge-canvas.lit { opacity: 1; }

/* the halo is now lighting a drawn mark, not hiding a plate's edge,
   so it sits tighter and cooler than it did under the render */
.hero-forge .hs-halo {
  inset: -22%;
  background:
    radial-gradient(50% 50% at 50% 50%, rgba(243,112,33,0.16) 0%, rgba(243,112,33,0.05) 48%, transparent 74%);
}

/* the pointer parallax in js/spotnet.js writes --px/--py on .hero-subject;
   it used to move the render plate, so hand it the canvas instead */
.hero-forge .forge-canvas { translate: var(--px) var(--py); }

/* On a phone the copy sits directly over the subject. A solid render
   plate could take that at low opacity - a line drawing cannot, its
   strokes cut straight through the paragraph. The mark stands down and
   the page's scene carries the backdrop alone. */
@media (max-width: 900px) {
  .hero-forge { display: none; }
}

/* ============================================================
   Accessibility toolbar + display modes (see js/a11y.js)
   ------------------------------------------------------------
   The group site carries the same component. Everything here is
   injected at runtime, so no page markup has to know about it.
   ============================================================ */

/* skip link - present always, visible once it takes focus */
.a11y-skip {
  position: fixed;
  inset-inline-start: 50%;
  top: -120px;
  transform: translateX(-50%);
  z-index: 10000;
  background: var(--orange);
  color: #fff;
  padding: 14px 26px;
  border-radius: 0 0 14px 14px;
  font-family: var(--font-display);
  font-size: 15px;
  text-decoration: none;
  transition: top .25s var(--ease-leo);
}
[dir="rtl"] .a11y-skip { transform: translateX(50%); }
.a11y-skip:focus { top: 0; }

.a11y-fab {
  position: fixed;
  inset-inline-start: 20px;
  bottom: 20px;
  z-index: 9990;
  width: 52px; height: 52px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--orange-bright), var(--orange));
  color: #fff;
  box-shadow: var(--shadow-orange);
  transition: transform .45s var(--ease-leo), box-shadow .45s var(--ease-leo);
}
.a11y-fab:hover { transform: translateY(-3px); }

.a11y-panel {
  position: fixed;
  inset-inline-start: 20px;
  bottom: 84px;
  z-index: 9991;
  width: min(320px, calc(100vw - 40px));
  padding: 18px;
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: rgba(18, 16, 13, 0.97);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  box-shadow: var(--shadow-lg);
}
.a11y-panel[hidden] { display: none; }
.a11y-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.a11y-head h2 { font-family: var(--font-display); font-weight: 500; font-size: 17px; color: var(--text-1); }
.a11y-close { width: 30px; height: 30px; border-radius: 50%; color: var(--text-3); font-size: 15px; }
.a11y-close:hover { color: #fff; background: rgba(255,255,255,0.08); }

.a11y-fs {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; margin-bottom: 14px;
  border: 1px solid var(--line-soft); border-radius: var(--r-sm);
}
.a11y-fs-label { flex: 1; font-size: 14px; color: var(--text-2); }
.a11y-step {
  width: 30px; height: 30px; border-radius: 8px;
  background: rgba(255,255,255,0.06); color: var(--text-1);
  font-size: 17px; line-height: 1;
}
.a11y-step:hover:not(:disabled) { background: var(--orange-soft); }
.a11y-step:disabled { opacity: .35; cursor: default; }
.a11y-fs-val { min-width: 44px; text-align: center; font-size: 13.5px; color: var(--text-3); }

.a11y-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.a11y-opt {
  display: flex; align-items: center; gap: 9px;
  padding: 11px 10px;
  border: 1px solid var(--line-soft); border-radius: var(--r-sm);
  font-size: 13px; color: var(--text-2); text-align: start;
  transition: border-color .3s, background .3s, color .3s;
}
.a11y-opt:hover { border-color: rgba(255,255,255,0.2); color: #fff; }
.a11y-opt[aria-pressed="true"] {
  border-color: rgba(243,112,33,0.55);
  background: var(--orange-50);
  color: #fff;
}
.a11y-ico { font-size: 14px; opacity: .85; flex-shrink: 0; }
.a11y-reset {
  width: 100%; margin-top: 12px; padding: 11px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  font-size: 13.5px; color: var(--text-2);
}
.a11y-reset:hover { color: #fff; border-color: rgba(255,255,255,0.24); }
.a11y-note { margin-top: 12px; font-size: 12px; line-height: 1.6; color: var(--text-3); }
.a11y-note a { color: var(--orange-bright); text-decoration: underline; text-underline-offset: 2px; }

/* ---- the modes ---- */
.a11y-zoomed { zoom: var(--a11y-zoom, 1); }
.a11y-grayscale body { filter: grayscale(1); }

.a11y-contrast body { background: #000; }
.a11y-contrast :where(p, li, span, td, th, label, dd, dt, .lede) { color: #fff !important; }
.a11y-contrast :where(h1, h2, h3, h4, h5, h6, strong) { color: #fff !important; }
.a11y-contrast :where(h1, h2, h3) strong,
.a11y-contrast .gradient-text {
  background: none !important;
  -webkit-text-fill-color: #fff !important;
  color: #fff !important;
}
.a11y-contrast a:not(.btn) { color: #ffd39b !important; }
.a11y-contrast :where(section, footer, .card-section, .dark-section, .vendor-card, .partner-logo-cell) {
  background-color: #000 !important;
}
/* the films and the drawn scenes are decoration; hold them right down
   so nothing competes with the text */
.a11y-contrast :where(.page-hero-media, .band-media, .hero-media, canvas, .forge-canvas, .hs-halo) {
  opacity: .12 !important;
}
.a11y-contrast .cta-form :where(input, textarea, select) {
  background: #000 !important; color: #fff !important; border-color: #fff !important;
}

.a11y-links a { text-decoration: underline !important; text-underline-offset: 3px; }
.a11y-links a:not(.btn) { color: #ffd39b !important; background: rgba(243,112,33,0.14); }

.a11y-readable, .a11y-readable :where(h1, h2, h3, h4, h5, h6, p, li, span, a, button, input, textarea, label) {
  font-family: Arial, "Helvetica Neue", Helvetica, sans-serif !important;
  letter-spacing: normal !important;
}

.a11y-nomotion *,
.a11y-nomotion *::before,
.a11y-nomotion *::after {
  animation: none !important;
  transition: none !important;
  scroll-behavior: auto !important;
}
/* WCAG 2.2.2 is satisfied by hiding it. Hiding also parks the work:
   every engine gates its frame on an IntersectionObserver, and a
   display:none canvas reports as not intersecting, so the loops stop
   on their own rather than drawing to something nobody can see. */
:root[data-motion="off"] :where(canvas, .forge-canvas, .scene-canvas, video) { display: none !important; }
:root[data-motion="off"] .logo-marquee { animation: none !important; }

.a11y-bigcursor, .a11y-bigcursor * {
  cursor: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='48' height='48' viewBox='0 0 48 48'><path d='M8 4l26 17-11 2 6 13-5 2-6-13-8 8z' fill='%23fff' stroke='%23000' stroke-width='2'/></svg>") 4 4, auto !important;
}

@media (max-width: 560px) {
  .a11y-fab { width: 46px; height: 46px; bottom: 14px; inset-inline-start: 14px; }
  .a11y-panel { bottom: 70px; inset-inline-start: 14px; }
}

/* ============================================================
   FORTINET - the SASE flow, the stack, the migration track
   ============================================================ */

/* ---- the drawn SASE diagram (js/flow.js) ---- */
.flow-figure {
  position: relative;
  margin: 54px 0 0;
  aspect-ratio: 16 / 7;
  min-height: 320px;
  border-radius: var(--r-lg);
  border: 1px solid var(--line-soft);
  background:
    radial-gradient(120% 100% at 50% 50%, rgba(243,112,33,0.05) 0%, transparent 62%),
    var(--card);
  overflow: hidden;
}
.flow-canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.flow-node, .flow-gate {
  position: absolute;
  transform: translate(-50%, -50%);
  white-space: nowrap;
  font-family: var(--font-display);
  pointer-events: none;
}
.flow-node {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 12px 14px 10px;
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  background: rgba(10,10,14,0.78);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  font-size: 12.5px;
  color: var(--text-2);
}
.fn-ico { width: 30px; height: 24px; color: var(--text-1); opacity: .88; }
.fg-ico { width: 24px; height: 26px; color: var(--orange-bright); }
.flow-gate {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  font-size: 15px;
  font-weight: 500;
  color: var(--text-1);
  text-align: center;
}
.flow-gate .fg-sub {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 400;
  color: var(--orange-bright);
  letter-spacing: .02em;
}
.flow-figure figcaption {
  position: absolute;
  inset-inline: 0;
  bottom: 14px;
  text-align: center;
  font-size: 12.5px;
  color: var(--text-3);
}
@media (max-width: 820px) {
  .flow-figure { aspect-ratio: 4 / 5; min-height: 460px; }
  .flow-node { font-size: 11px; padding: 8px 9px 7px; gap: 4px; max-width: 108px; text-align: center; line-height: 1.35; }
  .fn-ico { width: 22px; height: 18px; }
}

/* ---- migration: a track with real stages on it ---- */
.mig-track { position: relative; margin-top: 52px; }
.mig-track::before {
  content: "";
  position: absolute;
  inset-inline-start: 15px;
  top: 8px; bottom: 8px;
  width: 2px;
  background: linear-gradient(to bottom, transparent, var(--orange-soft) 12%, var(--orange-soft) 88%, transparent);
}
.mig-step { position: relative; padding-inline-start: 52px; padding-bottom: 30px; }
.mig-step:last-child { padding-bottom: 0; }
.mig-step .ms-dot {
  position: absolute;
  inset-inline-start: 8px;
  top: 4px;
  width: 16px; height: 16px;
  border-radius: 50%;
  border: 2px solid var(--orange);
  background: var(--bg);
}
.mig-step .ms-dot::after {
  content: "";
  position: absolute;
  inset: 3px;
  border-radius: 50%;
  background: var(--orange);
  opacity: 0;
  transition: opacity .6s var(--ease-leo);
}
.mig-step.in .ms-dot::after { opacity: 1; }
.mig-step h3 { font-family: var(--font-display); font-size: 18px; font-weight: 500; color: var(--text-1); margin-bottom: 6px; }
.mig-step p { font-size: 14.5px; line-height: 1.7; color: var(--text-3); }

/* ---- the talk, and the reel beside it ----
   A 9:16 clip under a 16:9 one is a column of dead space on both
   sides of it. Beside it, the two shapes explain each other: the
   stage, and the floor. */
.talk-pair {
  display: grid;
  grid-template-columns: minmax(0, 1.75fr) minmax(0, 1fr);
  gap: 20px;
  /* stretch, not start: the reel is the taller of the two and so it
     sets the row, and the photograph on the left takes exactly what is
     left over. With start, each column kept its own height and the gap
     under the recording was the thing you were looking at. */
  align-items: stretch;
  margin-top: 48px;
}
@media (max-width: 900px) { .talk-pair { grid-template-columns: 1fr; } }

/* the left column: the recording, then the photograph filling whatever
   height the reel beside it does not use, so the pair ends level */
.talk-col { display: flex; flex-direction: column; gap: 20px; min-width: 0; }
.stand {
  margin: 0;
  flex: 1 1 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: var(--card);
  overflow: hidden;
}
.stand img {
  width: 100%;
  /* basis zero, so the photograph contributes nothing to the column's
     natural height and simply grows into whatever the reel leaves */
  flex: 1 1 0;
  height: 0;
  min-height: 0;
  object-fit: cover;
  object-position: 50% 42%;
}
@media (max-width: 900px) {
  /* stacked, there is no leftover to fill - give it its own shape back */
  .stand, .stand img { flex: none; }
  .stand img { height: auto; aspect-ratio: 3 / 2; }
}

.reel {
  margin: 0;
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: var(--card);
  overflow: hidden;
}
.reel video {
  display: block;
  width: 100%;
  aspect-ratio: 9 / 16;
  object-fit: cover;
  background: #000;
}
/* on a phone the reel is the one that should not be full-bleed tall */
@media (max-width: 900px) {
  .reel video { aspect-ratio: 9 / 14; max-height: 70vh; }
}

/* ---- the talk: one slot, sized like a real feature ---- */
.talk {
  margin-top: 0;
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: var(--card);
  overflow: hidden;
}
.talk-frame { position: relative; aspect-ratio: 16 / 9; background: #000; }
.talk-frame iframe, .talk-frame video { width: 100%; height: 100%; border: 0; display: block; object-fit: cover; }
.talk-empty {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
  color: var(--text-3);
  background:
    radial-gradient(70% 70% at 50% 50%, rgba(243,112,33,0.09) 0%, transparent 70%),
    repeating-linear-gradient(135deg, rgba(255,255,255,0.02) 0 12px, transparent 12px 24px);
  font-size: 14px;
  text-align: center;
  padding: 24px;
}
.talk-empty svg { width: 34px; height: 34px; color: var(--orange-bright); }


/* ---- the spotlight: one product at a time ---- */
.spotlight { margin-top: 52px; }
/* Five pills of unequal width wrapped into a ragged two-row block with
   a hole in it, and the icons inside them were 15px - too small to be
   anything but decoration. It is a fixed five-column grid now: equal
   cells, the icon large and stacked above its name, so the row reads
   as one set of five rather than as a broken sentence. */
.sp-tabs {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 10px;
  margin-bottom: 22px;
}
.sp-tab {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 20px 12px 18px;
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: var(--card);
  font-family: var(--font-display);
  font-size: 13.5px;
  line-height: 1.35;
  color: var(--text-3);
  text-align: center;
  white-space: normal;
  transition: color .35s, border-color .35s, background .35s, transform .35s var(--ease-leo);
}
.sp-tab:hover { color: var(--text-1); border-color: rgba(255,255,255,0.24); transform: translateY(-3px); }
.sp-tab.on {
  color: #fff;
  border-color: rgba(243,112,33,0.55);
  background: linear-gradient(180deg, rgba(243,112,33,0.13), var(--card-2));
}
@media (max-width: 1000px) { .sp-tabs { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 620px)  { .sp-tabs { grid-template-columns: repeat(2, 1fr); gap: 8px; } }
.sp-stage {
  position: relative;
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: var(--card);
  overflow: hidden;
}
.sp-panel {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 34px;
  align-items: center;
  padding: 34px;
}
.sp-panel[hidden] { display: none; }
@media (max-width: 860px) { .sp-panel { grid-template-columns: 1fr; gap: 24px; padding: 24px; } }
.sp-art {
  border-radius: var(--r-md);
  background: rgba(0,0,0,0.28);
  border: 1px solid var(--line-soft);
  padding: 14px;
}
.sch { position: relative; z-index: 2; width: 100%; height: auto; color: var(--text-2); display: block; }
/* Product names are latin and the drawings are coordinate space, but an
   SVG inside an RTL document inherits direction: rtl - which flips what
   text-anchor start and end mean, so every label ran the wrong way out
   of the box it belonged to. The drawings are always LTR. */
.sch, .dv { direction: ltr; }
.sch text, .dv text { font-family: var(--font-body); direction: ltr; unicode-bidi: isolate; }
.sch .ic-hot { color: var(--orange); }
.sp-name {
  display: block;
  font-family: var(--font-display);
  font-size: 21px;
  font-weight: 500;
  color: var(--text-1);
  margin-bottom: 8px;
}
.sp-one { font-size: 15px; line-height: 1.7; color: var(--text-3); }
.sp-copy ul { list-style: none; margin: 18px 0 0; padding: 0; }
.sp-copy li {
  position: relative;
  padding-inline-start: 18px;
  margin-bottom: 9px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-2);
}
.sp-copy li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0; top: 9px;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--orange);
  opacity: .75;
}
/* the panel that is arriving fades rather than snapping */
.sp-panel.on { animation: spIn .5s var(--ease-leo) both; }
@keyframes spIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .sp-panel.on { animation: none; } }

/* ============================================================
   FORTINET - the drawn hardware, and everything that moves
   ============================================================ */

/* ---- the shared motion vocabulary ----
   .led blinks on its own clock, .mv is a mote crossing a schematic
   on a straight line, .pulse rides a real cable path in the rack,
   .w1/.w2 are the AP's signal arcs breathing. One switch - reduced
   motion or the toolbar's stop - kills all of it below. */
@keyframes dvLed { 0%, 54% { opacity: 1; } 60%, 72% { opacity: .2; } 78%, 100% { opacity: 1; } }
.dv .led { fill: currentColor; stroke: none; animation: dvLed 2.8s linear infinite; }
@keyframes apWave { 0%, 100% { opacity: .22; } 50% { opacity: 1; } }
.dv .w1 { animation: apWave 2.4s ease-in-out infinite; }
.dv .w2 { animation: apWave 2.4s ease-in-out .5s infinite; }
@keyframes schMove {
  0% { transform: translate(0, 0); opacity: 0; }
  12% { opacity: .95; }
  85% { opacity: .95; }
  100% { transform: translate(var(--tx, 0), var(--ty, 0)); opacity: 0; }
}
.sch .mv { fill: #FFB26B; stroke: none; animation: schMove var(--dur, 3.2s) linear infinite; animation-delay: var(--dly, 0s); }
.dv .pulse { fill: #FFB26B; stroke: none; opacity: 0; }
@supports (offset-path: path("M0 0 L1 1")) {
  @keyframes railRun {
    0% { offset-distance: 0%; opacity: 0; }
    10% { opacity: 1; }
    90% { opacity: 1; }
    100% { offset-distance: 100%; opacity: 0; }
  }
  .dv .pulse { offset-rotate: 0deg; animation: railRun var(--dur, 3s) linear infinite; animation-delay: var(--dly, 0s); }
}

/* ---- the hero rack ---- */
.rack-fig { position: relative; min-width: 0; }
.rack-fig::before {
  content: "";
  position: absolute;
  inset: -8% -12%;
  background: radial-gradient(50% 50% at 50% 46%, rgba(243,112,33,0.14) 0%, transparent 70%);
  pointer-events: none;
}
/* the mark sits behind the iron, big and quiet - a watermark the rack
   stands in front of, not a badge stuck next to a headline */
.rack-mark {
  position: absolute;
  top: 6%;
  inset-inline: -4%;
  width: 108%;
  height: auto;
  opacity: .085;
  filter: brightness(3.4) saturate(0);
  pointer-events: none;
}
.rack-fig .dv-rack { position: relative; width: 100%; height: auto; color: var(--text-2); }
@media (max-width: 1000px) {
  .rack-fig { max-width: 460px; margin: 8px auto 0; opacity: .92; }
}

/* ---- the fabric chain ----
   Three drawn devices joined by their links, the link names on the
   wire. Hovering a card is picking the box up: the panel brightens,
   the LEDs quicken, the uplink glows. */
.fabric-chain {
  display: grid;
  grid-template-columns: 1fr auto 1fr auto 1fr;
  gap: 14px;
  align-items: stretch;
  margin-top: 52px;
}
.fab-card {
  min-width: 0;
  padding: 20px;
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: var(--card);
  transition: transform .5s var(--ease-leo), border-color .5s var(--ease-leo), background .5s var(--ease-leo);
}
.fab-card:hover { transform: translateY(-5px); border-color: rgba(243,112,33,0.32); background: var(--card-2); }
.fab-dev {
  border-radius: var(--r-md);
  border: 1px solid var(--line-soft);
  background:
    radial-gradient(rgba(255,255,255,0.045) 1px, transparent 1px) 0 0 / 14px 14px,
    rgba(0,0,0,0.3);
  padding: 14px;
  margin-bottom: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 118px;
}
.fab-dev .dv { width: 100%; height: auto; color: var(--text-2); transition: color .4s; }
.fab-dev .dv-ap { width: 116px; }
.fab-card:hover .dv { color: var(--text-1); }
.fab-card:hover .dv .led { animation-duration: 1s; }
.fab-card:hover .dv .ic-hot { filter: drop-shadow(0 0 7px rgba(243,112,33,0.75)); }
.fab-card h3 {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 500;
  color: var(--text-1);
  margin-bottom: 7px;
}
.fab-card p { font-size: 14px; line-height: 1.7; color: var(--text-3); }
.fab-link {
  align-self: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  width: 76px;
}
.fab-link::before {
  content: "";
  width: 100%;
  height: 2px;
  background: repeating-linear-gradient(90deg, var(--orange) 0 6px, transparent 6px 13px);
  opacity: .65;
  animation: fabDash 1.1s linear infinite;
}
@keyframes fabDash { to { background-position: 13px 0; } }
[dir="rtl"] .fab-link::before { animation-direction: reverse; }
.fab-link span {
  font-size: 11px;
  letter-spacing: .07em;
  color: var(--orange-bright);
  white-space: nowrap;
}
@media (max-width: 980px) {
  .fabric-chain { grid-template-columns: 1fr; }
  .fab-link { width: auto; flex-direction: row; justify-content: center; gap: 12px; padding: 2px 0; }
  .fab-link::before { width: 44px; }
}

/* ---- the SASE tree: click to dive, so the scroll stays short ---- */
.acc { display: grid; gap: 12px; margin-top: 48px; }
.acc-item {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--card);
  overflow: hidden;
  transition: border-color .45s var(--ease-leo), background .45s var(--ease-leo);
}
.acc-item.open { border-color: rgba(243,112,33,0.32); background: var(--card-2); }
.acc-h { margin: 0; }
.acc-h button {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 19px 24px;
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 500;
  color: var(--text-2);
  text-align: start;
  transition: color .3s;
}
.acc-h button:hover, .acc-item.open .acc-h button { color: var(--text-1); }
.acc-x { position: relative; width: 16px; height: 16px; flex-shrink: 0; }
.acc-x::before, .acc-x::after {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  top: 50%;
  width: 100%;
  height: 1.6px;
  border-radius: 1px;
  background: var(--orange-bright);
  transition: transform .45s var(--ease-leo);
}
.acc-x::after { transform: rotate(90deg); }
.acc-item.open .acc-x::after { transform: rotate(0deg); }
.acc-body {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .55s var(--ease-leo);
}
.acc-item.open .acc-body { grid-template-rows: 1fr; }
.acc-clip { overflow: hidden; }
.acc-strip {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: 28px;
  align-items: center;
  padding: 2px 24px 24px;
}
.acc-strip p { font-size: 14.8px; line-height: 1.75; color: var(--text-3); }
@media (max-width: 860px) { .acc-strip { grid-template-columns: 1fr; gap: 18px; } }

/* ---- the drafting frame every drawing sits in ---- */
.acc-art, .sp-art, .works-art {
  position: relative;
  border-radius: var(--r-md);
  border: 1px solid var(--line-soft);
  /* a drawing board: a grid that reads as ruled paper under the line
     work, and a warm wash from the corner the accent tends to sit in */
  background:
    radial-gradient(90% 80% at 78% 20%, rgba(243,112,33,0.07) 0%, transparent 64%),
    linear-gradient(rgba(255,255,255,0.028) 1px, transparent 1px) 0 0 / 100% 22px,
    linear-gradient(90deg, rgba(255,255,255,0.028) 1px, transparent 1px) 0 0 / 22px 100%,
    #0b0a09;
  padding: 20px;
  overflow: hidden;
}
/* the sheen that crosses a drawing when its card is hovered or open */
.acc-art::before, .sp-art::before, .works-art::before { z-index: 1; }
.acc-item.open .acc-art .sch, .sp-panel.on .sch,
.works-card.in .sch { animation: schWake .8s var(--ease-leo) both; }
@keyframes schWake { from { opacity: 0; transform: scale(.985); } to { opacity: 1; transform: none; } }
.acc-art::before, .sp-art::before, .works-art::before,
.acc-art::after, .sp-art::after, .works-art::after {
  content: "";
  position: absolute;
  width: 17px;
  height: 17px;
  pointer-events: none;
}
.acc-art::before, .sp-art::before, .works-art::before {
  top: 8px;
  inset-inline-start: 8px;
  border-top: 1.5px solid rgba(243,112,33,0.65);
  border-inline-start: 1.5px solid rgba(243,112,33,0.65);
  border-start-start-radius: 4px;
}
.acc-art::after, .sp-art::after, .works-art::after {
  bottom: 8px;
  inset-inline-end: 8px;
  border-bottom: 1.5px solid rgba(243,112,33,0.65);
  border-inline-end: 1.5px solid rgba(243,112,33,0.65);
  border-end-end-radius: 4px;
}

/* ---- spotlight upgrades: icons, the autoplay bar, the CTA ---- */
.sp-tab { position: relative; overflow: hidden; }
/* the icon is the thing you scan, so it gets the room to be scanned */
.sp-tab svg {
  width: 34px;
  height: 34px;
  flex-shrink: 0;
  color: var(--text-2);
  transition: color .35s, transform .35s var(--ease-leo);
}
.sp-tab.on svg { color: var(--text-1); transform: scale(1.06); }
.sp-tab .ic-hot { color: var(--orange); }
.spotlight.sp-auto .sp-tab.on::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  height: 2px;
  background: var(--orange);
  transform: scaleX(0);
  transform-origin: var(--to, left);
  animation: spBar 7s linear forwards;
}
[dir="rtl"] .spotlight.sp-auto .sp-tab.on::after { --to: right; }
@keyframes spBar { to { transform: scaleX(1); } }
.sp-ask { margin-top: 20px; padding: 10px 20px; font-size: 13.5px; }

/* ---- migration: numbers on the track, a runner on the rail ---- */
.ms-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 26px;
  height: 22px;
  margin-inline-end: 10px;
  padding: 0 6px;
  border-radius: 6px;
  background: var(--orange-50);
  border: 1px solid rgba(243,112,33,0.3);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: .04em;
  color: var(--orange-bright);
  vertical-align: 2px;
}
.mig-track::after {
  content: "";
  position: absolute;
  inset-inline-start: 12.5px;
  top: 0;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--orange);
  box-shadow: 0 0 10px rgba(243,112,33,0.8);
  animation: migRun 9s linear infinite;
}
@keyframes migRun {
  0% { top: 2%; opacity: 0; }
  6% { opacity: 1; }
  92% { opacity: 1; }
  100% { top: 97%; opacity: 0; }
}
.mig-step { transition: color .3s; }
.mig-step:hover h3 { color: var(--orange-bright); }

/* ---- one switch kills all of it ---- */
@media (prefers-reduced-motion: reduce) {
  .sch .mv, .dv .pulse { animation: none; opacity: 0; }
  .dv .led, .dv .w1, .dv .w2 { animation: none; }
  .fab-link::before { animation: none; }
  .mig-track::after { animation: none; opacity: 0; }
  .spotlight.sp-auto .sp-tab.on::after { animation: none; }
}

/* the spotlight stage gets the same board treatment behind the panel */
.sp-stage { background: linear-gradient(180deg, var(--card-2), var(--card)); }
.sp-panel { align-items: stretch; }
.sp-copy { display: flex; flex-direction: column; justify-content: center; }
@media (prefers-reduced-motion: reduce) {
  .acc-item.open .acc-art .sch, .sp-panel.on .sch,
  .works-card.in .sch { animation: none; }
}

/* ------------------------------------------------------------------
   How the platform works - six mechanisms, each drawn

   Two columns rather than three: at three across the drawings shrink
   to thumbnails and the line work stops being readable, which defeats
   the point of drawing them.
   ------------------------------------------------------------------ */
.works-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px; margin-top: 64px; }
.works-card {
  margin: 0;
  min-width: 0;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 20px 20px 30px;
  transition: transform .5s var(--ease-leo), border-color .5s var(--ease-leo);
}
.works-card:hover { transform: translateY(-6px); border-color: rgba(243,112,33,0.3); }
.works-art { padding: 18px 20px; }
.works-card figcaption { padding: 0 12px; }
.works-card h3 { font-family: var(--font-display); font-size: 21px; font-weight: 500; margin: 26px 0 12px; color: var(--text-1); }
.works-card p { color: var(--text-3); font-size: 15.5px; line-height: 1.75; }
/* a drawing that needs the whole row - the orbit diagram and the install
   track are single wide arguments, not halves of a pair */
.works-wide { grid-column: 1 / -1; }
.works-wide .works-art { max-width: 880px; margin-inline: auto; }
@media (max-width: 900px) {
  .works-grid { grid-template-columns: 1fr; gap: 22px; }
  .works-art { padding: 12px 10px; }
  .works-card figcaption { padding: 0 4px; }
  .works-card h3 { font-size: 19px; margin-top: 20px; }
}

/* On a phone the board is ~280px wide, and a label drawn at 7 units in a
   320-unit viewBox lands at 6px - the line work survives the shrink, the
   words do not. Below 700px the drawing keeps a legible minimum width and
   the board scrolls instead. direction: ltr so an RTL page still opens the
   drawing at its left edge, where every one of them begins. */
@media (max-width: 700px) {
  .acc-art, .sp-art, .works-art {
    max-width: 100%;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    direction: ltr;
  }
  .acc-art .sch, .sp-art .sch, .works-art .sch { min-width: 460px; }
  .acc-art::-webkit-scrollbar, .sp-art::-webkit-scrollbar, .works-art::-webkit-scrollbar { height: 4px; }
  .acc-art::-webkit-scrollbar-thumb, .sp-art::-webkit-scrollbar-thumb, .works-art::-webkit-scrollbar-thumb {
    background: rgba(243,112,33,0.35);
    border-radius: 2px;
  }
}

/* ------------------------------------------------------------------
   Starlink - the plans, and the footnotes that matter more

   Two plan cards and six notes. The notes are the section: a business
   line's surprises all live in small print, so the small print is set
   at reading size and given its own frame.
   ------------------------------------------------------------------ */
.plan-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; margin-top: 60px; }
.plan-card {
  margin: 0;
  padding: 32px 30px 28px;
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: var(--card);
  transition: border-color .5s var(--ease-leo), transform .5s var(--ease-leo);
}
.plan-card:hover { border-color: rgba(243,112,33,0.3); transform: translateY(-4px); }
/* the plan that is not sold yet says so and steps back */
.plan-soon { border-style: dashed; background: rgba(255,255,255,0.012); }
.plan-soon:hover { border-color: var(--line); transform: none; }
.plan-soon p, .plan-soon .plan-sub { opacity: .72; }
.soon-tag {
  display: inline-block;
  margin-inline-start: 12px;
  vertical-align: 4px;
  padding: 4px 12px;
  border-radius: var(--r-pill);
  border: 1px solid rgba(243,112,33,0.35);
  color: var(--orange-bright);
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .02em;
}
.plan-card h3 { font-family: var(--font-display); font-size: 25px; font-weight: 500; color: var(--text-1); margin: 0; }
.plan-sub { display: block; margin: 6px 0 16px; font-size: 13.5px; color: var(--orange-bright); }
.plan-card p { color: var(--text-3); font-size: 15.5px; line-height: 1.75; margin: 0 0 22px; }
.plan-tiers { display: flex; flex-wrap: wrap; gap: 8px; list-style: none; padding: 0; margin: 0 0 14px; direction: ltr; }
[dir="rtl"] .plan-tiers { justify-content: flex-end; }
.plan-tiers li {
  padding: 7px 14px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  background: rgba(255,255,255,0.02);
  font-size: 13.5px;
  color: var(--text-2);
  font-variant-numeric: tabular-nums;
}
.plan-foot { display: block; font-size: 13px; line-height: 1.6; color: var(--text-4, var(--text-3)); opacity: .8; }

.plan-figs {
  margin-top: 28px;
  padding: 30px 32px 26px;
  border-radius: var(--r-lg);
  border: 1px solid var(--line-soft);
  background:
    radial-gradient(90% 80% at 50% 0%, rgba(243,112,33,0.06) 0%, transparent 64%),
    rgba(0,0,0,0.24);
}
.pf-row { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 20px; }
.pf { text-align: center; }
.pf-v, .plan-tiers li { direction: ltr; unicode-bidi: isolate; }
.pf-v {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(26px, 3.2vw, 38px);
  font-weight: 500;
  color: var(--text-1);
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}
.pf-u { display: block; margin-top: 6px; font-size: 13px; color: var(--text-3); }
/* the disclaimer is part of the figure, not a decoration under it */
.pf-note {
  margin: 24px 0 0;
  padding-top: 18px;
  border-top: 1px solid var(--line-soft);
  font-size: 13px;
  line-height: 1.7;
  color: var(--text-3);
  opacity: .82;
}

.plan-notes { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 22px; margin-top: 30px; }
.plan-note {
  padding: 26px 24px 24px;
  border-radius: var(--r-md);
  border: 1px solid var(--line-soft);
  background: rgba(255,255,255,0.018);
  position: relative;
}
.plan-note::before {
  content: "";
  position: absolute;
  top: 26px;
  inset-inline-start: 0;
  width: 2px;
  height: 20px;
  border-radius: 0 2px 2px 0;
  background: var(--orange);
  opacity: .55;
}
.plan-note h4 { font-size: 16px; font-weight: 500; color: var(--text-1); margin: 0 0 10px; line-height: 1.45; }
.plan-note p { margin: 0; font-size: 14.5px; line-height: 1.75; color: var(--text-3); }

@media (max-width: 1000px) {
  .plan-notes { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 760px) {
  .plan-grid, .plan-notes { grid-template-columns: 1fr; }
  .pf-row { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 26px 16px; }
  .plan-figs { padding: 26px 22px 22px; }
  .plan-card { padding: 26px 22px 24px; }
}

/* ------------------------------------------------------------
   The enquiry honeypot.

   Moved off-screen rather than hidden: a bot worth catching skips a
   field declared display:none, and one that does not skip it fills
   everything it finds. aria-hidden and tabindex="-1" in the markup
   keep it away from a keyboard and off the accessibility tree, so it
   is invisible to every person and present only to something reading
   the HTML.
   ------------------------------------------------------------ */
.cta-form .hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ============================================================
   Touch ergonomics

   This site had no equivalent of the pass the group site already
   carries, and it shows on a phone: footer links 18px tall, the legal
   row 22, an FAQ question 28, and the icon buttons between 38 and 42 -
   all under the 44px both Apple's HIG and WCAG 2.5.8 ask for. Measured
   across eight pages in both languages before writing any of this, and
   none of the small links turned out to be inline in prose, so growing
   them cannot break a sentence.

   Two techniques, chosen per control. Text links and pills get real
   padding, because their box is the target and it should look like it.
   Icon buttons keep their drawn size and get a centred pseudo-element
   instead, so the hit area grows and the design does not.

   Keyed to pointer:coarse rather than a width, because it is the input
   that needs this, not the screen - the same key the group site uses.
   ============================================================ */
@media (pointer: coarse) {
  /* text links: the box is the target */
  .site-footer ul a,
  .footer-bottom a,
  .fg-brands a,
  .breadcrumbs a {
    display: inline-block;
    padding-block: 13px;
    line-height: 1.35;
  }
  .site-footer ul li { margin-bottom: 0; }

  /* the FAQ question is the row, not the line of text sitting in it */
  .faq-item { padding-block: 0; }
  .faq-item summary { padding-block: 20px; }
  .faq-item .answer { padding-bottom: 22px; }

  /* pills: grow the box, leave the type alone */
  .filter-btn,
  .group-tag {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }

  /* The accessibility button floats at the reading-start corner, 52px
     tall and 20px up - the same corner the legal row starts from. At the
     bottom of the page the row sits under it and the first link cannot
     be tapped at its own centre. (The group site does not have this: its
     button is on the reading-end edge, where the short legal row has
     nothing.) Enough room below the row to clear the button's band. */
  .footer-bottom { padding-bottom: 84px; }

  /* icon buttons: the mark keeps its drawn size, only the hit area grows */
  .socials a,
  .menu-toggle,
  .pmodal-close,
  .mobile-drawer .close { position: relative; }

  .socials a::after,
  .menu-toggle::after,
  .pmodal-close::after,
  .mobile-drawer .close::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 44px;
    height: 44px;
    transform: translate(-50%, -50%);
  }
}
