/* ==========================================================================
   Sabertooth — Interactive Component Library  (components.css)
   --------------------------------------------------------------------------
   Loaded AFTER styles.css; consumes its :root brand tokens (--primary, --bg,
   --shadow-lg, --radius-*, etc.).

   Principles
   • Reusable: every piece is a standalone class you add to existing markup.
   • Accessible: all motion is gated behind `prefers-reduced-motion: reduce`;
     hover effects have keyboard equivalents (:focus-visible / :focus-within);
     scroll reveals are progressive-enhancement (content shows without JS).
   • Tunable: behaviour is driven by CSS custom properties you can override
     per-instance (e.g. style="--ticker-duration:60s").

   Contents
     0. Motion tokens + global focus visibility
     1. Hover-lift (.lift)              — cards/tiles rise on hover & focus
     2. Breathing CTA (.breathe/.pulse) — attention pulse for primary actions
     3. Scroll reveal (.reveal/-group)  — fade/slide in on enter (JS: .is-visible)
     4. Ticker / marquee (.ticker)      — infinite horizontal scroll, pausable
     5. Animated underline (.link-underline)
     6. Button sheen (.sheen)
     7. Count-up number (.count)        — JS animates the value
   ========================================================================== */

/* 0. Motion tokens --------------------------------------------------------- */
:root{
  --ease-out:cubic-bezier(.16,1,.3,1);
  --ease-in-out:cubic-bezier(.65,0,.35,1);
  --reveal-distance:26px;
  --reveal-duration:.7s;
  --reveal-delay:0s;
  --stagger:.08s;
  --ticker-duration:40s;
  --ticker-gap:1rem;
  --lift-distance:6px;
}

/* Global keyboard-focus visibility.
   styles.css resets `outline:none` on interactive elements for the mouse;
   this restores a clear, on-brand ring for keyboard users only. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible,
.faq-question:focus-visible,
.quote-fab:focus-visible{
  outline:2px solid var(--primary);
  outline-offset:2px;
  border-radius:4px;
}

/* ==========================================================================
   1. HOVER-LIFT  —  <article class="card lift"> … </article>
   Rises + deepens shadow on hover; keyboard users get it on :focus-within.
   Variants: .lift-sm .lift-lg .lift-tilt   ·  Tune: --lift-distance
   ========================================================================== */
.lift{
  transition:transform .28s var(--ease-out), box-shadow .28s var(--ease-out);
}
.lift:hover,
.lift:focus-visible,
.lift:focus-within{
  transform:translateY(calc(-1 * var(--lift-distance)));
  box-shadow:var(--shadow-lg);
}
.lift:active{ transform:translateY(calc(-.4 * var(--lift-distance))); transition-duration:.1s; }
.lift-sm{ --lift-distance:3px; }
.lift-lg{ --lift-distance:11px; }

/* Subtle 3D tilt — for hero tiles / feature cards */
.lift-tilt{ transition:transform .3s var(--ease-out), box-shadow .3s var(--ease-out); }
.lift-tilt:hover,
.lift-tilt:focus-within{
  transform:translateY(-6px) perspective(900px) rotateX(2.5deg);
  box-shadow:var(--shadow-lg);
}

/* ==========================================================================
   2. BREATHING CTA  —  <a class="btn btn-primary breathe">Book a call</a>
   A slow, subtle scale + expanding glow ring. Pauses on hover so it never
   fights the click. Use sparingly: one breathing element per viewport.
   .pulse = ring-only variant for icons/badges (uses ::after).
   ========================================================================== */
@keyframes breathe{
  0%,100%{ transform:scale(1);     box-shadow:0 0 0 0   rgba(176,29,33,.45); }
  50%    { transform:scale(1.035); box-shadow:0 0 0 14px rgba(176,29,33,0);  }
}
.breathe{ animation:breathe 2.6s var(--ease-in-out) infinite; }
.breathe:hover,
.breathe:focus-visible{ animation-play-state:paused; }

.pulse{ position:relative; }
.pulse::after{
  content:""; position:absolute; inset:0; border-radius:inherit; pointer-events:none;
  box-shadow:0 0 0 0 rgba(176,29,33,.5);
  animation:pulse-ring 2.2s var(--ease-out) infinite;
}
@keyframes pulse-ring{ to{ box-shadow:0 0 0 18px rgba(176,29,33,0); } }

