/*
Theme Name: Gavorix HQ
Theme URI: https://gavorix.com
Author: TSGI Services LLC
Author URI: https://gavorix.com
Description: Front door for gavorix.com. Installed and managed by the Gavorix Legal Hub plugin. Shares its design tokens with the generated legal and product pages so the whole site reads as one thing rather than a marketing site with documents bolted on.
Version: 2.1.4.0
Requires PHP: 8.2
Requires at least: 6.4
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: gavorix-hq
*/

/*
 * Design system.
 *
 * Premium is carried by four things here, none of them ornament: a strong
 * fluid type scale with real contrast between levels, a consistent spacing
 * rhythm, one restrained accent used precisely, and honest content blocks
 * (no logo walls, no invented counters, no testimonials - we have one shipped
 * app and figures would be fiction).
 *
 * Tokens are duplicated from the plugin's public.css on purpose rather than
 * imported: the legal documents must survive this theme being swapped out,
 * so neither file may depend on the other.
 */

:root {
  --gvx-accent: #4f46e5;
  --gvx-accent-2: #22d3ee;
  --gvx-bg: #ffffff;
  --gvx-surface: #f8fafc;
  --gvx-surface-2: #eef2f7;
  --gvx-text: #0f172a;
  --gvx-muted: #5b6b81;
  --gvx-line: #e2e8f0;
  --gvx-radius: 14px;
  --gvx-radius-lg: 22px;

  /* fluid type scale */
  --fs-900: clamp(2.6rem, 6.5vw, 4.4rem);
  --fs-800: clamp(1.9rem, 4vw, 2.6rem);
  --fs-700: clamp(1.45rem, 2.6vw, 1.8rem);
  --fs-600: 1.16rem;
  --fs-500: 1.02rem;
  --fs-400: .95rem;
  --fs-300: .84rem;
  --fs-200: .74rem;

  --space-section: clamp(4.5rem, 9vw, 7.5rem);
  --wrap: 74rem;
}


*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--gvx-bg);
  color: var(--gvx-text);
  font: 16px/1.65 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
a { color: var(--gvx-accent); }
img, svg { max-width: 100%; height: auto; }

.gvx-wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 1.5rem; }

h1, h2, h3, h4 { font-weight: 780; letter-spacing: -.028em; line-height: 1.08; margin: 0; }

/* ------------------------------------------------------------------ buttons */
.btn {
  display: inline-flex; align-items: center; gap: .5rem;
  font-weight: 650; font-size: var(--fs-400); text-decoration: none;
  padding: .8rem 1.55rem; border-radius: 999px; border: 1px solid transparent;
  transition: transform .16s ease, box-shadow .16s ease, background .16s ease, border-color .16s ease;
}
.btn--primary {
  background: var(--gvx-accent); color: #fff;
  box-shadow: 0 10px 26px -12px color-mix(in srgb, var(--gvx-accent) 80%, transparent);
}
.btn--primary:hover { transform: translateY(-1px); box-shadow: 0 16px 34px -12px color-mix(in srgb, var(--gvx-accent) 85%, transparent); }
.btn--ghost { color: var(--gvx-text); border-color: var(--gvx-line); background: transparent; }
.btn--ghost:hover { border-color: var(--gvx-accent); color: var(--gvx-accent); }

/* ------------------------------------------------------------------- header */
.site-top {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in srgb, var(--gvx-bg) 84%, transparent);
  backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid color-mix(in srgb, var(--gvx-line) 80%, transparent);
}
.site-top__inner {
  /* flex-wrap mirrors .gvx-top__inner. Without it this header kept the nav on
     the brand's row and let the nav wrap inside itself, so at 375px a theme page
     measured 114px tall and a document page 128px. Same header, two heights,
     visible only on a phone. */
  display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  /* Longhand on purpose: this element also carries .gvx-wrap, and the padding
     shorthand reset its 1.5rem side padding, pulling the header 24px out of
     alignment with every page section below it. */
  padding-top: .9rem; padding-bottom: .9rem;
}
.site-brand { display: inline-flex; align-items: center; gap: .65rem; color: inherit; text-decoration: none; font-weight: 780; letter-spacing: -.02em; font-size: 1.05rem; }
/* The mark was a blank gradient chip, which is a placeholder rather than a
   logo. radius 22% matches the rx in the SVG tile, so the box-shadow follows
   the artwork's own corners instead of cutting them. */
