/* Chrome: nav, footer, theme toggle, page-transition veil, brand orb. */

/* ── Brand orb (WebGL) ────────────────────────────────────────── */
/* The orb IS the logo now, so its slot must stay square: js/eye.js hardcodes
   camera.aspect = 1 and fit() only ever resizes to a square, so a non-square
   slot would letterbox and squash the sphere. */
.brand-eye{position:relative;flex:none;width:32px;height:32px;border-radius:50%;overflow:hidden}
.brand-eye canvas{width:100%;height:100%;display:block}
/* The mark's halo. It can't live in the WebGL scene — a halo big enough to read
   (1.5× the sphere) falls outside the camera frustum and clips to a hard edge —
   so it's a box-shadow, which spills past the canvas freely. */
.brand-eye.live{box-shadow:0 0 12px 1px var(--mint-glow-2)}
/* The static SVG mark is the no-WebGL fallback. eye.js adds .live only after it
   has actually rendered, so the 2D mark holds the slot until the orb can take
   it over — and stays for good if WebGL is unavailable. */
.brand-eye.live ~ .mark,.eye-slot.live ~ .mark{display:none}
/* Aria's chat avatar runs the same orb as the nav mark — eye.js boots one
   instance per [data-eye] host, with the 2D mark as each one's fallback. */
.eye-slot{position:relative;display:block;width:100%;height:100%}
.eye-slot canvas{width:100%;height:100%;display:block}
main section > .frame,
main section > .frame-narrow,
.foot > .frame{position:relative;z-index:3}

/* ── Nav ──────────────────────────────────────────────────────── */
.navwrap{position:sticky;top:12px;z-index:60;padding-inline:var(--bezel);padding-top:16px}
.nav{
  width:min(100%,var(--frame));margin:0 auto;
  display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:12px;
  padding:8px 10px 8px 16px;border-radius:var(--r-pill);
  background:linear-gradient(180deg,rgba(255,255,255,.065) 0%,rgba(255,255,255,.022) 100%);
  border:1px solid var(--hairline);
  backdrop-filter:blur(24px) saturate(150%);-webkit-backdrop-filter:blur(24px) saturate(150%);
  transition:box-shadow var(--dur) var(--ease-out),border-color var(--dur) var(--ease-out),background var(--dur) var(--ease-out);
}
html[data-theme="light"] .nav{background:linear-gradient(180deg,rgba(255,255,255,.9) 0%,rgba(255,255,255,.62) 100%)}
.nav.scrolled{border-color:var(--hairline-2);box-shadow:var(--sh-2)}

.brand{display:inline-flex;align-items:center;gap:12px;font-family:var(--serif);font-variation-settings:"opsz" 36,"wght" 500,"SOFT" 30;font-size:19px;letter-spacing:-.015em;color:var(--ink);padding:6px 14px 6px 6px;white-space:nowrap}
.brand:hover{color:var(--ink)}
.brand .mark{width:28px;height:28px;flex:none;filter:drop-shadow(0 0 14px var(--mint-glow-2))}
.brand .pro{font-style:italic;font-variation-settings:"opsz" 36,"wght" 500,"SOFT" 80;margin-left:.18em}
.brand .pdot{color:var(--mint);margin-left:.05em}
.brand-compact{display:none}

.nav-links{display:flex;justify-self:center;gap:2px;padding:4px;font-size:13px}
.nav-links a{position:relative;padding:9px 15px;border-radius:var(--r-pill);color:var(--ink-soft);transition:color var(--dur-fast) var(--ease-out),background var(--dur-fast) var(--ease-out)}
.nav-links a:hover{color:var(--ink);background:var(--panel)}
.nav-links a[aria-current="page"]{color:var(--ink);background:var(--panel-2)}
.nav-links a[aria-current="page"]::after{content:"";position:absolute;left:50%;bottom:2px;transform:translateX(-50%);width:14px;height:2px;border-radius:2px;background:var(--mint);box-shadow:0 0 10px var(--mint-glow)}
.fo-link{display:inline-flex;align-items:center;gap:7px;color:var(--mint)!important}
.fo-link-dot{width:6px;height:6px;border-radius:50%;background:var(--mint);box-shadow:0 0 9px var(--mint-glow);animation:pulse 2.4s ease-in-out infinite}