/* ==========================================================================
   3. SCROLL REVEAL  —  <section class="reveal"> … </section>
   Progressive enhancement: content is fully visible by default. The hidden
   start-state applies ONLY under `html.js` (a flag JS sets at boot), and JS
   adds `.is-visible` via IntersectionObserver when the element enters view.
   So with JS off, or before JS runs, nothing is ever hidden.
   Variants: .reveal-down .reveal-left .reveal-right .reveal-scale
   Stagger children: wrap in .reveal-group, give each child style="--i:N".
   Tune: --reveal-distance --reveal-duration --reveal-delay --stagger
   ========================================================================== */
html.js .reveal{
  opacity:0;
  transform:translateY(var(--reveal-distance));
  transition:opacity var(--reveal-duration) var(--ease-out),
             transform var(--reveal-duration) var(--ease-out);
  transition-delay:var(--reveal-delay);
}
html.js .reveal.is-visible{ opacity:1; transform:none; }

html.js .reveal-down  { transform:translateY(calc(-1 * var(--reveal-distance))); }
html.js .reveal-left  { transform:translateX(var(--reveal-distance)); }
html.js .reveal-right { transform:translateX(calc(-1 * var(--reveal-distance))); }
html.js .reveal-scale { transform:scale(.94); }
html.js .reveal-down.is-visible,
html.js .reveal-left.is-visible,
html.js .reveal-right.is-visible,
html.js .reveal-scale.is-visible{ transform:none; }

/* Staggered children (the parent gets .is-visible once) */
html.js .reveal-group > *{
  opacity:0;
  transform:translateY(var(--reveal-distance));
  transition:opacity var(--reveal-duration) var(--ease-out),
             transform var(--reveal-duration) var(--ease-out);
  transition-delay:calc(var(--stagger) * var(--i, 0));
}
html.js .reveal-group.is-visible > *{ opacity:1; transform:none; }

/* ==========================================================================
   4. TICKER / MARQUEE  —  infinite horizontal scroll, pauses on hover/focus
   Markup (two identical tracks for a seamless loop; clone is aria-hidden):
     <div class="ticker">
       <ul class="ticker__track"> …items… </ul>
       <ul class="ticker__track" aria-hidden="true"> …same items… </ul>
     </div>
   Variants: .ticker--reverse .ticker--slow .ticker--fast
   Tune: --ticker-duration --ticker-gap
   ========================================================================== */
.ticker{
  position:relative; display:flex; overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);
}
.ticker__track{
  display:flex; flex-shrink:0; align-items:center; gap:var(--ticker-gap);
  min-width:100%; padding-right:var(--ticker-gap);
  animation:ticker-scroll var(--ticker-duration) linear infinite;
}
@keyframes ticker-scroll{ from{transform:translateX(0)} to{transform:translateX(-100%)} }
.ticker:hover  .ticker__track,
.ticker:focus-within .ticker__track{ animation-play-state:paused; }
.ticker--reverse .ticker__track{ animation-direction:reverse; }
.ticker--slow{ --ticker-duration:64s; }
.ticker--fast{ --ticker-duration:24s; }

/* A ready-made pill for logo/word tickers */
.ticker-chip{
  display:inline-flex; align-items:center; gap:.5rem; white-space:nowrap;
  padding:.6rem 1.25rem; border-radius:var(--radius-pill);
  background:var(--surface); border:1px solid var(--border);
  font-weight:700; font-size:.95rem; color:var(--text-secondary);
}

/* ==========================================================================
   5. ANIMATED UNDERLINE  —  <a class="link-underline"> … </a>
   Underline wipes in from the left on hover/focus.
   ========================================================================== */
.link-underline{ position:relative; }
.link-underline::after{
  content:""; position:absolute; left:0; right:0; bottom:-2px; height:2px;
  background:currentColor; transform:scaleX(0); transform-origin:left;
  transition:transform .28s var(--ease-out);
}
.link-underline:hover::after,
.link-underline:focus-visible::after{ transform:scaleX(1); }

/* ==========================================================================
   6. BUTTON SHEEN  —  <a class="btn btn-primary sheen"> … </a>
   A light glint sweeps across on hover. Decorative only.
   ========================================================================== */
