/* ==========================================================================
   IroxPro — design tokens + component layer on top of Tailwind (CDN).
   Every color is a CSS custom property so the dark/light theme switch is
   instant and total: nothing here is theme-specific markup, it's all vars.
   ========================================================================== */

:root {
  /* ---- surfaces & text (DARK, default) ---- */
  --bg-canvas: #07090e;
  --bg-card: #111827;
  --bg-card-soft: #1a2436;
  --bg-alt: rgba(255, 255, 255, 0.02);
  --surface-1: rgba(255, 255, 255, 0.035);
  --surface-2: rgba(255, 255, 255, 0.07);
  --edge: rgba(148, 163, 184, 0.14);
  --edge-strong: rgba(148, 163, 184, 0.3);
  --ink: #f1f5f9;
  --muted: #94a3b8;
  /* #64748b (slate-500) measured 4.18:1 on this canvas — just under the
     4.5:1 WCAG AA minimum for small text, which is exactly how --subtle
     gets used (footer copyright, legal "Last Updated" dates, uppercase
     eyebrow labels). Lightened to clear AA with a small margin (5.06:1)
     while staying visually distinct from --muted. */
  --subtle: #73819a;
  --shadow-1: 0 10px 30px rgba(0, 0, 0, 0.45);
  --shadow-2: 0 30px 70px rgba(0, 0, 0, 0.55);
  --scrollbar-track: #07090e;
  --scrollbar-thumb: #1e293b;
  --glow-blob-blue: rgba(37, 99, 235, 0.15);
  --glow-blob-cyan: rgba(6, 182, 212, 0.15);

  /* ---- brand accents (identical in both themes) ---- */
  --accent-blue: #2563eb;
  --accent-cyan: #06b6d4;

  /* Heading accent — matches the Customer Portal's orange. Scoped to
     heading highlight text and the section-title underline only; the
     broader UI (buttons, card borders, nav, icons) stays on the blue/
     cyan --theme-accent system restored two turns ago. */
  --accent-orange: #f58520;
  --accent-orange-a08: rgba(245, 133, 32, 0.08);
  --accent-orange-a15: rgba(245, 133, 32, 0.15);
  --accent-orange-a25: rgba(245, 133, 32, 0.25);
  --accent-orange-a40: rgba(245, 133, 32, 0.4);
  /* Secondary accent — deep navy, distinct from the brighter --accent-blue
     used in gradients/nav; used for the hero overlay and dark HUD-style
     surfaces. */
  --accent-navy: #1b315d;

  /* Generic (non-per-service) borders/underlines/icons — fixed blue/cyan
     in both themes. Deliberately NOT applied to headings (kept on --ink
     for readability) and NOT applied to the per-service Managed IT/VPN/
     VPS blue/cyan/indigo system, which stays fixed so each service keeps
     its own identity. */
  --theme-accent: var(--accent-blue);
  --theme-accent-bar: var(--accent-cyan);
  --theme-accent-glow: rgba(37, 99, 235, 0.25);
  --theme-icon-accent: var(--accent-cyan);
  /* glow strength for button/card accent shadows — flat across both themes
     (the softer, theme-split --glow-blob-* tokens remain separate; those
     drive ambient background blobs and stay tuned per-theme so light mode
     doesn't pick up a muddy tint) */
  --glow-blue: rgba(37, 99, 235, 0.35);
  --glow-cyan: rgba(6, 182, 212, 0.35);
  --accent-blue-a08: rgba(37, 99, 235, 0.08);
  --accent-blue-a15: rgba(37, 99, 235, 0.15);
  --accent-blue-a25: rgba(37, 99, 235, 0.25);
  --accent-blue-a40: rgba(37, 99, 235, 0.4);
  --accent-cyan-a08: rgba(6, 182, 212, 0.08);
  --accent-cyan-a15: rgba(6, 182, 212, 0.15);
  --accent-cyan-a25: rgba(6, 182, 212, 0.25);
  --accent-cyan-a40: rgba(6, 182, 212, 0.4);

  /* Cloud/VPS identity accent — indigo, part of the same brand family */
  --accent-indigo: #6366f1;
  --accent-indigo-a08: rgba(99, 102, 241, 0.08);
  --accent-indigo-a15: rgba(99, 102, 241, 0.15);
  --accent-indigo-a25: rgba(99, 102, 241, 0.25);
  --accent-indigo-a40: rgba(99, 102, 241, 0.4);

  /* terminal/HUD chrome is intentionally theme-independent — always dark */
  --hud-bg: #1b2a4a;
  --hud-bg-soft: #223458;
  --hud-ink: #d6ecff;
  --hud-muted: #5b7089;

  /* glass-morphism accent border — used on table chrome and other elevated surfaces */
  --border-glass: rgba(255, 255, 255, 0.08);

  /* data tables */
  --table-head-bg: var(--bg-card-soft);
  --table-row-alt: rgba(255, 255, 255, 0.03);
  --table-row-hover: rgba(6, 182, 212, 0.06);

  /* header pill — near-opaque so page content never bleeds through while
     scrolling; distinct from --surface-2 (which stays very translucent for
     badges/toggles/etc. elsewhere and must not be affected by this fix) */
  --header-bg: rgba(10, 15, 29, 0.95);
}