.site-brand__mark {
  width: 2.5rem; height: 2.5rem; border-radius: 22%; flex: none;
  background: url("img/icon.svg") center / contain no-repeat;
  box-shadow: 0 4px 14px -6px color-mix(in srgb, var(--gvx-accent) 70%, transparent);
}
/* Mirror of .gvx-appnav in the plugin's public.css. Leading is pinned so the
   header measures the same on theme pages and on document pages, whose
   stylesheet uses looser body leading for long-form reading. */
.site-nav { display: flex; align-items: center; gap: .25rem; flex-wrap: wrap; line-height: 1.65; }
.site-nav a {
  color: var(--gvx-muted); text-decoration: none; font-size: var(--fs-400); font-weight: 600;
  padding: .42rem .8rem; border-radius: 999px;
}
.site-nav a:hover { color: var(--gvx-text); background: var(--gvx-surface); }
/* font-weight is restated because `.site-nav a` (0,1,1) outranks `.btn` (0,1,0)
   and was thinning the header button to nav-link weight, so the one button in
   the header did not match every other button on the site. */
.site-nav .btn { margin-left: .35rem; padding: .5rem 1.05rem; color: #fff; font-weight: 650; }

/* ------------------------------------------------------- technology band */
/* Modelled on the reference site's tech-ecosystem strip: one quiet row of brand
   marks directly under the hero, monochrome so it reads as an ecosystem
   statement rather than a sponsor wall. Colour on hover only, so the page has
   one accent at rest. */
.tech-band { border-top: 1px solid var(--gvx-line); border-bottom: 1px solid var(--gvx-line); background: color-mix(in srgb, var(--gvx-surface) 60%, transparent); }
.tech-band__inner {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 1.2rem 2.6rem; padding-top: 1.4rem; padding-bottom: 1.4rem;
}
.tech-band__item { display: inline-flex; color: var(--gvx-muted); opacity: .62; transition: opacity .18s ease, color .18s ease; }
.tech-band__item:hover { opacity: 1; color: var(--gvx-text); }
@media (max-width: 40rem) { .tech-band__inner { gap: 1rem 1.6rem; } }

/* --------------------------------------------------------------------- hero */
.hero { position: relative; overflow: clip; padding: clamp(4rem, 9vw, 7rem) 0 clamp(3rem, 7vw, 5.5rem); }
.hero::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background:
    radial-gradient(52% 46% at 18% 8%, color-mix(in srgb, var(--gvx-accent) 13%, transparent), transparent 70%),
    radial-gradient(40% 42% at 88% 20%, color-mix(in srgb, var(--gvx-accent-2) 10%, transparent), transparent 70%);
}
.hero__grid {
  display: grid; gap: 3.5rem; align-items: center;
  grid-template-columns: 1fr;
}
@media (min-width: 62rem) { .hero__grid { grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); } }

.hero__eyebrow {
  display: inline-flex; align-items: center; gap: .5rem;
  font-size: var(--fs-200); font-weight: 800; letter-spacing: .13em; text-transform: uppercase;
  color: var(--gvx-accent); margin: 0 0 1.3rem;
}
.hero__eyebrow::before { content: ""; width: 1.6rem; height: 2px; border-radius: 2px; background: var(--gvx-accent); }
.hero h1 { font-size: var(--fs-900); font-weight: 820; letter-spacing: -.042em; text-wrap: balance; margin: 0 0 1.4rem; }
.hero h1 em {
  font-style: normal;
  background: linear-gradient(92deg, var(--gvx-accent), color-mix(in srgb, var(--gvx-accent) 40%, var(--gvx-accent-2)));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.hero__sub { font-size: clamp(1.05rem, 2vw, 1.24rem); line-height: 1.6; color: var(--gvx-muted); max-width: 34rem; margin: 0 0 2.1rem; text-wrap: pretty; }
.hero__actions { display: flex; gap: .8rem; flex-wrap: wrap; }

/* Quiet inline text, not a box. This list used to sit in its own bordered panel
   directly above the technology band, so the hero was followed by two framed
   strips that competed with each other. The band keeps the border because it is
   the wider statement; this reads as a caption under the buttons.

   Spacing separates the items, not a character. CSS cannot see where a line
   breaks, so a leading separator orphans a dot onto the start of a wrapped line
   and a trailing one strands it at the end. Both were tried. Gap has neither
   failure mode, at any width and for any label length, and these labels are
   settings-driven so their widths will change. */
.hero__meta {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: .35rem 1.6rem; margin: 1.6rem 0 0; padding: 0; list-style: none;
  font-size: var(--fs-300); color: var(--gvx-muted);
}
.hero__meta li { font-weight: 600; }
}
.hero__meta li {
  font-size: var(--fs-300); font-weight: 650; color: var(--gvx-muted);
  padding: .38rem .9rem; border: 1px solid var(--gvx-line); border-radius: 999px;
  background: color-mix(in srgb, var(--gvx-surface) 65%, transparent);
}