.sheen{ position:relative; overflow:hidden; }
.sheen::before{
  content:""; position:absolute; top:0; left:-120%; width:60%; height:100%;
  background:linear-gradient(110deg,transparent,rgba(255,255,255,.35),transparent);
  transform:skewX(-18deg); transition:left .6s var(--ease-out); pointer-events:none;
}
.sheen:hover::before,
.sheen:focus-visible::before{ left:150%; }

/* ==========================================================================
   7. COUNT-UP  —  <span class="count" data-to="300" data-suffix="+">0</span>
   The value is animated by JS; this just keeps digits from reflowing.
   ========================================================================== */
.count{ font-variant-numeric:tabular-nums; }

/* ==========================================================================
   REDUCED MOTION  —  honour the user's OS setting.
   Disable transforms/looping animation; preserve meaning (shadows, links,
   and ticker content stay reachable as a static, scrollable row).
   ========================================================================== */
@media (prefers-reduced-motion: reduce){
  .lift, .lift-tilt{ transition:box-shadow .2s ease; }
  .lift:hover, .lift:focus-within, .lift:focus-visible,
  .lift-tilt:hover, .lift-tilt:focus-within{ transform:none; }

  .breathe{ animation:none; }
  .pulse::after{ animation:none; box-shadow:none; }

  html.js .reveal,
  html.js .reveal-group > *{ opacity:1 !important; transform:none !important; transition:none; }

  .ticker{ overflow-x:auto; -webkit-mask-image:none; mask-image:none; }
  .ticker__track{ animation:none; }
  .ticker__track[aria-hidden="true"]{ display:none; } /* no duplicate text when static */

  .sheen::before{ display:none; }
  .link-underline::after{ transition:none; }
}

/* ==========================================================================
   8. Modern interaction layer
   scroll progress · shrinking header · nav underline/active · back-to-top
   · toasts · button ripple · magnetic buttons · 3D card tilt · hero parallax
   (all motion gated behind prefers-reduced-motion at the bottom)
   ========================================================================== */