[data-theme="light"] {
  --bg-canvas: #ffffff;
  --bg-card: #ffffff;
  --bg-card-soft: #ffffff;
  --bg-alt: #ffffff;
  --surface-1: rgba(15, 23, 42, 0.025);
  --surface-2: rgba(15, 23, 42, 0.04);
  --edge: rgba(15, 23, 42, 0.08);
  --edge-strong: rgba(15, 23, 42, 0.15);
  --ink: #0f172a;
  --muted: #475569;
  --subtle: #64748b;
  --shadow-1: 0 4px 20px -2px rgba(0, 0, 0, 0.05);
  --shadow-2: 0 12px 40px -6px rgba(0, 0, 0, 0.08);
  --scrollbar-track: #ffffff;
  --scrollbar-thumb: #e2e8f0;
  --glow-blob-blue: rgba(37, 99, 235, 0.05);
  --glow-blob-cyan: rgba(6, 182, 212, 0.05);

  /* glass-morphism accent border — a touch crisper than --edge for table chrome */
  --border-glass: rgba(15, 23, 42, 0.1);

  /* data tables — crisp tinted blue-gray head, near-invisible zebra */
  --table-head-bg: #eef4fc;
  --table-row-alt: rgba(15, 23, 42, 0.022);
  --table-row-hover: rgba(37, 99, 235, 0.045);

  /* header pill — near-opaque so page content never bleeds through */
  --header-bg: rgba(255, 255, 255, 0.95);
}

/* Instant, no-transition swap on the very first paint; after that we allow
   soft transitions on repaint-cheap properties only. */
html {
  scroll-behavior: smooth;
  color-scheme: dark;
}
[data-theme="light"] {
  color-scheme: light;
}
body {
  background-color: var(--bg-canvas);
  line-height: 1.65;
  transition: background-color 0.3s ease;
}

/* Heading font stack — matches the Customer Portal. Overrides the
   Tailwind-generated ".font-display" utility (same specificity; this
   rule wins because assets/css/site.css loads after the Tailwind CDN
   script that injects it). Every h1-h4 across the site carries the
   "font-display" class already, so this alone re-fonts every heading. */
.font-display {
  font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
}
/* Sleeker heading weight — Tailwind's font-bold/font-extrabold utility
   classes outrank a plain element selector, so !important is needed
   here to actually win. */
h1, h2, h3 {
  font-weight: 600 !important;
  /* Balances line lengths instead of leaving a short orphaned last word
     (e.g. "Empowering businesses through smart IT" stranding "IT" on
     its own line) — supported browsers only, graceful no-op elsewhere. */
  text-wrap: balance;
}
body,
body * {
  transition-property: background-color, border-color, color, box-shadow;
  transition-duration: 0.25s;
  transition-timing-function: ease;
}

::selection {
  background: var(--accent-blue-a40);
  color: var(--ink);
}

/* Visible keyboard-focus ring, site-wide, on every interactive element */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--accent-cyan);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ==========================================================================
   Buttons — shared primitives (centralizes radius/height/padding/hover
   so every CTA on every page draws from the same scale).
   ========================================================================== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  border-radius: 999px;
  font-weight: 600;
  font-size: 0.875rem;
  line-height: 1;
  padding: 0.875rem 1.75rem;
  white-space: nowrap;
  transition: transform 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}
/* ==========================================================================
   Eyebrow tags, badges/pills, and legacy text-highlight compatibility
   ========================================================================== */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  color: var(--accent-cyan);
}
.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  border-radius: 999px;
  padding: 0.25rem 0.75rem;
  font-size: 0.6875rem;
  font-weight: 700;
  background: var(--accent-orange-a15);
  color: var(--accent-orange);
  border: 1px solid var(--accent-orange-a25);
}

/* Card icons — glow tuned to whichever accent color the icon itself uses
   (blue/cyan/indigo), via currentColor, so it never mismatches. Lucide
   renders each icon as an inline <svg class="lucide ...">, so the glow
   uses filter:drop-shadow (text-shadow has no effect on SVG content). */
.lucide {
  filter: drop-shadow(0 0 10px currentColor);
}
.btn:disabled,
.btn[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none !important;
}

/* Scrollbar */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--scrollbar-track); }
::-webkit-scrollbar-thumb { background: var(--scrollbar-thumb); border-radius: 999px; border: 2px solid var(--scrollbar-track); }
* { scrollbar-width: thin; scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track); }

/* ==========================================================================
   Reveal-on-scroll
   ========================================================================== */