/* Device mockup: pure CSS/SVG, no image assets. An abstract route on a phone,
   which is honest about what we make without pretending to be a screenshot. */
.hero__visual { display: grid; place-items: center; }
.phone {
  width: min(19rem, 78vw); aspect-ratio: 9 / 18.6; border-radius: 2.6rem; position: relative;
  background: linear-gradient(160deg, color-mix(in srgb, var(--gvx-surface) 92%, transparent), var(--gvx-bg));
  border: 1px solid var(--gvx-line);
  box-shadow:
    0 40px 80px -38px color-mix(in srgb, var(--gvx-accent) 38%, transparent),
    0 24px 50px -30px rgb(2 6 23 / .35),
    inset 0 0 0 6px color-mix(in srgb, var(--gvx-bg) 70%, var(--gvx-line));
  transform: rotate(4deg);
  /* Own compositor layer. This element animates forever and carries three
     blurred shadows (80px, 50px and an inset); without the hint the browser can
     repaint all three every frame, which is what makes the hero feel like it is
     still settling after the page has loaded. */
  will-change: transform;
}
.phone::before {
  content: ""; position: absolute; top: .8rem; left: 50%; translate: -50% 0;
  width: 34%; height: .9rem; border-radius: 999px;
  background: color-mix(in srgb, var(--gvx-text) 12%, var(--gvx-surface));
}
.phone__screen { position: absolute; inset: 2rem .9rem .9rem; border-radius: 1.8rem; overflow: hidden; background: var(--gvx-surface); }
.phone__screen svg { width: 100%; height: 100%; display: block; }
/* Generic app-grid motif on the phone screen. The route drawing moved to the
   product page (styled there by the plugin's public.css); the homepage must
   style what it actually renders, which was the bug this comment replaces:
   the tiles SVG shipped with no .tile rules in THIS file, and unstyled SVG
   rects default to solid black. */
.tile { fill: color-mix(in srgb, var(--gvx-muted) 16%, transparent); }
.tile--accent { fill: var(--gvx-accent); }
.tile--soft { fill: color-mix(in srgb, var(--gvx-accent) 30%, transparent); }

/* ----------------------------------------------------------------- sections */
.section { padding: var(--space-section) 0; border-top: 1px solid var(--gvx-line); }
.section--flush { border-top: 0; padding-top: 0; }
.section__label {
  font-size: var(--fs-200); font-weight: 800; letter-spacing: .13em; text-transform: uppercase;
  color: var(--gvx-accent); margin: 0 0 1rem;
}
.section h2 { font-size: var(--fs-800); margin: 0 0 .85rem; }
.section__lede { color: var(--gvx-muted); max-width: 44rem; margin: 0 0 2.75rem; font-size: var(--fs-600); line-height: 1.6; }

/* --------------------------------------------------------------- more apps */
.apps { display: grid; gap: 1.2rem; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); }
.app-card {
  position: relative; display: flex; flex-direction: column; gap: .6rem;
  padding: 1.9rem; border: 1px solid var(--gvx-line); border-radius: var(--gvx-radius);
  background: var(--gvx-bg); text-decoration: none; color: inherit; overflow: hidden;
  transition: transform .18s ease, border-color .18s ease, box-shadow .18s ease;
}
.app-card::after {
  content: ""; position: absolute; inset: 0 0 auto; height: 3px;
  background: linear-gradient(90deg, var(--gvx-accent), color-mix(in srgb, var(--gvx-accent) 45%, var(--gvx-accent-2)));
  opacity: 0; transition: opacity .18s ease;
}
.app-card:hover { transform: translateY(-3px); border-color: color-mix(in srgb, var(--gvx-accent) 55%, var(--gvx-line)); box-shadow: 0 18px 40px -26px color-mix(in srgb, var(--gvx-accent) 65%, transparent); }
.app-card:hover::after { opacity: 1; }
.app-card h3 { font-size: var(--fs-600); }
.app-card p { margin: 0; color: var(--gvx-muted); font-size: var(--fs-400); }
.app-card__more { margin-top: auto; padding-top: .7rem; color: var(--gvx-accent); font-weight: 650; font-size: var(--fs-400); }
.apps__empty { color: var(--gvx-muted); }