.nav-cta{display:inline-flex;gap:8px;align-items:center;grid-column:3;justify-self:end;justify-content:flex-end}
.nav-cta>.nav-signin,.nav-cta>.btn{height:44px;padding-block:0;align-items:center}
.nav-cta>.nav-burger{width:44px;height:44px}
.nav-signin{display:inline-flex;align-items:center;gap:7px;padding:9px 14px;border:1px solid var(--hairline);border-radius:999px;color:var(--ink-soft)!important;font-size:13.5px;font-weight:550;white-space:nowrap;transition:color var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out),background var(--dur-fast) var(--ease-out)}
.nav-signin:hover{color:var(--ink)!important;border-color:var(--hairline-2);background:var(--panel)}
.nav-signin svg{width:14px;height:14px;flex:0 0 14px}
@media(max-width:900px){.nav-signin,.nav-start{display:none}}/* Both nav CTAs collapse into the burger sheet, which carries its own Start free + Operator sign in. Leaving .nav-start visible pushed the bar past the viewport at 320px. */
.nav-burger{display:none;width:40px;height:40px;border-radius:50%;border:1px solid var(--hairline);background:var(--panel);cursor:pointer;flex-direction:column;align-items:center;justify-content:center;gap:4px;transition:background var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out)}
.nav-burger:hover{background:var(--panel-2);border-color:var(--hairline-2)}
.nav-burger-bar{width:15px;height:1.5px;background:var(--ink);border-radius:2px;transition:transform var(--dur) var(--ease-drawer),opacity var(--dur) var(--ease-drawer)}
.nav-burger[aria-expanded="true"] .nav-burger-bar:nth-child(1){transform:translateY(5.5px) rotate(45deg)}
.nav-burger[aria-expanded="true"] .nav-burger-bar:nth-child(2){opacity:0}
.nav-burger[aria-expanded="true"] .nav-burger-bar:nth-child(3){transform:translateY(-5.5px) rotate(-45deg)}

@media(max-width:1140px){.nav-links{display:none}.nav-burger{display:flex}}
@media(max-width:640px){
  .brand-eye{width:28px;height:28px}
  .nav-cta .btn.ghost{display:none}
  /* "Talk to Aria" + burger do not both fit beside the wordmark at 390px --
     the cluster overhangs the viewport. Collapse the CTA to its arrow; the
     label stays in the DOM, so the link keeps its accessible name. */
  .nav-cta .btn.primary{width:44px;padding:0;gap:0;justify-content:center;font-size:0}
  .nav-cta .btn.primary .ico{font-size:11px}
  .brand{font-size:17px;gap:9px;padding-right:6px}
  .brand-full{display:none}.brand-compact{display:inline}
}

/* Mobile sheet */
.msheet{position:fixed;inset:0;z-index:80;display:none;place-items:start center;padding:88px var(--bezel) 32px;overflow-y:auto;overscroll-behavior:contain;background:rgba(2,10,7,.72);backdrop-filter:blur(22px);-webkit-backdrop-filter:blur(22px);opacity:0;visibility:hidden;pointer-events:none;transition:opacity var(--dur) var(--ease-out)}
html[data-theme="light"] .msheet{background:rgba(244,247,243,.82)}
.msheet.open,.msheet.closing{display:grid;visibility:visible}
.msheet.open{opacity:1;pointer-events:auto}
/* Under reduced motion the UA rule forces transition-duration to .01ms on
   every property -- including the sheet's visibility, which is discrete. A
   transitioning visibility is not "visible" yet in the task that opens the
   sheet, so focus() lands on nothing and the modal opens with focus still on
   the burger. Reduced motion wants no fade here anyway: drop the transition
   entirely and the state applies synchronously. */
.msheet-inner{width:min(100%,440px);display:grid;gap:6px}
.msheet a{display:flex;align-items:center;justify-content:space-between;padding:17px 20px;border-radius:var(--r-sm);border:1px solid var(--hairline);background:var(--panel);color:var(--ink);font-size:17px;font-family:var(--display);font-variation-settings:"wght" 500;opacity:0;transform:translateY(14px)}
.msheet.open a{opacity:1;transform:none;transition:opacity 420ms var(--ease-out) var(--d),transform 420ms var(--ease-out-strong) var(--d),background var(--dur-fast) ease}
.msheet a:hover{background:var(--panel-2)}
.msheet-close{justify-self:end;width:44px;height:44px;display:grid;place-items:center;border-radius:50%;border:1px solid var(--hairline);background:var(--panel);color:var(--ink);cursor:pointer;margin-bottom:10px;transition:background var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out)}
.msheet-close:hover{background:var(--panel-2);border-color:var(--hairline-2)}
.msheet .msheet-cta,.msheet .msheet-cta-ghost{margin-top:6px;justify-content:center;font-family:var(--sans);opacity:0;transform:translateY(14px)}
.msheet.open .msheet-cta,.msheet.open .msheet-cta-ghost{opacity:1;transform:none;transition:opacity 420ms var(--ease-out) var(--d),transform 420ms var(--ease-out-strong) var(--d)}

/* While the sheet is modal, nothing outside it may be visible or clickable --
   the chat launcher's z-index (2147483000) beats any stacking context this
   document can build, so it is hidden at the host instead of out-stacked. */
body.menu-open .back-to-top,
body.menu-open .theme-toggle,
body.menu-open .mobile-sticky-cta-wrap,
body.menu-open [data-csp-widget="true"]{visibility:hidden;pointer-events:none}
.msheet a .ar{color:var(--mint);font-size:14px}