[data-reveal] {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1), transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
}
[data-reveal].is-visible { opacity: 1; transform: translateY(0); }

/* ==========================================================================
   Brand logo — assets/img/logo-crop.png is a pre-cropped, 1404x457px,
   properly anti-aliased transparent PNG (verified: smooth 3px alpha
   gradient at the mark's edge, not a hard/aliased cutout) — the source
   file itself is high quality. The rough/pixelated look reported in the
   header was caused by the two rules previously here: both
   "image-rendering: crisp-edges" and "-webkit-optimize-contrast" force
   the browser to use a nearest-neighbour-style scaler intended for
   scaling PIXEL ART UP without blur — applied to a large photographic/
   vector-style logo being scaled DOWN by ~92% (1404px source to a
   36-40px display height), it does the opposite of what was intended
   and produces jagged, aliased edges. Removing both and leaving
   image-rendering at its default lets the browser use its normal
   high-quality (bilinear/bicubic) downscaling, which is what actually
   renders a large source cleanly at a small display size.
   ========================================================================== */
.brand-logo {
  width: auto;
  object-fit: contain;
  display: block;
}

/* Footer logo — assets/img/logo-footer-crop.png, a tight crop of
   logo1.png's own visible mark (logo1.png has ~33% transparent padding
   above and ~13% to the left baked into the file, which was throwing
   off top/left alignment against the column headings and contact text
   no matter what CSS was applied to the <img> box). The crop's render
   height (36px) reproduces the exact same visible size logo1.png was
   already rendering at h-[110px] — nothing was actually enlarged or
   shrunk, only the invisible padding was removed. */
.footer-logo {
  max-height: 42px;
  width: auto;
  margin-top: 0;
  display: block;
}


/* ==========================================================================
   Floating pill navbar
   ========================================================================== */
#site-header {
  z-index: 9999 !important;
  transition: box-shadow 0.3s ease, background-color 0.3s ease, border-color 0.3s ease, top 0.3s ease;
}
/* Near-opaque background, not the very translucent --surface-2 the
   bg-surface2 utility class supplies — page content must never show
   through the header while scrolling. #nav-pill's id selector already
   outranks the class, so no !important is needed, but it's included for
   certainty since this rule is safety-critical. */
#nav-pill {
  background: var(--header-bg) !important;
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
}
#nav-pill.is-scrolled {
  background: var(--header-bg) !important;
  box-shadow: var(--shadow-2);
  border-color: var(--edge-strong);
}
#mobile-nav {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.35s ease, opacity 0.3s ease;
  opacity: 0;
}
#mobile-nav > div {
  background: var(--header-bg) !important;
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
}
#mobile-nav.is-open { max-height: 34rem; opacity: 1; }

/* Mobile-only header fix: below the lg breakpoint (1024px) the centered
   <nav> is display:none, and its "auto" grid track doesn't reliably
   collapse to zero across browsers — leaving the theme-toggle/hamburger
   group visually stranded nearer the middle than the true right edge.
   Overriding to a simple flex/justify-between for mobile only guarantees
   logo-flush-left, controls-flush-right, with zero effect on desktop
   (which keeps the original 3-column grid untouched above 1024px). */
@media (max-width: 1023px) {
  #nav-pill {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
}

.nav-link { position: relative; }
.nav-link[data-active="true"] { color: var(--accent-cyan); }
.nav-link::after {
  content: "";
  position: absolute;
  left: 14px; right: 14px; bottom: 2px;
  height: 2px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--accent-blue), var(--accent-cyan));
  transform: scaleX(0);
  opacity: 0;
  transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.25s ease;
}
.nav-link:hover::after {
  transform: scaleX(1);
  opacity: 0.55;
  box-shadow: 0 0 8px var(--glow-cyan);
}
.nav-link[data-active="true"]::after {
  transform: scaleX(1);
  opacity: 1;
  box-shadow: 0 0 8px var(--glow-cyan);
}

/* Theme toggle switch */
.theme-toggle {
  position: relative;
  width: 52px;
  height: 30px;
  border-radius: 999px;
  background: var(--surface-2);
  border: 1px solid var(--edge);
  cursor: pointer;
  flex-shrink: 0;
}
.theme-toggle .knob {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 22px;
  height: 22px;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--accent-blue), var(--accent-cyan));
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
[data-theme="light"] .theme-toggle .knob { transform: translateX(22px); }
.theme-toggle .knob svg { width: 12px; height: 12px; }
.theme-toggle .icon-sun,
.theme-toggle .icon-moon {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  color: var(--subtle);
}
.theme-toggle .icon-moon { left: 7px; }
.theme-toggle .icon-sun { right: 7px; }

/* ==========================================================================
   HUD / terminal widget chrome (theme-independent — always dark glass)
   ========================================================================== */