/* --------------------------------------------------------------- principles */
.principles { display: grid; gap: 2.2rem 2.5rem; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); counter-reset: principle; }
.principles article { border-top: 2px solid var(--gvx-line); padding-top: 1.3rem; position: relative; }
.principles article::before {
  counter-increment: principle; content: "0" counter(principle);
  display: block; font-size: var(--fs-300); font-weight: 800; letter-spacing: .08em;
  color: var(--gvx-accent); margin-bottom: .7rem; font-variant-numeric: tabular-nums;
}
.principles article:first-child { border-top-color: var(--gvx-accent); }
.principles h3 { font-size: var(--fs-600); margin: 0 0 .55rem; }
.principles p { margin: 0; color: var(--gvx-muted); font-size: var(--fs-400); line-height: 1.62; }

/* ------------------------------------------------------------ privacy stance */
.stance { display: grid; gap: 2rem; align-items: start; grid-template-columns: 1fr; }
@media (min-width: 56rem) { .stance { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
.stance__facts { list-style: none; margin: 0; padding: 0; display: grid; gap: .9rem; }
.stance__facts li {
  padding: 1.05rem 1.25rem; border: 1px solid var(--gvx-line); border-radius: var(--gvx-radius);
  background: var(--gvx-surface); font-size: var(--fs-400);
}
.stance__facts strong { display: block; margin-bottom: .15rem; }
.stance__facts span { color: var(--gvx-muted); }

/* ------------------------------------------------------------------ contact */
.contact {
  border: 1px solid var(--gvx-line); border-radius: var(--gvx-radius-lg);
  padding: clamp(2rem, 5vw, 3.2rem); text-align: center;
  background:
    radial-gradient(60% 100% at 50% 0%, color-mix(in srgb, var(--gvx-accent) 8%, transparent), transparent 70%),
    var(--gvx-surface);
}
.contact h2 { font-size: var(--fs-700); margin: 0 0 .6rem; }
.contact p { color: var(--gvx-muted); max-width: 34rem; margin: 0 auto 1.6rem; }

/* ------------------------------------------------------------------- footer */
.site-foot { border-top: 1px solid var(--gvx-line); background: var(--gvx-surface); padding: 3.2rem 0 2.4rem; font-size: var(--fs-400); }
.site-foot__grid { display: grid; gap: 2.2rem; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); align-items: start; }
.site-foot__brand p { color: var(--gvx-muted); margin: .7rem 0 0; max-width: 20rem; }
.site-foot h4 { font-size: var(--fs-300); text-transform: uppercase; letter-spacing: .1em; color: var(--gvx-muted); margin: 0 0 .8rem; font-weight: 750; }
.site-foot ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .45rem; }
.site-foot a { color: var(--gvx-muted); text-decoration: none; }
.site-foot a:hover { color: var(--gvx-text); }
.site-foot__base { margin-top: 2.6rem; padding-top: 1.4rem; border-top: 1px solid var(--gvx-line); color: var(--gvx-muted); font-size: var(--fs-300); display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }

/* ------------------------------------------------------------ content pages */
.entry { max-width: 44rem; margin: 0 auto; padding: 3.5rem 0; }
.entry h1 { font-size: var(--fs-800); margin-bottom: 1rem; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { transition: none !important; animation: none !important; }
  .phone { transform: none; }
}

.site-foot__tagline { font-style: italic; opacity: .85; }
@media (max-width: 40rem) { .site-foot__base { justify-content: center; text-align: center; } }

/* ------------------------------------------------------------------ motion
   Attention through motion, not fabrication: the device floats, sections
   reveal on scroll. Hidden states only exist under html.js (added by the
   script itself), so content never disappears when JS fails, and every
   animation dies under prefers-reduced-motion. */
@keyframes gvx-float {
  0%, 100% { transform: rotate(4deg) translateY(0); }
  50%      { transform: rotate(4deg) translateY(-12px); }
}
.hero .phone { animation: gvx-float 7s ease-in-out infinite; }

html.js .reveal { opacity: 0; transform: translateY(18px); transition: opacity .55s ease, transform .55s ease; }
html.js .reveal.is-visible { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .hero .phone { animation: none; }
  html.js .reveal { opacity: 1; transform: none; }
}