/* 8.1 Scroll progress bar */
.scroll-progress{position:fixed;top:0;left:0;height:3px;width:100%;z-index:1200;pointer-events:none;
  transform:scaleX(var(--p,0));transform-origin:0 50%;
  background:linear-gradient(90deg,var(--primary),#ff6b3d 55%,var(--primary-dark));
  transition:transform .12s linear}

/* 8.2 Shrinking / shadowed header on scroll */
.logo-img{transition:height .3s var(--ease-out)}
.site-header.scrolled{background:rgba(255,255,255,.97);box-shadow:0 8px 28px rgba(20,10,8,.10)}
.site-header.scrolled .header-inner{height:74px}
.site-header.scrolled .logo-img{height:52px}

/* 8.3 Nav link sliding underline + active page state */
.nav-link{position:relative}
.nav-link::after{content:"";position:absolute;left:.9rem;right:.9rem;bottom:.32rem;height:2px;border-radius:2px;
  background:var(--primary);transform:scaleX(0);transform-origin:0 50%;transition:transform .28s var(--ease-out)}
.nav-link:hover::after,.nav-dropdown:hover > .nav-link::after,.nav-link.active::after{transform:scaleX(1)}
.nav-link.active{color:var(--primary)}
.dropdown-item.active{background:var(--secondary);color:var(--primary)}
.mobile-link.active,.mobile-sub.active{color:var(--primary)}

/* 8.4 Back-to-top FAB (bottom-right) */
.to-top{position:fixed;bottom:22px;right:22px;z-index:1090;width:46px;height:46px;border:none;border-radius:50%;
  display:grid;place-items:center;background:var(--primary);color:#fff;cursor:pointer;box-shadow:var(--shadow-lg);
  opacity:0;visibility:hidden;transform:translateY(12px);transition:opacity .3s,transform .3s,background .2s}
.to-top.show{opacity:1;visibility:visible;transform:none}
.to-top:hover{background:var(--primary-dark);transform:translateY(-3px)}
.to-top svg{width:20px;height:20px}

/* 8.5 Toast notifications */
.toast-wrap{position:fixed;top:86px;right:20px;z-index:1300;display:flex;flex-direction:column;gap:.6rem;pointer-events:none}
.toast{display:flex;align-items:center;gap:.65rem;max-width:340px;padding:.85rem 1.15rem;border-radius:var(--radius-md);
  background:var(--dark);color:#fff;font-weight:600;font-size:.92rem;box-shadow:var(--shadow-lg);
  transform:translateX(120%);opacity:0;transition:transform .45s var(--ease-out),opacity .45s}
.toast.show{transform:none;opacity:1}
.toast .toast-ic{flex-shrink:0;display:grid;place-items:center;width:22px;height:22px;border-radius:50%;background:var(--primary)}
.toast .toast-ic svg{width:13px;height:13px}

/* 8.6 Button ripple */
.btn{position:relative;overflow:hidden}
.ripple{position:absolute;border-radius:50%;background:rgba(255,255,255,.5);transform:scale(0);pointer-events:none;
  animation:ripple .6s var(--ease-out)}
.btn-outline .ripple,.btn-outline-dark .ripple,.btn-ghost .ripple{background:rgba(176,29,33,.22)}
@keyframes ripple{to{transform:scale(2.6);opacity:0}}

/* 8.7 Magnetic + 3D tilt helpers (JS sets the transform on pointer move) */
.btn.magnetic{transition:transform .25s var(--ease-out),background .2s,box-shadow .2s}
.tilt-3d{transition:transform .2s var(--ease-out),box-shadow .2s var(--ease-out);will-change:transform}

/* 8.8 Hero background parallax */
.hero-dark-bg{will-change:transform}

@media (prefers-reduced-motion: reduce){
  .scroll-progress,.toast,.to-top,.nav-link::after{transition:none}
  .ripple{display:none}
  .btn.magnetic,.tilt-3d,.hero-dark-bg{transform:none !important}
}

/* ==========================================================================
   9. AEO / GEO answer layer
   direct-answer box · comparison table · market-take callout · author card
   ========================================================================== */

/* 9.1 Direct-answer / definition snippet box (AI snippet bait) */
.answer-box{background:linear-gradient(180deg,#fff, var(--surface));border:1px solid var(--border);
  border-left:4px solid var(--primary);border-radius:var(--radius-md);padding:1.5rem 1.75rem;box-shadow:var(--shadow-sm)}
.answer-box .answer-label{display:inline-flex;align-items:center;gap:.45rem;font-size:.72rem;font-weight:800;letter-spacing:.08em;
  text-transform:uppercase;color:var(--primary);margin-bottom:.5rem}
.answer-box .answer-label svg{width:15px;height:15px}
.answer-box p{font-size:1.06rem;line-height:1.6;color:var(--text);margin:0}
.answer-box p + p{margin-top:.75rem}

/* 9.1b Assessment category sub-heading (assessments hub) */
.cat-group-title{font-size:.8rem;font-weight:800;letter-spacing:.09em;text-transform:uppercase;color:var(--primary);
  margin-top:2.75rem;padding-bottom:.7rem;border-bottom:1px solid var(--border)}
.cat-group-title:first-of-type{margin-top:0}

/* 9.2 Comparison table (SD-WAN vs MPLS, advisor vs direct, etc.) */
.compare-wrap{overflow-x:auto;border:1px solid var(--border);border-radius:var(--radius-md)}
.compare-table{width:100%;border-collapse:collapse;min-width:560px;font-size:.94rem;background:#fff}
.compare-table th,.compare-table td{padding:.85rem 1.1rem;text-align:left;border-bottom:1px solid var(--border);vertical-align:top}
.compare-table thead th{background:var(--dark);color:#fff;font-weight:700;font-size:.9rem}
.compare-table thead th:first-child{background:var(--dark)}
.compare-table tbody th{font-weight:700;color:var(--text);width:30%;background:var(--surface)}
.compare-table tbody tr:last-child td,.compare-table tbody tr:last-child th{border-bottom:none}
.compare-table .yes{color:#1a7f4b;font-weight:700}
.compare-table .no{color:var(--text-muted)}
.compare-table .col-primary{color:var(--primary);font-weight:700}

/* 9.3 Original-data / market-take callout (original opinion for GEO) */
.market-take{background:var(--dark);color:#efeae8;border-radius:var(--radius-md);padding:1.75rem 2rem;position:relative}
.market-take .answer-label{color:#ff8a5c}
.market-take h3{color:#fff;margin:.15rem 0 .6rem;font-size:1.25rem}
.market-take p{color:#cfc7c4;margin:0;font-size:.98rem}
.market-take .source-note{display:block;margin-top:.85rem;font-size:.8rem;color:#9a918e}

/* 9.4 Sources / external citations row */
.sources{font-size:.85rem;color:var(--text-muted);border-top:1px solid var(--border);padding-top:1rem;margin-top:1.5rem}
.sources strong{color:var(--text-secondary)}
.sources a{color:var(--text-secondary);font-weight:600;text-decoration:underline;text-underline-offset:2px}
.sources a:hover{color:var(--primary)}

/* 9.5 Author / E-E-A-T authority card */
.author-card{display:flex;gap:1.25rem;align-items:flex-start;background:#fff;border:1px solid var(--border);
  border-radius:var(--radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm)}
.author-avatar{flex-shrink:0;width:72px;height:72px;border-radius:50%;display:grid;place-items:center;
  background:var(--primary);color:#fff;font-weight:800;font-size:1.5rem}
.author-card h3{margin:0 0 .15rem}
.author-card .author-role{color:var(--primary);font-weight:700;font-size:.9rem;margin-bottom:.6rem}
.author-card p{font-size:.94rem;margin:0;color:var(--text-secondary)}
.author-cred{display:flex;flex-wrap:wrap;gap:.5rem;margin-top:.85rem}
.author-cred span{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-pill);
  padding:.3rem .8rem;font-size:.78rem;font-weight:600;color:var(--text-secondary)}
@media(max-width:560px){.author-card{flex-direction:column}}

/* 9.6 Numbered step list ("how to" / checklist for AI step extraction) */
.step-list{counter-reset:step;display:grid;gap:1rem}
.step-list .step{display:flex;gap:1rem;align-items:flex-start;background:#fff;border:1px solid var(--border);
  border-radius:var(--radius-md);padding:1.25rem 1.5rem}
.step-list .step::before{counter-increment:step;content:counter(step);flex-shrink:0;width:34px;height:34px;border-radius:50%;
  background:var(--primary);color:#fff;font-weight:800;display:grid;place-items:center;font-size:1rem}
.step-list .step h3{margin:.2rem 0 .35rem;font-size:1.05rem}
.step-list .step p{margin:0;font-size:.93rem;color:var(--text-secondary)}

/* ── Featured technology providers (partners page) ───────────── */
.vendor-verticals{display:grid;gap:2.5rem}
.vendor-vertical-head{display:flex;align-items:baseline;flex-wrap:wrap;gap:.4rem .8rem;margin-bottom:1.25rem;padding-bottom:.7rem;border-bottom:1px solid var(--border)}
.vendor-vertical-tag{font-size:.92rem;font-weight:800;letter-spacing:.05em;text-transform:uppercase;color:var(--primary)}
.vendor-vertical-sub{font-size:.85rem;font-weight:600;color:var(--text-muted)}
.vendor-card{display:flex;flex-direction:column;background:#fff;border:1px solid var(--border);border-radius:var(--radius-lg);padding:1.5rem 1.6rem;transition:.25s;height:100%}
.vendor-card:hover{box-shadow:var(--shadow-md);transform:translateY(-4px);border-color:transparent}
.vendor-logo{height:52px;display:flex;align-items:center;margin-bottom:1.1rem}
.vendor-logo img{max-height:46px;max-width:190px;width:auto;object-fit:contain}
.vendor-card h3{margin:0 0 .5rem;font-size:1.15rem}
.vendor-card p{font-size:.9rem;color:var(--text-secondary);margin:0 0 1rem;flex:1 1 auto}
.vendor-card .card-link{margin-top:auto}
.vendor-disclaimer{margin-top:3rem;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-md);padding:1.6rem 1.85rem}
.vendor-disclaimer h4{font-size:.78rem;font-weight:800;text-transform:uppercase;letter-spacing:.12em;color:var(--primary);margin:0 0 .75rem}
.vendor-disclaimer p{font-size:.85rem;color:var(--text-muted);line-height:1.65;margin:0}
.vendor-disclaimer p + p{margin-top:.7rem}