.hud-panel {
  background: linear-gradient(180deg, var(--hud-bg-soft), var(--hud-bg));
  border: 1px solid rgba(148, 163, 184, 0.16);
  border-radius: 1.5rem;
  box-shadow: 0 30px 70px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(255, 255, 255, 0.02) inset;
  overflow: hidden;
  position: relative;
}
.hud-panel::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 15% -10%, var(--accent-blue-a15), transparent 55%),
    radial-gradient(circle at 100% 110%, var(--accent-cyan-a15), transparent 55%);
  pointer-events: none;
}
.hud-titlebar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 16px;
  border-bottom: 1px solid rgba(148, 163, 184, 0.12);
  position: relative;
}
.hud-dot { width: 10px; height: 10px; border-radius: 999px; }
.hud-body {
  padding: 20px;
  font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
  color: var(--hud-ink);
  position: relative;
}
.hud-caret {
  display: inline-block;
  width: 7px;
  height: 15px;
  background: var(--accent-cyan);
  margin-left: 2px;
  vertical-align: -2px;
  animation: irox-caret 1s steps(1) infinite;
  box-shadow: 0 0 8px var(--accent-cyan);
}
@keyframes irox-caret { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }

.hud-line { min-height: 1.6em; }
.hud-prompt { color: #4ade80; }
.hud-muted-line { color: var(--hud-muted); }

/* ==========================================================================
   Data tables — pricing / feature-comparison / resource-spec
   Shared design system across Managed IT, VPN, VPS and Pricing pages.
   ========================================================================== */
.data-table-wrap {
  border-radius: 1.25rem;
  border: 1px solid var(--border-glass);
  background: var(--bg-card);
  box-shadow: var(--shadow-1);
  overflow: hidden;
}
.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
}
.data-table thead th {
  background: linear-gradient(180deg, var(--accent-blue-a08), transparent), var(--table-head-bg);
  color: var(--ink);
  font-weight: 700;
  text-align: left;
  padding: 1.1rem 1.5rem;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  border-bottom: 1px solid var(--border-glass);
  box-shadow: inset 0 -2px 0 0 var(--accent-cyan-a25);
  white-space: nowrap;
}
.data-table tbody td {
  padding: 1rem 1.5rem;
  color: var(--muted);
  border-bottom: 1px solid var(--border-glass);
  vertical-align: middle;
}
.data-table tbody tr:last-child td {
  border-bottom: none;
}
.data-table tbody tr:nth-child(even) {
  background: var(--table-row-alt);
}
.data-table tbody tr {
  transition: background-color 0.2s ease;
}
.data-table tbody tr:hover {
  background: var(--table-row-hover);
}
.data-table tbody td:first-child {
  font-weight: 600;
  color: var(--ink);
  box-shadow: inset 3px 0 0 transparent;
  transition: box-shadow 0.2s ease;
}
.data-table tbody tr:hover td:first-child {
  box-shadow: inset 3px 0 0 var(--accent-cyan-a40);
}
.data-table .col-featured {
  background: var(--accent-cyan-a08);
  box-shadow: inset 3px 0 0 var(--accent-cyan);
}
.data-table thead th.col-featured {
  background: linear-gradient(180deg, var(--accent-cyan-a15), var(--accent-cyan-a08));
  color: var(--accent-cyan);
  box-shadow: inset 3px 0 0 var(--accent-cyan), 0 0 24px -8px var(--accent-cyan-a40);
}
.data-table tbody tr:nth-child(even) .col-featured {
  background: var(--accent-cyan-a15);
}
.data-table tbody tr:hover .col-featured {
  background: var(--accent-cyan-a25);
}

/* ==========================================================================
   Bento grid / card component
   ".card" is a plain alias — same component, so either class name works.
   ========================================================================== */
.bento-card,
.card {
  position: relative;
  border-radius: 1.75rem;
  border: 1px solid var(--edge);
  background: var(--bg-card);
  box-shadow: var(--shadow-1);
  overflow: hidden;
  transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.35s ease, box-shadow 0.35s ease;
}
/* Bottom accent bar — flush to the card edge, expands in on hover */
.bento-card::after,
.card::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 3px;
  background: var(--theme-accent-bar);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
  pointer-events: none;
}
.bento-card:hover,
.card:hover {
  transform: translateY(-6px);
  border-color: rgba(37, 99, 235, 0.45);
  box-shadow: 0 20px 45px rgba(37, 99, 235, 0.2);
}
.bento-card:hover::after,
.card:hover::after {
  transform: scaleX(1);
}

/* ==========================================================================
   Service card — ONE reusable component for the three "What We Run" cards
   (and anywhere else a service needs to be introduced). Built on .bento-card
   for surface/border/shadow/hover; only the two --card-accent-* custom
   properties vary per instance (set inline), so every card is guaranteed
   identical structure, spacing and hierarchy.
   ========================================================================== */