/* ── Footer ───────────────────────────────────────────────────── */
.foot{margin-top:clamp(80px,10vw,150px);padding-block:clamp(56px,6vw,84px) 36px;border-top:1px solid var(--hairline);background:linear-gradient(180deg,transparent,rgba(0,0,0,.22))}
html[data-theme="light"] .foot{background:linear-gradient(180deg,transparent,rgba(11,28,18,.03))}
.foot-grid{display:grid;grid-template-columns:1.7fr repeat(4,1fr);gap:clamp(24px,3vw,48px);margin-bottom:56px}
.foot-mast{font-family:var(--serif);font-variation-settings:"opsz" 36,"wght" 500,"SOFT" 30;font-size:26px;letter-spacing:-.02em;margin-bottom:14px}
.foot-mast .pro{font-style:italic;font-variation-settings:"opsz" 36,"wght" 500,"SOFT" 80}
.foot-mast .pdot{color:var(--mint)}
.foot-tagline{font-size:14px;line-height:1.62;color:var(--ink-faint);max-width:40ch;text-wrap:pretty}
.foot-col h4{font-family:var(--mono);font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-faint);margin:0 0 16px;font-weight:500}
.foot-col ul{list-style:none;margin:0;padding:0;display:grid;gap:11px}
.foot-col a{font-size:14px;color:var(--ink-soft)}
.foot-col a:hover{color:var(--mint)}
.foot-base{display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap;padding-top:26px;border-top:1px solid var(--hairline);font-size:12.5px;color:var(--ink-mute)}
.foot-legal-inline{display:flex;gap:12px;align-items:center}
.foot-legal-inline a{color:var(--ink-mute)}
.foot-legal-inline a:hover{color:var(--ink-soft)}
@media(max-width:960px){.foot-grid{grid-template-columns:1fr 1fr;gap:36px}}
@media(max-width:520px){.foot-grid{grid-template-columns:1fr}}

/* ── Page transition veil ─────────────────────────────────────── */
/* Cross-document view transitions live in vt.css, injected by the inline head
   script only when the document is top-level. Declaring @view-transition where
   it cannot run (inside an iframe) makes the engine create a transition and
   immediately skip it, rejecting a promise no author code owns — an unfixable
   console error. Declared only where it is eligible instead. */
#veil{position:fixed;inset:0;z-index:150;pointer-events:none;background:var(--bg);opacity:0;transition:opacity 165ms var(--ease-out)}
#veil.out{opacity:1}
#veil .veil-mark{position:absolute;left:50%;top:50%;translate:-50% -50%;width:52px;height:52px;opacity:0;transition:opacity 300ms ease}
#veil.out .veil-mark{opacity:1}
/* Entrance animation deliberately excludes <main>: if JS is slow or blocked,
   content must never start invisible. The nav and footer can afford it. */
body.entering .navwrap,body.entering .foot{animation:pageIn 380ms var(--ease-out-strong) both}
@keyframes pageIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}

/* ── Scroll progress ──────────────────────────────────────────── */
#progress{position:fixed;left:0;top:0;height:2px;z-index:90;width:0;background:linear-gradient(90deg,var(--mint-deep),var(--mint),var(--mint-bright));box-shadow:0 0 14px var(--mint-glow);transition:width 120ms linear}

/* The Aria widget owns the bottom-right corner: its launcher is fixed at
   --csp-offset-y/--csp-offset-x (20px) with a z-index of 2147483000, so anything
   we place at the same coordinates is painted over and unclickable. Reserve the
   launcher's own footprint -- 20px offset + 52px medium launcher + the same 14px
   gap the widget itself leaves above the launcher for its panel -- and stack the
   back-to-top button above it instead of underneath it. */
:root{--launcher-clear:86px}
/* ── Back to top ──────────────────────────────────────────────── */
.back-to-top{position:fixed;right:20px;bottom:calc(var(--launcher-clear) + var(--chrome-lift,0px) + env(safe-area-inset-bottom,0px));z-index:70;display:inline-flex;align-items:center;gap:7px;padding:9px 14px;border-radius:var(--r-pill);border:1px solid var(--hairline);background:linear-gradient(180deg,rgba(255,255,255,.07),rgba(255,255,255,.02));backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);cursor:pointer;font-size:12px;color:var(--ink-soft);opacity:0;pointer-events:none;transform:translateY(8px);transition:opacity var(--dur) ease,transform var(--dur) var(--ease-spring),border-color var(--dur-fast) ease}
html[data-theme="light"] .back-to-top{background:rgba(255,255,255,.85)}
.back-to-top.show{opacity:1;pointer-events:auto;transform:none}
.back-to-top:hover{border-color:var(--mint-rim)}
@media(max-width:640px){.back-to-top{right:20px}.back-to-top-label{display:none}}