.service-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 2rem;
}
.service-card-icon {
  width: 3.25rem;
  height: 3.25rem;
  border-radius: 1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  background: var(--card-accent-15, var(--accent-cyan-a15));
  border: 1px solid var(--card-accent-25, var(--accent-cyan-a25));
  margin-bottom: 1.5rem;
}
.service-card-title {
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--ink);
  transition: color 0.3s ease;
}
.service-card-desc {
  margin-top: 0.75rem;
  font-size: 0.875rem;
  color: var(--muted);
  line-height: 1.65;
  flex-grow: 1;
}
.service-card-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 1.5rem;
}
.service-card-badges span {
  border-radius: 0.5rem;
  background: var(--surface-1);
  border: 1px solid var(--edge);
  padding: 0.25rem 0.625rem;
  font-size: 0.625rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--ink);
}
.service-card-cta {
  margin-top: 1.5rem;
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--card-accent, var(--accent-cyan));
}
.service-card-cta i {
  transition: transform 0.3s ease;
}
.service-card:hover .service-card-cta i,
.bento-card:hover .service-card-cta i {
  transform: translateX(4px);
}

/* ==========================================================================
   Audience card — "Built for every stage." Same surface/lift as .bento-card,
   with the shared blue/cyan --theme-accent bar rather than the per-service
   blue/cyan/indigo system used elsewhere.
   ========================================================================== */
.audience-card {
  position: relative;
  border-radius: 1.75rem;
  border: 1px solid var(--edge);
  background: var(--bg-card);
  box-shadow: var(--shadow-1);
  overflow: hidden;
  transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.35s ease, box-shadow 0.35s ease;
}
.audience-card::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 3px;
  background: var(--theme-accent-bar);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
  pointer-events: none;
}
.audience-card:hover {
  transform: translateY(-6px);
  border-color: var(--theme-accent);
  box-shadow: 0 15px 40px var(--theme-accent-glow);
}
.audience-card:hover::after {
  transform: scaleX(1);
}

/* Shared accent icon color (cyan). Pairs with .audience-card / edge-style
   feature boxes; the per-service Managed IT/VPN/VPS cards keep their own
   fixed blue/cyan/indigo instead. */
.icon-theme-accent {
  color: var(--theme-icon-accent);
}

/* ==========================================================================
   Section title — centered heading with a short gradient underline, used
   on section intros that don't already carry their own eyebrow line.
   ========================================================================== */
.section-title {
  text-align: center;
}
.section-title h2 {
  position: relative;
  display: inline-block;
  padding-bottom: 1.25rem;
}
.section-title h2::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 60px;
  height: 3px;
  transform: translateX(-50%);
  border-radius: 2px;
  background: var(--accent-orange);
}

/* ==========================================================================
   Homepage hero — single permanent hero (index.html). Subtle technical
   grid + a decorative network-node SVG sit behind the content; both are
   homepage-only and intentionally restrained (no per-frame JS).
   ========================================================================== */
/* Hero background grid — a smooth, fully-graduated radial fade (no flat
   "core" before it starts fading) so the pattern reads as soft ambient
   texture rather than a rectangular panel at any viewport size. Opacity
   is intentionally low and tuned per theme, since faint grey lines are
   more visually assertive against a light background than against dark. */
.hero-grid {
  background-image:
    linear-gradient(var(--edge) 1px, transparent 1px),
    linear-gradient(90deg, var(--edge) 1px, transparent 1px);
  background-size: 56px 56px;
  mask-image: radial-gradient(ellipse 80% 70% at 50% 25%, black 0%, transparent 70%);
  -webkit-mask-image: radial-gradient(ellipse 80% 70% at 50% 25%, black 0%, transparent 70%);
  opacity: 0.35;
}
[data-theme="light"] .hero-grid {
  opacity: 0.16;
}

/* Light-mode-only hero atmosphere. Dark mode already reads as premium via
   the canvas/glow-blob tokens as-is, so nothing here touches dark mode —
   these rules only fire under [data-theme="light"], scoped to #hero so no
   other page's identical glow-blob/eyebrow-pill markup is affected. */
[data-theme="light"] #hero .animate-float-slow {
  background-color: rgba(37, 99, 235, 0.10);
}
[data-theme="light"] #hero .animate-float-slower {
  background-color: rgba(6, 182, 212, 0.10);
}
[data-theme="light"] #hero .hero-eyebrow {
  box-shadow: 0 0 24px -6px rgba(6, 182, 212, 0.35);
}

/* Network graph — a fixed, softly-glowing topology rather than a
   continuously pulsing one. The single entrance fade comes from the
   sitewide [data-reveal] mechanism (applied to the <svg> itself), not a
   looping keyframe — "no constant animation" per design direction. */
.hero-node {
  filter: drop-shadow(0 0 6px rgba(6, 182, 212, 0.55));
}
.hero-node-primary {
  filter: drop-shadow(0 0 10px rgba(6, 182, 212, 0.75));
}

/* The graph's own edge fade — this is what stops its rectangular viewBox
   from reading as a hard-edged box against the canvas (most visible in
   dark mode, where line/node contrast against near-black is highest).
   Opacity is intentionally asymmetric: dark mode needs real visibility,
   light mode already reads cleanly at a much lower value and would look
   heavy-handed at the same opacity dark mode needs. */
.hero-network-graph {
  /* Generous black core (60% of the ellipse's own radius) so every actual
     node sits fully opaque — the previous mask's black-stop was small
     enough that most nodes fell into the fade zone, which is what made
     lines look like they dangled into empty space. Only the true empty
     margin beyond the node cluster fades out now. */
  mask-image: radial-gradient(ellipse 85% 85% at 50% 50%, black 60%, transparent 100%);
  -webkit-mask-image: radial-gradient(ellipse 85% 85% at 50% 50%, black 60%, transparent 100%);
}
/* Desktop: nodes and lines get independent opacity so nodes stay clearly
   visible while lines stay a subtle connective texture — a single blanket
   opacity on the whole graph washed nodes out at the low value lines need,
   especially in light mode. Below lg, the Tailwind opacity-[...] utilities
   on the <svg> itself still fade the whole graph as one soft background
   texture, which is the right call at that size. */
@media (min-width: 1024px) {
  .hero-lines { opacity: 0.55; }
  .hero-nodes { opacity: 0.9; }
  [data-theme="light"] .hero-lines { opacity: 0.32; }
  [data-theme="light"] .hero-nodes { opacity: 0.85; }
}

/* ==========================================================================
   Homepage service slider — full-image cinematic carousel (index.html only).
   Hand-rolled, dependency-free, matching the rest of the site's approach
   (no Swiper/Bootstrap Carousel). Distinct "svc-" namespace so it can't
   collide with anything on another page.
   ========================================================================== */
.svc-slider-viewport {
  position: relative;
  height: 440px;
  border-radius: 1.5rem;
  overflow: hidden;
  border: 1px solid var(--edge);
  box-shadow: var(--shadow-2);
  background: #05070c;
}
@media (min-width: 640px) { .svc-slider-viewport { height: 520px; } }
@media (min-width: 1024px) { .svc-slider-viewport { height: 600px; } }

.svc-slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.8s ease;
}
.svc-slide.is-active {
  opacity: 1;
  visibility: visible;
  z-index: 1;
}
.svc-slide-media {
  position: absolute;
  inset: 0;
}
.svc-slide-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}
/* Dark on the text side (left), fading out toward the right so the
   photo stays clearly visible — never an almost-black image. */
.svc-slide-scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, rgba(5, 7, 12, 0.90) 0%, rgba(5, 7, 12, 0.55) 45%, rgba(5, 7, 12, 0.12) 100%);
}
.svc-slide-content {
  position: relative;
  z-index: 2;
  height: 100%;
  display: flex;
  align-items: center;
  padding: 2rem 1.5rem;
}
@media (min-width: 640px) { .svc-slide-content { padding: 3rem; } }
@media (min-width: 1024px) { .svc-slide-content { padding: 4rem 4.5rem; } }

/* Small content movement on activation — fade + a short rise, never a
   zoom/scale on the photo itself. */
.svc-slide-content > div {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: 0.15s;
}
.svc-slide.is-active .svc-slide-content > div {
  opacity: 1;
  transform: translateY(0);
}

.svc-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 10;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(5, 7, 12, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.15);
  color: #fff;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: background-color 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}
.svc-arrow:hover {
  background: rgba(5, 7, 12, 0.8);
  border-color: var(--accent-cyan);
  transform: translateY(-50%) scale(1.06);
}
.svc-arrow.left { left: 0.875rem; }
.svc-arrow.right { right: 0.875rem; }

/* Dots sit below the photo, on the page's own background, so — unlike
   the arrows — they need theme-aware color rather than a fixed white. */
.svc-dot {
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--edge-strong);
  transition: background-color 0.3s ease, width 0.3s ease;
}
.svc-dot.is-active {
  width: 22px;
  background: linear-gradient(90deg, var(--accent-blue), var(--accent-cyan));
}

@media (prefers-reduced-motion: reduce) {
  .svc-slide { transition: none; }
  .svc-slide-content > div { transition: none; transform: none; opacity: 1; }
}

/* ==========================================================================
   Section quick-nav (pill bar with a sliding indicator) — used for in-page
   scroll-spy navigation, e.g. the it-network.html section jump-links.
   ========================================================================== */
.tab-btn {
  position: relative;
  z-index: 1;
  color: var(--muted);
  transition: color 0.3s ease;
}
.tab-btn[aria-selected="true"] { color: #fff; }
.tab-indicator {
  position: absolute;
  top: 4px;
  bottom: 4px;
  left: 0;
  border-radius: 999px;
  background: var(--accent-orange);
  box-shadow: 0 8px 20px var(--accent-orange-a40);
  transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1), width 0.35s cubic-bezier(0.4, 0, 0.2, 1);
  z-index: 0;
}

/* ==========================================================================
   Pricing cycle toggle (reused across pricing.html + previews)
   ========================================================================== */
.cycle-toggle {
  position: relative;
  width: 56px;
  height: 30px;
  border-radius: 999px;
  background: var(--surface-2);
  border: 1px solid var(--edge);
  cursor: pointer;
}
.cycle-toggle .knob {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 22px;
  height: 22px;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--accent-blue), var(--accent-cyan));
  box-shadow: 0 2px 10px var(--accent-blue-a40);
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.cycle-toggle input:checked ~ .knob { transform: translateX(26px); }
.cycle-toggle input { position: absolute; inset: 0; opacity: 0; cursor: pointer; margin: 0; }

/* ==========================================================================
   Feature image card — glassmorphism frame for the Managed IT / RoxVPN
   feature-section images (index.html, it-network.html, vpn.html)
   ========================================================================== */
.feature-image-card {
  position: relative;
  border-radius: 16px;
  border: 1px solid rgba(245, 133, 32, 0.25);
  background: #0f172a;
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.6), 0 0 25px rgba(245, 133, 32, 0.12);
  overflow: hidden;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.feature-image-card img,
.feature-image-card video {
  width: 100%;
  height: 100%;
  max-height: 420px;
  display: block;
  object-fit: cover;
}
.feature-image-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 25px 50px rgba(0, 0, 0, 0.8), 0 0 35px rgba(245, 133, 32, 0.25);
}

/* ==========================================================================
   Download card — WireGuard client-setup panel (pricing.html)
   ========================================================================== */
.download-card {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  border-radius: 1rem;
  border: 1px solid var(--edge);
  background: var(--surface1);
  padding: 0.875rem 1rem;
  transition: border-color 0.25s ease, transform 0.25s ease, background-color 0.25s ease;
}
.download-card:hover {
  border-color: var(--accent-cyan);
  background: var(--accent-cyan-a08);
  transform: translateY(-2px);
}
.download-card-icon {
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 0.75rem;
  background: var(--accent-cyan-a15);
  border: 1px solid var(--accent-cyan-a25);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--accent-cyan);
  flex-shrink: 0;
}

.discount-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  border-radius: 999px;
  background: rgba(74, 222, 128, 0.12);
  color: #4ade80;
  font-size: 11px;
  font-weight: 800;
  padding: 2px 9px;
  border: 1px solid rgba(74, 222, 128, 0.25);
}

/* ==========================================================================
   Styled range slider (VPS resource configurator)
   ========================================================================== */
input[type="range"].irox-slider {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 6px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--accent-blue) var(--fill, 50%), var(--surface-2) var(--fill, 50%));
  outline: none;
}
input[type="range"].irox-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 22px;
  height: 22px;
  border-radius: 999px;
  background: var(--bg-card);
  border: 4px solid var(--accent-cyan);
  box-shadow: 0 0 0 6px var(--accent-cyan-a15), 0 4px 14px rgba(0, 0, 0, 0.35);
  cursor: pointer;
  transition: transform 0.15s ease;
}
input[type="range"].irox-slider::-webkit-slider-thumb:hover { transform: scale(1.12); }
input[type="range"].irox-slider::-moz-range-thumb {
  width: 22px; height: 22px; border-radius: 999px;
  background: var(--bg-card); border: 4px solid var(--accent-cyan);
  box-shadow: 0 0 0 6px var(--accent-cyan-a15), 0 4px 14px rgba(0, 0, 0, 0.35);
  cursor: pointer;
}
input[type="range"].irox-slider::-moz-range-track { height: 6px; border-radius: 999px; background: transparent; }

/* ==========================================================================
   Marquee (technologies)
   ========================================================================== */
@keyframes irox-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.animate-marquee { animation: irox-marquee 28s linear infinite; }
.marquee-track:hover .animate-marquee { animation-play-state: paused; }
.marquee-fade {
  mask-image: linear-gradient(to right, transparent, black 8%, black 92%, transparent);
  -webkit-mask-image: linear-gradient(to right, transparent, black 8%, black 92%, transparent);
}
.tech-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--font-display, inherit);
  font-weight: 600;
  font-size: 0.8125rem;
  color: var(--muted);
  opacity: 0.75;
  transition: opacity 0.2s ease, transform 0.2s ease, color 0.2s ease;
}
.marquee-track:hover .tech-badge:not(:hover) { opacity: 0.55; }
.tech-badge:hover {
  opacity: 1;
  color: var(--ink);
  transform: scale(1.03);
}
/* Real brand logos (SVG, authentic colours) sized by height only so each
   keeps its own natural proportions — square marks and wide wordmarks
   sit at the same visual height without being stretched to match widths. */
.tech-badge-logo {
  height: 1.375rem;
  width: auto;
  display: block;
  flex-shrink: 0;
}
.tech-badge-logo-wide { height: 1.125rem; }
/* A few marks (MikroTik, AWS wordmark, pfSense) are near-black and read
   fine on a light background but nearly disappear on the site's
   near-black dark canvas. A small neutral chip keeps them visible in
   dark mode without recolouring the artwork; removed in light mode
   where the logo already has enough contrast on its own. */
.tech-badge-chip {
  background: #f1f5f9;
  border-radius: 0.3rem;
  padding: 2px 4px;
}
[data-theme="light"] .tech-badge-chip {
  background: transparent;
  padding: 0;
}
/* Mirror problem: a few bright saturated marks (Cisco cyan, Meraki
   green, Veeam green) read fine on the dark canvas but wash out against
   white — measured 2.66-2.98:1, under the 3:1 non-text minimum. A small
   dark-neutral chip in light mode only fixes this; no chip in dark mode
   since these already have 6.5:1+ contrast there on their own. */
.tech-badge-chip-light {
  border-radius: 0.3rem;
  padding: 2px 5px;
}
[data-theme="light"] .tech-badge-chip-light {
  background: #1e293b;
}

/* Ambient hero glow blobs */
@keyframes irox-float {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(24px, -30px) scale(1.08); }
}
.animate-float-slow { animation: irox-float 14s ease-in-out infinite; }
.animate-float-slower { animation: irox-float 19s ease-in-out infinite reverse; }

@keyframes irox-gradient-x {
  0%, 100% { background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
}
.animate-gradient-x { background-size: 200% 200%; animation: irox-gradient-x 6s ease infinite; }

/* Sitewide reduced-motion: the continuous ambient/decorative loops (glow
   blobs, logo marquee) have no functional purpose beyond visual motion,
   so they're fully disabled for users who've asked the OS for reduced
   motion — unlike .hero-node/.service-badge above, which already had
   their own reduced-motion rule. */
@media (prefers-reduced-motion: reduce) {
  .animate-float-slow,
  .animate-float-slower,
  .animate-marquee {
    animation: none;
  }
}

/* ==========================================================================
   FAQ accordion
   ========================================================================== */
.faq-toggle[aria-expanded="true"] .faq-chevron { transform: rotate(180deg); }
.faq-toggle .faq-chevron { transition: transform 0.25s ease; }
.faq-panel { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.3s ease; }
.faq-toggle[aria-expanded="true"] + .faq-panel { grid-template-rows: 1fr; }
.faq-panel > div { overflow: hidden; }

/* ==========================================================================
   Cookie consent banner (assets/js/cookie-banner.js injects the markup).
   Fixed, theme-independent — always dark navy with white/grey text and an
   orange accept button, regardless of the site's own dark/light toggle.
   ========================================================================== */
.cookie-banner {
  position: fixed;
  left: 50%;
  bottom: 24px;
  z-index: 9999;
  width: calc(100% - 32px);
  max-width: 900px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 20px;
  background: #0f172a;
  color: #ffffff;
  border-radius: 16px;
  padding: 20px 24px;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.35);
  opacity: 0;
  pointer-events: none;
  transform: translateX(-50%) translateY(12px);
  transition: opacity 0.3s ease, transform 0.3s ease;
}
.cookie-banner.is-visible {
  opacity: 1;
  pointer-events: auto;
  transform: translateX(-50%) translateY(0);
}
.cookie-banner.is-hidden {
  opacity: 0;
  transform: translateX(-50%) translateY(12px);
}
.cookie-banner-text {
  flex: 1 1 320px;
  margin: 0;
  font-size: 0.8125rem;
  line-height: 1.6;
  color: #94a3b8;
}
.cookie-banner-text a {
  color: #ffffff;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.cookie-banner-actions {
  display: flex;
  gap: 12px;
  flex-shrink: 0;
}
/* Equal size/padding on both buttons — deliberately not making "Accept"
   more visually dominant than "Only Necessary" (ICO guidance on consent
   banners requires a genuine, unpressured choice between the two). */
.cookie-btn {
  border-radius: 999px;
  padding: 0.625rem 1.25rem;
  font-size: 0.8125rem;
  font-weight: 700;
  white-space: nowrap;
  border: 2px solid transparent;
  transition: transform 0.2s ease, opacity 0.2s ease;
}
.cookie-btn:hover {
  transform: translateY(-1px);
}
.cookie-btn-decline {
  background: transparent;
  border-color: rgba(255, 255, 255, 0.25);
  color: #ffffff;
}
.cookie-btn-accept {
  background: #f58520;
  border-color: #f58520;
  color: #0f172a;
}
@media (max-width: 640px) {
  .cookie-banner {
    flex-direction: column;
    align-items: stretch;
    bottom: 12px;
    padding: 18px 20px;
  }
  .cookie-banner-actions {
    flex-direction: column;
  }
  .cookie-btn {
    width: 100%;
    text-align: center;
  }
}

