aiplang 2.11.7 → 2.11.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/aiplang.js CHANGED
@@ -5,7 +5,7 @@ const fs = require('fs')
5
5
  const path = require('path')
6
6
  const http = require('http')
7
7
 
8
- const VERSION = '2.11.7'
8
+ const VERSION = '2.11.9'
9
9
  const RUNTIME_DIR = path.join(__dirname, '..', 'runtime')
10
10
  const cmd = process.argv[2]
11
11
  const args = process.argv.slice(3)
@@ -686,7 +686,7 @@ function generateTypes(app, srcFile) {
686
686
  }
687
687
 
688
688
  lines.push(`// ── aiplang version ──────────────────────────────────────────`)
689
- lines.push(`export const AIPLANG_VERSION = '2.11.7'`)
689
+ lines.push(`export const AIPLANG_VERSION = '2.11.9'`)
690
690
  lines.push(``)
691
691
  return lines.join('\n')
692
692
  }
@@ -1427,7 +1427,7 @@ function rHero(b) {
1427
1427
  const bgStyle = b.bg ? ` style="background:${b.bg}"` : b.style ? ` style="${b.style.replace(/,/g,';')}"` : ''
1428
1428
  const inlineStyle = b.style && !b.bg ? ` style="${b.style.replace(/,/g,';')}"` : ''
1429
1429
  if (v === 'landing') {
1430
- return `<section class="fx-hero fx-hero-landing"${bgStyle}><div class="fx-hero-inner">${h1}${sub}${ctas}</div></section>
1430
+ return `<section class="fx-hero fx-hero-landing"${bgStyle}><div class="fx-hero-grid"></div><div class="fx-hero-inner">${h1}${sub}${ctas}</div></section>
1431
1431
  `
1432
1432
  }
1433
1433
  if (h1) h1 = heroBadge + h1
@@ -1801,172 +1801,853 @@ function genCustomThemeVars(ct) {
1801
1801
 
1802
1802
  function genThemeVarCSS(t) {
1803
1803
  const r=[]
1804
- if(t.accent) r.push(`.fx-cta,.fx-btn,.fx-pricing-cta{background:${t.accent}!important;color:#fff!important}`)
1805
- if(t.bg) r.push(`body{background:${t.bg}!important}`)
1806
- if(t.text) r.push(`body{color:${t.text}!important}`)
1807
- if(t.font) r.push(`@import url('https://fonts.googleapis.com/css2?family=${t.font.replace(/ /g,'+')}:wght@400;700;900&display=swap');body{font-family:'${t.font}',system-ui,sans-serif!important}`)
1808
- if(t.radius) r.push(`.fx-card,.fx-form,.fx-btn,.fx-input,.fx-cta,.fx-pricing-card{border-radius:${t.radius}!important}`)
1809
- if(t.surface) r.push(`.fx-card,.fx-form{background:${t.surface}!important}`)
1810
- if(t.border) r.push(`.fx-card,.fx-form,.fx-input{border-color:${t.border}!important}`)
1811
- if(t.shadow) r.push(`.fx-card:hover{box-shadow:${t.shadow}!important}`)
1812
- if(t.navbg) r.push(`.fx-nav{background:${t.navbg}!important}`)
1813
- if(t.spacing) r.push(`.fx-sect,.fx-hero{padding-top:${t.spacing};padding-bottom:${t.spacing}}`)
1804
+ const rv=[]
1805
+ function h2r(h){h=h.replace('#','');return h.length===6?parseInt(h.slice(0,2),16)+','+parseInt(h.slice(2,4),16)+','+parseInt(h.slice(4,6),16):'255,255,255'}
1806
+ if(t.accent){rv.push('--aip-accent:'+t.accent);rv.push('--aip-accent-rgb:'+h2r(t.accent))}
1807
+ if(t.bg){var rgb=h2r(t.bg);rv.push('--ds-background-100:'+t.bg);rv.push('--ds-background-100-rgb:'+rgb);rv.push('--ds-background-200:'+t.bg)}
1808
+ if(t.text){rv.push('--ds-gray-1000:'+t.text)}
1809
+ if(t.radius){rv.push('--radius-sm:'+t.radius);rv.push('--radius-md:'+t.radius)}
1810
+ if(rv.length) r.push(':root{'+rv.join(';')+'}')
1811
+ if(t.font) r.push("body{font-family:'"+t.font+"',var(--geist-font)!important}")
1812
+ if(t.accent) r.push('.fx-cta,.fx-btn,.fx-pricing-cta,.fx-nav-cta{background:'+t.accent+'!important;color:#fff!important}')
1813
+ if(t.bg) r.push('body,html{background:'+t.bg+'!important}')
1814
+ if(t.text) r.push('body{color:'+t.text+'!important}')
1814
1815
  return r.join('')
1815
1816
  }
1816
1817
 
1818
+
1817
1819
  function css(theme) {
1818
- const base=`*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}html{scroll-behavior:smooth}body{font-family:-apple-system,'Segoe UI',system-ui,sans-serif;-webkit-font-smoothing:antialiased;min-height:100vh}a{text-decoration:none;color:inherit}input,button,select{font-family:inherit}img{max-width:100%;height:auto}.fx-nav{display:flex;align-items:center;justify-content:space-between;padding:1rem 2.5rem;position:sticky;top:0;z-index:50;backdrop-filter:blur(12px);flex-wrap:wrap;gap:.5rem}.fx-brand{font-size:1.25rem;font-weight:800;letter-spacing:-.03em}.fx-nav-links{display:flex;align-items:center;gap:1.75rem}.fx-nav-link{font-size:.875rem;font-weight:500;opacity:.65;transition:opacity .15s}.fx-nav-link:hover{opacity:1}.fx-hamburger{display:none;flex-direction:column;gap:5px;background:none;border:none;cursor:pointer;padding:.25rem}.fx-hamburger span{display:block;width:22px;height:2px;background:currentColor;transition:all .2s;border-radius:1px}.fx-hamburger.open span:nth-child(1){transform:rotate(45deg) translate(5px,5px)}.fx-hamburger.open span:nth-child(2){opacity:0}.fx-hamburger.open span:nth-child(3){transform:rotate(-45deg) translate(5px,-5px)}@media(max-width:640px){.fx-hamburger{display:flex}.fx-nav-links{display:none;width:100%;flex-direction:column;align-items:flex-start;gap:.75rem;padding:.75rem 0}.fx-nav-links.open{display:flex}}.fx-hero{display:flex;align-items:center;justify-content:center;min-height:92vh;padding:4rem 1.5rem}.fx-hero-split{display:grid;grid-template-columns:1fr 1fr;gap:3rem;align-items:center;padding:4rem 2.5rem;min-height:70vh}@media(max-width:768px){.fx-hero-split{grid-template-columns:1fr}}.fx-hero-img{width:100%;border-radius:1.25rem;object-fit:cover;max-height:500px}.fx-hero-inner{max-width:56rem;text-align:center;display:flex;flex-direction:column;align-items:center;gap:1.5rem}.fx-hero-split .fx-hero-inner{text-align:left;align-items:flex-start;max-width:none}.fx-title{font-size:clamp(2.5rem,8vw,5.5rem);font-weight:900;letter-spacing:-.04em;line-height:1}.fx-sub{font-size:clamp(1rem,2vw,1.25rem);line-height:1.75;max-width:40rem}.fx-cta{display:inline-flex;align-items:center;padding:.875rem 2.5rem;border-radius:.75rem;font-weight:700;font-size:1rem;letter-spacing:-.01em;transition:transform .15s;margin:.25rem}.fx-cta:hover{transform:translateY(-1px)}.fx-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:3rem;padding:5rem 2.5rem;text-align:center}.fx-stat-val{font-size:clamp(2.5rem,5vw,4rem);font-weight:900;letter-spacing:-.04em;line-height:1}.fx-stat-lbl{font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.1em;margin-top:.5rem}.fx-grid{display:grid;gap:1.25rem;padding:1rem 2.5rem 5rem}.fx-grid-2{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}.fx-grid-3{grid-template-columns:repeat(auto-fit,minmax(240px,1fr))}.fx-grid-4{grid-template-columns:repeat(auto-fit,minmax(200px,1fr))}.fx-card{border-radius:1rem;padding:1.75rem;transition:transform .2s,box-shadow .2s}.fx-card:hover{transform:translateY(-2px)}.fx-card-img{width:100%;border-radius:.75rem;object-fit:cover;height:180px;margin-bottom:1rem}.fx-icon{font-size:2rem;margin-bottom:1rem}.fx-card-title{font-size:1.0625rem;font-weight:700;letter-spacing:-.02em;margin-bottom:.5rem}.fx-card-body{font-size:.875rem;line-height:1.65}.fx-card-link{font-size:.8125rem;font-weight:600;display:inline-block;margin-top:1rem;opacity:.6;transition:opacity .15s}.fx-card-link:hover{opacity:1}.fx-sect{padding:5rem 2.5rem}.fx-sect-title{font-size:clamp(1.75rem,4vw,3rem);font-weight:800;letter-spacing:-.04em;margin-bottom:1.5rem;text-align:center}.fx-sect-body{font-size:1rem;line-height:1.75;text-align:center;max-width:48rem;margin:0 auto}.fx-form-wrap{padding:3rem 2.5rem;display:flex;justify-content:center}.fx-form{width:100%;max-width:28rem;border-radius:1.25rem;padding:2.5rem}.fx-field{margin-bottom:1.25rem}.fx-label{display:block;font-size:.8125rem;font-weight:600;margin-bottom:.5rem}.fx-input{width:100%;padding:.75rem 1rem;border-radius:.625rem;font-size:.9375rem;outline:none;transition:box-shadow .15s}.fx-input:focus{box-shadow:0 0 0 3px rgba(37,99,235,.35)}.fx-btn{width:100%;padding:.875rem 1.5rem;border:none;border-radius:.625rem;font-size:.9375rem;font-weight:700;cursor:pointer;margin-top:.5rem;transition:transform .15s,opacity .15s;letter-spacing:-.01em}.fx-btn:hover{transform:translateY(-1px)}.fx-btn:disabled{opacity:.5;cursor:not-allowed;transform:none}.fx-btn-wrap{padding:0 2.5rem 1.5rem}.fx-standalone-btn{width:auto;padding:.75rem 2rem;margin-top:0}.fx-form-msg{font-size:.8125rem;padding:.5rem 0;min-height:1.5rem;text-align:center}.fx-form-err{color:#f87171}.fx-form-ok{color:#4ade80}.fx-table-wrap{overflow-x:auto;padding:0 2.5rem 4rem}.fx-table{width:100%;border-collapse:collapse;font-size:.875rem}.fx-th{text-align:left;padding:.875rem 1.25rem;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em}.fx-th-actions{opacity:.6}.fx-tr{transition:background .1s}.fx-td{padding:.875rem 1.25rem}.fx-td-empty{padding:2rem 1.25rem;text-align:center;opacity:.4}.fx-td-actions{white-space:nowrap;padding:.5rem 1rem!important}.fx-action-btn{border:none;cursor:pointer;font-size:.75rem;font-weight:600;padding:.3rem .75rem;border-radius:.375rem;margin-right:.375rem;font-family:inherit;transition:opacity .15s}.fx-action-btn:hover{opacity:.85}.fx-edit-btn{background:#1e40af;color:#93c5fd}.fx-delete-btn{background:#7f1d1d;color:#fca5a5}.fx-select-wrap{padding:.5rem 2.5rem}.fx-select-block{width:auto;min-width:200px;margin-top:0}.fx-pricing{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:1.5rem;padding:2rem 2.5rem 5rem;align-items:start}.fx-pricing-card{border-radius:1.25rem;padding:2rem;position:relative;transition:transform .2s}.fx-pricing-featured{transform:scale(1.03)}.fx-pricing-badge{position:absolute;top:-12px;left:50%;transform:translateX(-50%);background:#2563eb;color:#fff;font-size:.7rem;font-weight:700;padding:.25rem .875rem;border-radius:999px;white-space:nowrap;letter-spacing:.05em}.fx-pricing-name{font-size:.875rem;font-weight:700;text-transform:uppercase;letter-spacing:.1em;margin-bottom:.5rem;opacity:.7}.fx-pricing-price{font-size:3rem;font-weight:900;letter-spacing:-.05em;line-height:1;margin-bottom:.75rem}.fx-pricing-desc{font-size:.875rem;line-height:1.65;margin-bottom:1.5rem;opacity:.7}.fx-pricing-cta{display:block;text-align:center;padding:.75rem;border-radius:.625rem;font-weight:700;font-size:.9rem;transition:opacity .15s}.fx-pricing-cta:hover{opacity:.85}.fx-faq{max-width:48rem;margin:0 auto}.fx-faq-item{border-radius:.75rem;margin-bottom:.625rem;cursor:pointer;overflow:hidden;transition:background .15s}.fx-faq-q{display:flex;justify-content:space-between;align-items:center;padding:1rem 1.25rem;font-size:.9375rem;font-weight:600}.fx-faq-arrow{transition:transform .2s;font-size:.75rem;opacity:.5}.fx-faq-item.open .fx-faq-arrow{transform:rotate(90deg)}.fx-faq-a{max-height:0;overflow:hidden;padding:0 1.25rem;font-size:.875rem;line-height:1.7;transition:max-height .3s,padding .3s}.fx-faq-item.open .fx-faq-a{max-height:300px;padding:.75rem 1.25rem 1.25rem}.fx-testi-wrap{padding:5rem 2.5rem;display:flex;justify-content:center}.fx-testi{max-width:42rem;text-align:center;display:flex;flex-direction:column;align-items:center;gap:1.25rem}.fx-testi-img{width:64px;height:64px;border-radius:50%;object-fit:cover}.fx-testi-avatar{width:64px;height:64px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:1.5rem;font-weight:700;background:#1e293b}.fx-testi-quote{font-size:1.25rem;line-height:1.7;font-style:italic;opacity:.9}.fx-testi-author{font-size:.875rem;font-weight:600;opacity:.5}.fx-gallery{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:.75rem;padding:1rem 2.5rem 4rem}.fx-gallery-item{border-radius:.75rem;overflow:hidden;aspect-ratio:4/3}.fx-gallery-item img{width:100%;height:100%;object-fit:cover;transition:transform .3s}.fx-gallery-item:hover img{transform:scale(1.04)}.fx-if-wrap{display:contents}.fx-footer{padding:3rem 2.5rem;text-align:center}.fx-footer-text{font-size:.8125rem}.fx-footer-link{font-size:.8125rem;margin:0 .75rem;opacity:.5;transition:opacity .15s}.fx-footer-link:hover{opacity:1}
1819
- /* ── code window ── */
1820
- .fx-code-window{border-radius:.875rem;overflow:hidden;border:1px solid rgba(255,255,255,.08);margin:0 2.5rem 2rem}
1821
- .fx-code-bar{display:flex;align-items:center;gap:.75rem;padding:.625rem 1rem;background:rgba(255,255,255,.04);border-bottom:1px solid rgba(255,255,255,.06)}
1822
- .fx-dots{display:flex;gap:.375rem}
1823
- .fx-dots span{width:10px;height:10px;border-radius:50%;background:rgba(255,255,255,.15)}
1824
- .fx-dots span:nth-child(1){background:#ff5f57}.fx-dots span:nth-child(2){background:#febc2e}.fx-dots span:nth-child(3){background:#28c840}
1825
- .fx-code-lang{font-size:.62rem;letter-spacing:.1em;text-transform:uppercase;opacity:.35;font-family:monospace;margin-left:.25rem}
1826
- .fx-code-copy{margin-left:auto;font-family:monospace;font-size:.62rem;letter-spacing:.1em;text-transform:uppercase;background:none;border:1px solid rgba(255,255,255,.15);color:rgba(255,255,255,.4);padding:.2rem .625rem;border-radius:.3rem;cursor:pointer;transition:all .15s}
1827
- .fx-code-copy:hover{border-color:rgba(255,255,255,.3);color:rgba(255,255,255,.7)}
1828
- .fx-code-body{padding:1.375rem 1.5rem;overflow-x:auto}
1829
- .fx-code-line{font-family:"JetBrains Mono","Fira Code","Courier New",monospace;font-size:.8rem;line-height:1.75;color:#8899aa;white-space:pre}
1830
- .fx-kw{color:#c792ea}.fx-st{color:#c3e88d}.fx-fn{color:#82aaff}.fx-nb{color:#f78c6c}.fx-op{color:var(--accent,#ff5722)}.fx-comment{color:#3d5166;font-style:italic}
1831
- /* ── benchmark ── */
1832
- .fx-benchmark{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:1rem;padding:1rem 2.5rem 4rem}
1833
- .fx-bench-card{border-radius:1rem;padding:1.5rem;border:1px solid rgba(255,255,255,.06);background:rgba(255,255,255,.02);position:relative;overflow:hidden}
1834
- .fx-bench-card::before{content:"";position:absolute;top:0;left:0;right:0;height:2px;background:linear-gradient(90deg,transparent,var(--accent,#ff5722),transparent)}
1835
- .fx-bench-label{font-size:.6rem;letter-spacing:.12em;text-transform:uppercase;opacity:.5;margin-bottom:.5rem;font-family:monospace}
1836
- .fx-bench-num{font-size:clamp(2rem,5vw,3.5rem);font-weight:900;letter-spacing:-.04em;line-height:1;color:var(--accent,#ff5722)}
1837
- .fx-bench-vs{font-size:.7rem;opacity:.4;margin-top:.25rem;font-family:monospace}
1838
- .fx-bench-bar{margin-top:1rem;height:5px;background:rgba(255,255,255,.06);border-radius:3px;overflow:hidden}
1839
- .fx-bench-fill{height:100%;border-radius:3px;background:var(--accent,#ff5722);transition:width 1.5s cubic-bezier(.4,0,.2,1)}
1840
- /* ── install ── */
1841
- .fx-install-wrap{border-radius:.875rem;overflow:hidden;border:1px solid rgba(255,255,255,.08);margin:0 2.5rem 2rem;max-width:540px}
1842
- .fx-install-body{padding:1.25rem 1.5rem}
1843
- .fx-install-line{display:flex;gap:.75rem;padding:.25rem 0;font-family:"JetBrains Mono","Courier New",monospace;font-size:.8rem;line-height:1.7}
1844
- .fx-install-prompt{color:var(--accent,#ff5722);flex-shrink:0}
1845
- .fx-install-cmd{color:rgba(255,255,255,.85)}
1846
- .fx-install-comment{font-family:"JetBrains Mono","Courier New",monospace;font-size:.72rem;color:rgba(255,255,255,.25);padding:.25rem 0;font-style:italic}
1847
- /* ── stats upgrade ── */
1848
- .fx-stat-vs{font-size:.65rem;opacity:.35;margin-top:.2rem;letter-spacing:.02em}
1849
- /* ── hero landing (dark variant) grid + glow ── */
1850
- .fx-hero-landing{position:relative;overflow:hidden}
1851
- .fx-hero-landing::before{content:"";position:absolute;inset:0;background:linear-gradient(rgba(255,255,255,.05) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.05) 1px,transparent 1px);background-size:60px 60px;mask-image:radial-gradient(ellipse 70% 60% at 50% 50%,black,transparent);pointer-events:none}
1852
- .fx-hero-landing::after{content:"";position:absolute;width:700px;height:500px;border-radius:50%;background:radial-gradient(ellipse,rgba(255,87,34,.13) 0%,transparent 70%);left:50%;top:50%;transform:translate(-50%,-50%);pointer-events:none;animation:fx-breathe 6s ease-in-out infinite}
1853
- @keyframes fx-breathe{0%,100%{transform:translate(-50%,-50%) scale(1)}50%{transform:translate(-50%,-50%) scale(1.1)}}
1854
- /* ── feature grid ── */
1855
- .fx-grid-feature{gap:1rem}
1856
- .fx-grid-feature .fx-card{transition:border-color .2s,transform .15s}
1857
- .fx-grid-feature .fx-card:hover{border-color:rgba(255,87,34,.25)}
1858
- .fx-grid-feature .fx-icon{width:44px;height:44px;border-radius:.75rem;display:flex;align-items:center;justify-content:center;background:rgba(255,87,34,.08);border:1px solid rgba(255,87,34,.15)}
1859
- /* ── footer upgrade ── */
1860
- .fx-footer-inner{max-width:1100px;margin:0 auto;display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:1rem}
1861
- .fx-footer-brand{font-size:1rem;font-weight:800;letter-spacing:-.02em}
1862
- .fx-footer-links{display:flex;gap:1.5rem;flex-wrap:wrap}
1863
- .fx-footer-note{font-size:.72rem;opacity:.3;font-family:monospace}
1864
- /* ── marquee ── */
1865
- .fx-marquee{overflow:hidden;padding:1.5rem 0;border-top:1px solid rgba(255,255,255,.06);border-bottom:1px solid rgba(255,255,255,.06);-webkit-mask:linear-gradient(90deg,transparent,black 10%,black 90%,transparent);mask:linear-gradient(90deg,transparent,black 10%,black 90%,transparent)}
1866
- .fx-marquee-track{display:flex;width:max-content;animation:fx-marquee 25s linear infinite}
1820
+ // ════════════════════════════════════════════════════════════════
1821
+ // GEIST DESIGN SYSTEM Vercel's design language for aiplang
1822
+ // Principles: precision, minimalism, Swiss typography, semantic tokens
1823
+ // Fonts: Geist Sans + Geist Mono (Google Fonts)
1824
+ // ════════════════════════════════════════════════════════════════
1825
+ const base = `
1826
+ @import url('https://fonts.googleapis.com/css2?family=Geist:wght@300;400;500;600;700;800;900&family=Geist+Mono:wght@400;500;700&display=swap');
1827
+
1828
+ :root {
1829
+ --geist-font:'Geist','Geist Sans',-apple-system,BlinkMacSystemFont,system-ui,sans-serif;
1830
+ --geist-mono:'Geist Mono','Geist_Mono',ui-monospace,'Cascadia Code','Source Code Pro',Menlo,Consolas,'DejaVu Sans Mono',monospace;
1831
+ /* Spacing scale (4px base) */
1832
+ --space-1:4px;--space-2:8px;--space-3:12px;--space-4:16px;
1833
+ --space-5:20px;--space-6:24px;--space-8:32px;--space-10:40px;--space-12:48px;
1834
+ /* Radius */
1835
+ --radius-sm:4px;--radius-md:8px;--radius-lg:12px;--radius-xl:16px;--radius-full:9999px;
1836
+ /* Easing - Vercel guidelines */
1837
+ --ease-out:cubic-bezier(.16,1,.3,1);
1838
+ --ease-in-out:cubic-bezier(.4,0,.2,1);
1839
+ --ease-spring:cubic-bezier(.34,1.56,.64,1);
1840
+ /* Transitions - only opacity + transform per guidelines */
1841
+ --duration-fast:100ms;--duration-normal:150ms;--duration-slow:250ms;
1842
+ }
1843
+
1844
+ /* ── Reset ── */
1845
+ *,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
1846
+ html{
1847
+ font-size:16px;
1848
+ scroll-behavior:smooth;
1849
+ text-size-adjust:100%;
1850
+ -webkit-text-size-adjust:100%;
1851
+ /* Vercel: tabular nums by default for consistency */
1852
+ font-feature-settings:'ss01','ss02','cv01','cv02';
1853
+ }
1854
+ body{
1855
+ font-family:var(--geist-font);
1856
+ background:var(--ds-background-100);
1857
+ color:var(--ds-gray-1000);
1858
+ line-height:1.5;
1859
+ -webkit-font-smoothing:antialiased;
1860
+ -moz-osx-font-smoothing:grayscale;
1861
+ min-height:100vh;
1862
+ overflow-x:hidden;
1863
+ /* Reduce banding from gradients */
1864
+ text-rendering:optimizeLegibility;
1865
+ }
1866
+ a{text-decoration:none;color:inherit}
1867
+ img{max-width:100%;height:auto;display:block}
1868
+ input,button,select,textarea{font-family:var(--geist-font);font-size:inherit}
1869
+ button{cursor:pointer;border:none;background:none}
1870
+ code,pre,kbd{font-family:var(--geist-mono)}
1871
+ /* Vercel guideline: touch-action on interactive elements */
1872
+ button,a,[role=button]{touch-action:manipulation}
1873
+ /* Vercel: visible focus ring */
1874
+ :focus-visible{
1875
+ outline:2px solid var(--ds-blue-700);
1876
+ outline-offset:2px;
1877
+ border-radius:var(--radius-sm);
1878
+ }
1879
+ /* Vercel: honor prefers-reduced-motion */
1880
+ @media(prefers-reduced-motion:reduce){
1881
+ *,*::before,*::after{
1882
+ animation-duration:.01ms!important;
1883
+ animation-iteration-count:1!important;
1884
+ transition-duration:.01ms!important;
1885
+ }
1886
+ }
1887
+
1888
+ /* ═══════════════════════════════════════════
1889
+ NAV — Geist nav style
1890
+ ═══════════════════════════════════════════ */
1891
+ .fx-nav{
1892
+ position:sticky;top:0;z-index:200;
1893
+ display:flex;align-items:center;justify-content:space-between;
1894
+ padding:0 var(--space-6);height:54px;
1895
+ background:var(--ds-background-100);
1896
+ border-bottom:1px solid var(--ds-gray-alpha-400);
1897
+ /* Vercel: backdrop-blur for glass effect */
1898
+ backdrop-filter:blur(16px) saturate(200%);
1899
+ -webkit-backdrop-filter:blur(16px) saturate(200%);
1900
+ background:rgba(var(--ds-background-100-rgb),.92);
1901
+ flex-wrap:wrap;gap:var(--space-2);
1902
+ transition:border-color var(--duration-slow) var(--ease-in-out);
1903
+ }
1904
+ .fx-nav.scrolled{border-bottom-color:var(--ds-gray-alpha-400)}
1905
+ .fx-brand{
1906
+ font-size:14px;font-weight:600;letter-spacing:-.02em;
1907
+ color:var(--ds-gray-1000);
1908
+ }
1909
+ .fx-nav-links{display:flex;align-items:center;gap:2px}
1910
+ .fx-nav-link{
1911
+ display:inline-flex;align-items:center;
1912
+ font-size:13px;font-weight:400;
1913
+ color:var(--ds-gray-900);
1914
+ padding:5px 10px;border-radius:var(--radius-md);
1915
+ /* Only transition opacity + transform per Vercel guidelines */
1916
+ transition:color var(--duration-normal) var(--ease-in-out),background var(--duration-normal) var(--ease-in-out);
1917
+ }
1918
+ .fx-nav-link:hover{
1919
+ color:var(--ds-gray-1000);
1920
+ background:var(--ds-gray-alpha-200);
1921
+ }
1922
+ /* Vercel CTA button style */
1923
+ .fx-nav-cta{
1924
+ display:inline-flex;align-items:center;gap:6px;
1925
+ height:32px;padding:0 12px;
1926
+ background:var(--ds-gray-1000);
1927
+ color:var(--ds-background-100);
1928
+ font-size:13px;font-weight:500;
1929
+ border-radius:var(--radius-md);
1930
+ transition:opacity var(--duration-normal) var(--ease-in-out);
1931
+ white-space:nowrap;
1932
+ }
1933
+ .fx-nav-cta:hover{opacity:.85}
1934
+ .fx-hamburger{display:none;flex-direction:column;gap:5px;padding:6px;border-radius:var(--radius-md)}
1935
+ .fx-hamburger span{display:block;width:18px;height:1px;background:var(--ds-gray-900);transition:all var(--duration-normal) var(--ease-in-out)}
1936
+ .fx-hamburger.open span:nth-child(1){transform:rotate(45deg) translate(4px,4px)}
1937
+ .fx-hamburger.open span:nth-child(2){opacity:0}
1938
+ .fx-hamburger.open span:nth-child(3){transform:rotate(-45deg) translate(4px,-4px)}
1939
+ @media(max-width:640px){
1940
+ .fx-hamburger{display:flex}
1941
+ .fx-nav-links{
1942
+ display:none;width:100%;
1943
+ flex-direction:column;align-items:stretch;
1944
+ padding:8px 0;gap:1px;
1945
+ border-top:1px solid var(--ds-gray-alpha-400);margin-top:8px;
1946
+ }
1947
+ .fx-nav-links.open{display:flex}
1948
+ .fx-nav-link{padding:8px 10px}
1949
+ }
1950
+
1951
+ /* ═══════════════════════════════════════════
1952
+ HERO
1953
+ ═══════════════════════════════════════════ */
1954
+ .fx-hero{
1955
+ display:flex;align-items:center;justify-content:center;
1956
+ min-height:calc(100svh - 54px);
1957
+ padding:80px 24px 64px;
1958
+ position:relative;overflow:hidden;
1959
+ }
1960
+ .fx-hero-inner{
1961
+ max-width:960px;width:100%;
1962
+ text-align:center;
1963
+ display:flex;flex-direction:column;align-items:center;
1964
+ gap:24px;
1965
+ position:relative;z-index:1;
1966
+ }
1967
+ .fx-hero-minimal{min-height:50vh!important}
1968
+ .fx-hero-tall{min-height:100svh!important}
1969
+ /* Landing: Vercel-style grid + radial */
1970
+ .fx-hero-landing{overflow:hidden}
1971
+ .fx-hero-grid{
1972
+ position:absolute;inset:0;pointer-events:none;
1973
+ background-image:
1974
+ linear-gradient(var(--ds-gray-alpha-200) 1px,transparent 1px),
1975
+ linear-gradient(90deg,var(--ds-gray-alpha-200) 1px,transparent 1px);
1976
+ background-size:48px 48px;
1977
+ mask-image:radial-gradient(ellipse 80% 70% at 50% 0%,black 40%,transparent 100%);
1978
+ -webkit-mask-image:radial-gradient(ellipse 80% 70% at 50% 0%,black 40%,transparent 100%);
1979
+ }
1980
+ /* Vercel-style ambient glow */
1981
+ .fx-hero-landing::after{
1982
+ content:'';position:absolute;
1983
+ width:80vw;height:40vh;max-width:900px;
1984
+ border-radius:50%;
1985
+ background:radial-gradient(ellipse,rgba(var(--aip-accent-rgb),.08) 0%,transparent 60%);
1986
+ left:50%;top:0;transform:translate(-50%,-20%);
1987
+ pointer-events:none;
1988
+ animation:fx-glow 8s ease-in-out infinite;
1989
+ }
1990
+ @keyframes fx-glow{0%,100%{opacity:.6}50%{opacity:1}}
1991
+ /* Vercel hero typography */
1992
+ .fx-title{
1993
+ font-size:clamp(40px,6vw,80px);
1994
+ font-weight:700;
1995
+ letter-spacing:-.04em;
1996
+ line-height:1.05;
1997
+ color:var(--ds-gray-1000);
1998
+ }
1999
+ .fx-gradient-text{
2000
+ background:linear-gradient(90deg,var(--ds-gray-1000) 0%,var(--ds-gray-700) 100%);
2001
+ -webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;
2002
+ }
2003
+ /* Override with accent when set */
2004
+ .fx-gradient-text-accent{
2005
+ background:linear-gradient(135deg,var(--ds-gray-1000) 30%,rgba(var(--aip-accent-rgb),1) 100%);
2006
+ -webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;
2007
+ }
2008
+ .fx-sub{
2009
+ font-size:clamp(15px,2vw,18px);
2010
+ line-height:1.65;
2011
+ color:var(--ds-gray-900);
2012
+ max-width:540px;font-weight:400;
2013
+ }
2014
+ /* Vercel hero badge */
2015
+ .fx-hero-badge{
2016
+ display:inline-flex;align-items:center;gap:6px;
2017
+ height:28px;padding:0 10px;
2018
+ background:var(--ds-gray-alpha-100);
2019
+ border:1px solid var(--ds-gray-alpha-400);
2020
+ border-radius:var(--radius-full);
2021
+ font-size:12px;font-weight:500;color:var(--ds-gray-900);
2022
+ letter-spacing:.01em;
2023
+ }
2024
+ .fx-hero-badge-dot{
2025
+ width:5px;height:5px;border-radius:50%;
2026
+ background:var(--ds-green-700);
2027
+ animation:fx-pulse 3s ease infinite;flex-shrink:0;
2028
+ }
2029
+ @keyframes fx-pulse{0%,100%{opacity:1}50%{opacity:.4}}
2030
+ /* Vercel CTA button */
2031
+ .fx-cta{
2032
+ display:inline-flex;align-items:center;gap:6px;
2033
+ height:40px;padding:0 20px;
2034
+ background:var(--ds-gray-1000);
2035
+ color:var(--ds-background-100);
2036
+ font-size:14px;font-weight:500;letter-spacing:-.01em;
2037
+ border-radius:var(--radius-md);
2038
+ /* Only transform per Vercel guidelines */
2039
+ transition:opacity var(--duration-normal) var(--ease-in-out),transform var(--duration-normal) var(--ease-out);
2040
+ }
2041
+ .fx-cta:hover{opacity:.88;transform:translateY(-1px)}
2042
+ .fx-cta:active{transform:translateY(0)}
2043
+ .fx-cta-outline{
2044
+ background:transparent!important;
2045
+ border:1px solid var(--ds-gray-alpha-400)!important;
2046
+ color:var(--ds-gray-900)!important;
2047
+ }
2048
+ .fx-cta-outline:hover{background:var(--ds-gray-alpha-100)!important}
2049
+ /* Vercel hero split */
2050
+ .fx-hero-split{
2051
+ display:grid;grid-template-columns:1fr 1fr;gap:64px;
2052
+ align-items:center;padding:80px 40px;min-height:80vh;
2053
+ }
2054
+ @media(max-width:768px){.fx-hero-split{grid-template-columns:1fr;padding:48px 24px;min-height:auto}}
2055
+ .fx-hero-split .fx-hero-inner{text-align:left;align-items:flex-start;max-width:none}
2056
+ .fx-hero-img{width:100%;border-radius:var(--radius-lg);border:1px solid var(--ds-gray-alpha-400)}
2057
+
2058
+ /* ═══════════════════════════════════════════
2059
+ STATS BAR — Geist big number style
2060
+ ═══════════════════════════════════════════ */
2061
+ .fx-stats{
2062
+ display:grid;
2063
+ grid-template-columns:repeat(auto-fit,minmax(140px,1fr));
2064
+ border-top:1px solid var(--ds-gray-alpha-400);
2065
+ border-bottom:1px solid var(--ds-gray-alpha-400);
2066
+ }
2067
+ .fx-stat{
2068
+ padding:40px 24px;text-align:center;
2069
+ border-right:1px solid var(--ds-gray-alpha-400);
2070
+ transition:background var(--duration-normal) var(--ease-in-out);
2071
+ }
2072
+ .fx-stat:last-child{border-right:none}
2073
+ .fx-stat:hover{background:var(--ds-gray-alpha-100)}
2074
+ .fx-stat-val{
2075
+ font-size:clamp(28px,4vw,40px);
2076
+ font-weight:700;letter-spacing:-.04em;line-height:1;
2077
+ color:var(--ds-gray-1000);
2078
+ font-variant-numeric:tabular-nums;
2079
+ }
2080
+ .fx-stat-lbl{
2081
+ font-size:12px;font-weight:500;
2082
+ text-transform:uppercase;letter-spacing:.08em;
2083
+ color:var(--ds-gray-700);
2084
+ margin-top:8px;
2085
+ }
2086
+ .fx-stat-vs{font-size:11px;color:var(--ds-gray-600);margin-top:4px;letter-spacing:.01em}
2087
+ @media(max-width:640px){
2088
+ .fx-stats{grid-template-columns:repeat(2,1fr)}
2089
+ .fx-stat{border-right:none;border-bottom:1px solid var(--ds-gray-alpha-400)}
2090
+ .fx-stat:nth-child(odd){border-right:1px solid var(--ds-gray-alpha-400)}
2091
+ .fx-stat:last-child,:nth-last-child(-n+2):nth-child(even){border-bottom:none}
2092
+ }
2093
+
2094
+ /* ═══════════════════════════════════════════
2095
+ SECTIONS
2096
+ ═══════════════════════════════════════════ */
2097
+ .fx-sect{padding:80px 40px;position:relative}
2098
+ @media(max-width:768px){.fx-sect{padding:64px 24px}}
2099
+ .fx-sect-title{
2100
+ font-size:clamp(24px,3.5vw,40px);
2101
+ font-weight:700;letter-spacing:-.03em;line-height:1.15;
2102
+ margin-bottom:12px;text-align:center;color:var(--ds-gray-1000);
2103
+ }
2104
+ .fx-sect-body{
2105
+ font-size:15px;line-height:1.7;text-align:center;
2106
+ color:var(--ds-gray-900);max-width:480px;margin:0 auto;
2107
+ }
2108
+ .fx-sect-link{font-size:13px;font-weight:500;color:var(--ds-blue-700);display:inline-block;margin-top:12px}
2109
+
2110
+ /* ═══════════════════════════════════════════
2111
+ CARDS / GRID — Geist card style
2112
+ ═══════════════════════════════════════════ */
2113
+ .fx-grid{display:grid;gap:12px;padding:0 40px 80px}
2114
+ .fx-grid-2{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
2115
+ .fx-grid-3{grid-template-columns:repeat(auto-fit,minmax(240px,1fr))}
2116
+ .fx-grid-4{grid-template-columns:repeat(auto-fit,minmax(200px,1fr))}
2117
+ @media(max-width:640px){.fx-grid{padding:0 24px 48px}.fx-grid-2,.fx-grid-3,.fx-grid-4{grid-template-columns:1fr}}
2118
+ .fx-card{
2119
+ border-radius:var(--radius-lg);
2120
+ padding:24px;
2121
+ background:var(--ds-background-200);
2122
+ border:1px solid var(--ds-gray-alpha-400);
2123
+ transition:border-color var(--duration-normal) var(--ease-in-out),transform var(--duration-slow) var(--ease-out);
2124
+ position:relative;overflow:hidden;
2125
+ }
2126
+ .fx-card:hover{
2127
+ border-color:var(--ds-gray-alpha-700);
2128
+ transform:translateY(-1px);
2129
+ }
2130
+ .fx-card-img{width:100%;border-radius:var(--radius-md);height:180px;object-fit:cover;margin-bottom:16px;border:1px solid var(--ds-gray-alpha-400)}
2131
+ .fx-icon{
2132
+ font-size:20px;
2133
+ margin-bottom:16px;
2134
+ width:40px;height:40px;
2135
+ display:flex;align-items:center;justify-content:center;
2136
+ border-radius:var(--radius-md);
2137
+ background:var(--ds-gray-alpha-200);
2138
+ border:1px solid var(--ds-gray-alpha-400);
2139
+ }
2140
+ .fx-card-title{
2141
+ font-size:14px;font-weight:600;letter-spacing:-.015em;
2142
+ margin-bottom:6px;color:var(--ds-gray-1000);line-height:1.4;
2143
+ }
2144
+ .fx-card-body{font-size:13px;line-height:1.65;color:var(--ds-gray-900)}
2145
+ .fx-card-link{font-size:13px;font-weight:500;color:var(--ds-blue-700);display:inline-block;margin-top:12px}
2146
+ .fx-grid-feature .fx-card:hover{border-color:rgba(var(--aip-accent-rgb),.4)}
2147
+ .fx-grid-feature .fx-icon{background:rgba(var(--aip-accent-rgb),.06);border-color:rgba(var(--aip-accent-rgb),.15)}
2148
+
2149
+ /* ═══════════════════════════════════════════
2150
+ FORMS — Geist input style
2151
+ ═══════════════════════════════════════════ */
2152
+ .fx-form-wrap{padding:48px 40px;display:flex;justify-content:center}
2153
+ .fx-form{
2154
+ width:100%;max-width:400px;
2155
+ background:var(--ds-background-200);
2156
+ border:1px solid var(--ds-gray-alpha-400);
2157
+ border-radius:var(--radius-xl);padding:32px;
2158
+ }
2159
+ .fx-field{margin-bottom:16px}
2160
+ .fx-label{
2161
+ display:block;font-size:13px;font-weight:500;
2162
+ color:var(--ds-gray-1000);margin-bottom:6px;letter-spacing:-.01em;
2163
+ }
2164
+ .fx-input{
2165
+ width:100%;height:40px;padding:0 12px;
2166
+ background:var(--ds-background-100);
2167
+ border:1px solid var(--ds-gray-alpha-400);
2168
+ border-radius:var(--radius-md);
2169
+ color:var(--ds-gray-1000);font-size:14px;
2170
+ outline:none;-webkit-appearance:none;
2171
+ transition:border-color var(--duration-normal) var(--ease-in-out),box-shadow var(--duration-normal) var(--ease-in-out);
2172
+ }
2173
+ .fx-input:hover{border-color:var(--ds-gray-alpha-700)}
2174
+ .fx-input:focus{
2175
+ border-color:var(--ds-blue-700);
2176
+ box-shadow:0 0 0 3px rgba(var(--ds-blue-rgb),.15);
2177
+ }
2178
+ .fx-input::placeholder{color:var(--ds-gray-600)}
2179
+ textarea.fx-input{height:auto;padding:10px 12px;resize:vertical;min-height:80px;line-height:1.5}
2180
+ .fx-btn{
2181
+ width:100%;height:40px;padding:0 16px;
2182
+ background:var(--ds-gray-1000);color:var(--ds-background-100);
2183
+ font-size:14px;font-weight:500;letter-spacing:-.01em;
2184
+ border-radius:var(--radius-md);
2185
+ margin-top:4px;
2186
+ transition:opacity var(--duration-normal) var(--ease-in-out),transform var(--duration-normal) var(--ease-out);
2187
+ }
2188
+ .fx-btn:hover{opacity:.88;transform:translateY(-1px)}
2189
+ .fx-btn:active{transform:translateY(0)}
2190
+ .fx-btn:disabled{opacity:.4;cursor:not-allowed;transform:none}
2191
+ .fx-btn-wrap{padding:0 40px 24px}
2192
+ .fx-standalone-btn{width:auto;padding:0 20px;margin-top:0}
2193
+ .fx-form-msg{font-size:13px;padding:6px 0;min-height:24px;text-align:center;font-weight:500}
2194
+ .fx-form-err{color:var(--ds-red-700)}.fx-form-ok{color:var(--ds-green-700)}
2195
+
2196
+ /* ═══════════════════════════════════════════
2197
+ TABLE — Geist table style
2198
+ ═══════════════════════════════════════════ */
2199
+ .fx-table-wrap{overflow-x:auto;padding:0 40px 64px}
2200
+ .fx-table{width:100%;border-collapse:collapse;font-size:13px}
2201
+ .fx-th{
2202
+ text-align:left;padding:0 12px 10px;
2203
+ font-size:11px;font-weight:600;text-transform:uppercase;
2204
+ letter-spacing:.06em;color:var(--ds-gray-700);
2205
+ border-bottom:1px solid var(--ds-gray-alpha-400);white-space:nowrap;
2206
+ }
2207
+ .fx-th-actions{opacity:.5}
2208
+ .fx-tr{border-bottom:1px solid var(--ds-gray-alpha-200);transition:background var(--duration-fast) var(--ease-in-out)}
2209
+ .fx-tr:last-child{border-bottom:none}
2210
+ .fx-tr:hover{background:var(--ds-gray-alpha-100)}
2211
+ .fx-td{padding:12px;color:var(--ds-gray-900);vertical-align:middle}
2212
+ .fx-td:first-child{color:var(--ds-gray-1000);font-weight:500}
2213
+ .fx-td-empty{padding:48px 12px;text-align:center;color:var(--ds-gray-600);font-size:13px}
2214
+ .fx-td-actions{white-space:nowrap;padding:6px 12px!important}
2215
+ .fx-action-btn{
2216
+ height:28px;padding:0 10px;border-radius:var(--radius-md);
2217
+ font-size:12px;font-weight:500;margin-right:4px;
2218
+ transition:background var(--duration-normal) var(--ease-in-out);
2219
+ }
2220
+ .fx-edit-btn{background:var(--ds-blue-100);color:var(--ds-blue-700)}
2221
+ .fx-edit-btn:hover{background:var(--ds-blue-200)}
2222
+ .fx-delete-btn{background:var(--ds-red-100);color:var(--ds-red-700)}
2223
+ .fx-delete-btn:hover{background:var(--ds-red-200)}
2224
+
2225
+ /* ═══════════════════════════════════════════
2226
+ PRICING — Geist pricing style
2227
+ ═══════════════════════════════════════════ */
2228
+ .fx-pricing{
2229
+ display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));
2230
+ gap:16px;padding:24px 40px 80px;align-items:start;
2231
+ }
2232
+ .fx-pricing-card{
2233
+ border-radius:var(--radius-xl);padding:32px;
2234
+ background:var(--ds-background-200);
2235
+ border:1px solid var(--ds-gray-alpha-400);
2236
+ position:relative;
2237
+ transition:border-color var(--duration-normal) var(--ease-in-out);
2238
+ }
2239
+ .fx-pricing-featured{border-color:var(--ds-gray-alpha-700)!important}
2240
+ .fx-pricing-badge{
2241
+ position:absolute;top:-12px;left:50%;transform:translateX(-50%);
2242
+ background:var(--ds-gray-1000);color:var(--ds-background-100);
2243
+ font-size:11px;font-weight:600;padding:3px 10px;
2244
+ border-radius:var(--radius-full);white-space:nowrap;letter-spacing:.04em;
2245
+ }
2246
+ .fx-pricing-name{font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.1em;color:var(--ds-gray-700);margin-bottom:12px}
2247
+ .fx-pricing-price{font-size:40px;font-weight:700;letter-spacing:-.05em;line-height:1;margin-bottom:8px;color:var(--ds-gray-1000);font-variant-numeric:tabular-nums}
2248
+ .fx-pricing-price-sm{font-size:28px}
2249
+ .fx-pricing-desc{font-size:13px;line-height:1.6;margin-bottom:24px;color:var(--ds-gray-900)}
2250
+ .fx-pricing-cta{
2251
+ display:block;text-align:center;height:36px;line-height:36px;
2252
+ border-radius:var(--radius-md);font-size:13px;font-weight:500;
2253
+ background:var(--ds-gray-1000);color:var(--ds-background-100);
2254
+ transition:opacity var(--duration-normal) var(--ease-in-out);
2255
+ }
2256
+ .fx-pricing-cta:hover{opacity:.85}
2257
+
2258
+ /* ═══════════════════════════════════════════
2259
+ FAQ — Geist collapse style
2260
+ ═══════════════════════════════════════════ */
2261
+ .fx-faq-wrap{padding:0 40px 64px}
2262
+ .fx-faq{max-width:640px;margin:0 auto}
2263
+ .fx-faq-item{
2264
+ border-bottom:1px solid var(--ds-gray-alpha-400);
2265
+ cursor:pointer;
2266
+ }
2267
+ .fx-faq-item:first-child{border-top:1px solid var(--ds-gray-alpha-400)}
2268
+ .fx-faq-q{
2269
+ display:flex;justify-content:space-between;align-items:center;
2270
+ padding:16px 0;
2271
+ font-size:14px;font-weight:500;color:var(--ds-gray-1000);
2272
+ user-select:none;
2273
+ }
2274
+ .fx-faq-arrow{
2275
+ width:16px;height:16px;color:var(--ds-gray-700);flex-shrink:0;
2276
+ transition:transform var(--duration-normal) var(--ease-in-out);
2277
+ }
2278
+ .fx-faq-arrow::after{
2279
+ content:'↓';font-size:12px;display:block;text-align:center;line-height:16px;
2280
+ }
2281
+ .fx-faq-item.open .fx-faq-arrow{transform:rotate(180deg)}
2282
+ .fx-faq-a{
2283
+ max-height:0;overflow:hidden;
2284
+ font-size:14px;line-height:1.65;color:var(--ds-gray-900);
2285
+ transition:max-height var(--duration-slow) var(--ease-out),padding var(--duration-slow) var(--ease-out);
2286
+ padding:0;
2287
+ }
2288
+ .fx-faq-item.open .fx-faq-a{max-height:300px;padding:0 0 16px}
2289
+
2290
+ /* ═══════════════════════════════════════════
2291
+ CODE WINDOW — Geist snippet style
2292
+ ═══════════════════════════════════════════ */
2293
+ .fx-code-window{
2294
+ border-radius:var(--radius-lg);overflow:hidden;
2295
+ border:1px solid var(--ds-gray-alpha-400);
2296
+ background:var(--ds-background-200);
2297
+ margin:0 40px 24px;
2298
+ }
2299
+ .fx-code-bar{
2300
+ display:flex;align-items:center;gap:8px;
2301
+ padding:10px 16px;
2302
+ background:var(--ds-background-200);
2303
+ border-bottom:1px solid var(--ds-gray-alpha-400);
2304
+ }
2305
+ .fx-dots{display:flex;gap:5px}
2306
+ .fx-dots span{width:10px;height:10px;border-radius:50%}
2307
+ .fx-dots span:nth-child(1){background:#ff5f57}
2308
+ .fx-dots span:nth-child(2){background:#febc2e}
2309
+ .fx-dots span:nth-child(3){background:#28c840}
2310
+ .fx-code-lang{
2311
+ font-size:11px;letter-spacing:.06em;text-transform:uppercase;
2312
+ color:var(--ds-gray-700);margin-left:4px;font-family:var(--geist-mono);font-weight:500;
2313
+ }
2314
+ .fx-code-copy{
2315
+ margin-left:auto;height:24px;padding:0 8px;
2316
+ font-family:var(--geist-mono);font-size:11px;letter-spacing:.04em;
2317
+ background:var(--ds-gray-alpha-200);
2318
+ border:1px solid var(--ds-gray-alpha-400);
2319
+ color:var(--ds-gray-900);border-radius:var(--radius-sm);cursor:pointer;
2320
+ transition:background var(--duration-normal),color var(--duration-normal);
2321
+ }
2322
+ .fx-code-copy:hover{background:var(--ds-gray-alpha-400);color:var(--ds-gray-1000)}
2323
+ .fx-code-body{padding:20px 24px;overflow-x:auto}
2324
+ .fx-code-line{font-family:var(--geist-mono);font-size:13px;line-height:1.75;color:var(--ds-gray-800);white-space:pre}
2325
+ .fx-kw{color:#c792ea}.fx-st{color:#a6e3a1}.fx-fn{color:#89b4fa}
2326
+ .fx-nb{color:#fab387}.fx-op{color:rgba(var(--aip-accent-rgb),1)}.fx-comment{color:var(--ds-gray-600);font-style:italic}
2327
+
2328
+ /* ═══════════════════════════════════════════
2329
+ INSTALL BLOCK
2330
+ ═══════════════════════════════════════════ */
2331
+ .fx-install-wrap{
2332
+ border-radius:var(--radius-lg);overflow:hidden;
2333
+ border:1px solid var(--ds-gray-alpha-400);
2334
+ background:var(--ds-background-200);
2335
+ margin:0 40px 24px;max-width:480px;
2336
+ }
2337
+ .fx-install-body{padding:20px 24px}
2338
+ .fx-install-line{display:flex;gap:10px;padding:3px 0;font-family:var(--geist-mono);font-size:13px;line-height:1.6}
2339
+ .fx-install-prompt{color:rgba(var(--aip-accent-rgb),1);flex-shrink:0;font-weight:700}
2340
+ .fx-install-cmd{color:var(--ds-gray-1000)}
2341
+ .fx-install-comment{font-family:var(--geist-mono);font-size:12px;color:var(--ds-gray-700);padding:3px 0;font-style:italic}
2342
+
2343
+ /* ═══════════════════════════════════════════
2344
+ BENCHMARK CARDS
2345
+ ═══════════════════════════════════════════ */
2346
+ .fx-benchmark{
2347
+ display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));
2348
+ gap:12px;padding:0 40px 64px;
2349
+ }
2350
+ .fx-bench-card{
2351
+ border-radius:var(--radius-lg);padding:24px;
2352
+ background:var(--ds-background-200);
2353
+ border:1px solid var(--ds-gray-alpha-400);
2354
+ position:relative;overflow:hidden;
2355
+ transition:border-color var(--duration-normal) var(--ease-in-out);
2356
+ }
2357
+ .fx-bench-card:hover{border-color:var(--ds-gray-alpha-700)}
2358
+ /* Subtle top accent line */
2359
+ .fx-bench-card::after{
2360
+ content:'';position:absolute;top:0;left:0;right:0;height:1px;
2361
+ background:linear-gradient(90deg,transparent,rgba(var(--aip-accent-rgb),.6),transparent);
2362
+ }
2363
+ .fx-bench-label{
2364
+ font-size:11px;letter-spacing:.06em;text-transform:uppercase;
2365
+ color:var(--ds-gray-700);margin-bottom:10px;font-weight:600;
2366
+ }
2367
+ .fx-bench-num{
2368
+ font-size:clamp(24px,4vw,36px);font-weight:700;
2369
+ letter-spacing:-.04em;line-height:1;
2370
+ color:var(--ds-gray-1000);font-variant-numeric:tabular-nums;
2371
+ }
2372
+ .fx-bench-vs{font-size:12px;color:var(--ds-gray-700);margin-top:6px;font-family:var(--geist-mono)}
2373
+ .fx-bench-bar{margin-top:16px;height:3px;background:var(--ds-gray-alpha-200);border-radius:999px;overflow:hidden}
2374
+ .fx-bench-fill{height:100%;border-radius:999px;background:rgba(var(--aip-accent-rgb),1);transition:width 1.2s var(--ease-out)}
2375
+
2376
+ /* ═══════════════════════════════════════════
2377
+ MARQUEE — smooth infinite scroll
2378
+ ═══════════════════════════════════════════ */
2379
+ .fx-marquee{
2380
+ overflow:hidden;padding:20px 0;
2381
+ border-top:1px solid var(--ds-gray-alpha-400);
2382
+ border-bottom:1px solid var(--ds-gray-alpha-400);
2383
+ -webkit-mask:linear-gradient(90deg,transparent,black 10%,black 90%,transparent);
2384
+ mask:linear-gradient(90deg,transparent,black 10%,black 90%,transparent);
2385
+ }
2386
+ .fx-marquee-track{display:flex;width:max-content;animation:fx-marquee 30s linear infinite}
1867
2387
  .fx-marquee:hover .fx-marquee-track{animation-play-state:paused}
1868
2388
  @keyframes fx-marquee{0%{transform:translateX(0)}100%{transform:translateX(-50%)}}
1869
- .fx-marquee-item{font-size:.9375rem;font-weight:600;opacity:.35;white-space:nowrap;padding:0 1.5rem;transition:opacity .2s}
1870
- .fx-marquee-item:hover{opacity:.7}
1871
- .fx-marquee-sep{opacity:.15;padding:0 .25rem}
1872
- /* ── cta section ── */
1873
- .fx-cta-section{position:relative;padding:6rem 2.5rem;text-align:center;overflow:hidden}
1874
- .fx-cta-glow{position:absolute;width:600px;height:400px;border-radius:50%;background:radial-gradient(ellipse,rgba(var(--accent-rgb,255,87,34),.12),transparent 70%);left:50%;top:50%;transform:translate(-50%,-50%);pointer-events:none}
1875
- .fx-cta-inner{position:relative;z-index:1;max-width:44rem;margin:0 auto;display:flex;flex-direction:column;align-items:center;gap:1.5rem}
1876
- .fx-cta-title{font-size:clamp(2rem,5vw,4rem);font-weight:900;letter-spacing:-.04em;line-height:1.05}
1877
- .fx-cta-sub{font-size:1.0625rem;line-height:1.75;opacity:.65;max-width:36rem}
1878
- .fx-cta-actions{display:flex;gap:.875rem;flex-wrap:wrap;justify-content:center}
1879
- .fx-cta-outline{background:transparent!important;border:1px solid rgba(255,255,255,.2)!important;color:inherit!important}
1880
- .fx-cta-outline:hover{background:rgba(255,255,255,.05)!important}
1881
- /* ── steps ── */
1882
- .fx-steps{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:2rem;padding:2rem 2.5rem 4rem;position:relative}
1883
- .fx-steps::before{content:"";position:absolute;top:3.5rem;left:calc(2.5rem + 1.5rem);right:calc(2.5rem + 1.5rem);height:1px;background:linear-gradient(90deg,transparent,rgba(255,255,255,.1),transparent);pointer-events:none}
1884
- .fx-step{display:flex;flex-direction:column;align-items:flex-start;gap:1rem}
1885
- .fx-step-num{width:48px;height:48px;border-radius:50%;background:var(--accent,#ff5722);color:#fff;font-weight:900;font-size:1.125rem;display:flex;align-items:center;justify-content:center;flex-shrink:0;position:relative;z-index:1}
1886
- .fx-step-title{font-size:1rem;font-weight:700;margin-bottom:.375rem;letter-spacing:-.02em}
1887
- .fx-step-desc{font-size:.875rem;line-height:1.65;opacity:.6}
1888
- .fx-steps-vertical{grid-template-columns:1fr}
1889
- .fx-steps-vertical::before{display:none}
1890
- .fx-steps-vertical .fx-step{flex-direction:row}
1891
- /* ── compare ── */
1892
- .fx-compare{max-width:640px;margin:0 auto 4rem;padding:0 2.5rem}
1893
- .fx-compare-header{display:grid;grid-template-columns:1fr 1fr 1fr;padding:.75rem 1rem;background:rgba(255,255,255,.04);border-radius:.75rem .75rem 0 0;font-size:.72rem;font-weight:700;text-transform:uppercase;letter-spacing:.1em;opacity:.6}
1894
- .fx-compare-row{display:grid;grid-template-columns:1fr 1fr 1fr;padding:.75rem 1rem;border-bottom:1px solid rgba(255,255,255,.05);transition:background .15s}
1895
- .fx-compare-row:hover{background:rgba(255,255,255,.02)}
1896
- .fx-compare-row:last-child{border-bottom:none;border-radius:0 0 .75rem .75rem}
1897
- .fx-compare-cell{font-size:.875rem}
1898
- .fx-compare-feature{opacity:.7}
1899
- .fx-compare-col-a{text-align:center;color:#4ade80}
1900
- .fx-compare-col-b{text-align:center;opacity:.35}
1901
- /* ── video ── */
1902
- .fx-video-wrap{padding:0 2.5rem 3rem}
1903
- .fx-video-yt{position:relative;padding-bottom:56.25%;height:0;overflow:hidden;border-radius:1rem;border:1px solid rgba(255,255,255,.06)}
2389
+ .fx-marquee-item{
2390
+ font-size:13px;font-weight:500;
2391
+ color:var(--ds-gray-700);
2392
+ white-space:nowrap;padding:0 24px;
2393
+ transition:color var(--duration-normal);
2394
+ }
2395
+ .fx-marquee-item:hover{color:var(--ds-gray-1000)}
2396
+ .fx-marquee-sep{color:var(--ds-gray-alpha-400)}
2397
+
2398
+ /* ═══════════════════════════════════════════
2399
+ CTA SECTION
2400
+ ═══════════════════════════════════════════ */
2401
+ .fx-cta-section{
2402
+ position:relative;padding:120px 40px;text-align:center;overflow:hidden;
2403
+ border-top:1px solid var(--ds-gray-alpha-400);
2404
+ }
2405
+ .fx-cta-glow{
2406
+ position:absolute;
2407
+ width:700px;height:350px;border-radius:50%;
2408
+ background:radial-gradient(ellipse,rgba(var(--aip-accent-rgb),.06),transparent 60%);
2409
+ left:50%;top:50%;transform:translate(-50%,-50%);pointer-events:none;
2410
+ }
2411
+ .fx-cta-inner{position:relative;z-index:1;max-width:560px;margin:0 auto;display:flex;flex-direction:column;align-items:center;gap:24px}
2412
+ .fx-cta-title{
2413
+ font-size:clamp(28px,4vw,48px);font-weight:700;
2414
+ letter-spacing:-.04em;line-height:1.1;color:var(--ds-gray-1000);
2415
+ }
2416
+ .fx-cta-sub{font-size:15px;line-height:1.65;color:var(--ds-gray-900);max-width:440px}
2417
+ .fx-cta-actions{display:flex;gap:12px;flex-wrap:wrap;justify-content:center}
2418
+
2419
+ /* ═══════════════════════════════════════════
2420
+ STEPS — numbered with connector
2421
+ ═══════════════════════════════════════════ */
2422
+ .fx-steps{
2423
+ display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));
2424
+ gap:40px;padding:16px 40px 80px;position:relative;
2425
+ }
2426
+ .fx-steps::before{
2427
+ content:'';position:absolute;top:36px;
2428
+ left:calc(40px + 20px);right:calc(40px + 20px);
2429
+ height:1px;background:var(--ds-gray-alpha-400);pointer-events:none;
2430
+ }
2431
+ @media(max-width:640px){.fx-steps::before{display:none}.fx-steps{gap:32px;padding:0 24px 48px}}
2432
+ .fx-step{display:flex;flex-direction:column;align-items:flex-start;gap:16px}
2433
+ .fx-step-num{
2434
+ width:36px;height:36px;border-radius:50%;
2435
+ background:var(--ds-gray-alpha-200);
2436
+ border:1px solid var(--ds-gray-alpha-400);
2437
+ color:var(--ds-gray-1000);
2438
+ font-size:13px;font-weight:700;font-variant-numeric:tabular-nums;
2439
+ display:flex;align-items:center;justify-content:center;
2440
+ flex-shrink:0;position:relative;z-index:1;
2441
+ }
2442
+ .fx-step-title{font-size:14px;font-weight:600;letter-spacing:-.015em;color:var(--ds-gray-1000)}
2443
+ .fx-step-desc{font-size:13px;line-height:1.6;color:var(--ds-gray-900)}
2444
+
2445
+ /* ═══════════════════════════════════════════
2446
+ COMPARE — visual feature table
2447
+ ═══════════════════════════════════════════ */
2448
+ .fx-compare{
2449
+ max-width:560px;margin:0 auto 64px;padding:0 40px;
2450
+ border-radius:var(--radius-xl);overflow:hidden;
2451
+ border:1px solid var(--ds-gray-alpha-400);
2452
+ }
2453
+ .fx-compare-header{
2454
+ display:grid;grid-template-columns:1fr 1fr 1fr;
2455
+ padding:12px 16px;
2456
+ background:var(--ds-background-200);
2457
+ font-size:11px;font-weight:700;text-transform:uppercase;
2458
+ letter-spacing:.08em;color:var(--ds-gray-700);
2459
+ border-bottom:1px solid var(--ds-gray-alpha-400);
2460
+ }
2461
+ .fx-compare-row{
2462
+ display:grid;grid-template-columns:1fr 1fr 1fr;
2463
+ padding:12px 16px;border-bottom:1px solid var(--ds-gray-alpha-200);
2464
+ transition:background var(--duration-fast);
2465
+ }
2466
+ .fx-compare-row:last-child{border-bottom:none}
2467
+ .fx-compare-row:hover{background:var(--ds-gray-alpha-100)}
2468
+ .fx-compare-feature{font-size:13px;color:var(--ds-gray-900)}
2469
+ .fx-compare-col-a{text-align:center;font-size:14px;font-weight:600;color:var(--ds-green-700)}
2470
+ .fx-compare-col-b{text-align:center;font-size:14px;color:var(--ds-gray-600)}
2471
+
2472
+ /* ═══════════════════════════════════════════
2473
+ VIDEO
2474
+ ═══════════════════════════════════════════ */
2475
+ .fx-video-wrap{padding:0 40px 48px}
2476
+ .fx-video-yt{
2477
+ position:relative;padding-bottom:56.25%;height:0;overflow:hidden;
2478
+ border-radius:var(--radius-xl);border:1px solid var(--ds-gray-alpha-400);
2479
+ background:var(--ds-background-200);
2480
+ }
1904
2481
  .fx-video-yt iframe{position:absolute;top:0;left:0;width:100%;height:100%}
1905
- .fx-video{width:100%;border-radius:1rem;border:1px solid rgba(255,255,255,.06)}
1906
- /* ── gradient text ── */
1907
- .fx-gradient-text{background:linear-gradient(135deg,var(--accent,#ff5722),#ff8a50,#ffd4c4);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}
1908
- /* ── scroll animations (IntersectionObserver) ── */
1909
- .fx-animate{opacity:0;transform:translateY(20px);transition:opacity .6s cubic-bezier(.4,0,.2,1),transform .6s cubic-bezier(.4,0,.2,1)}
1910
- .fx-animate.fx-visible{opacity:1;transform:none}
1911
- .fx-animate-delay-1{transition-delay:.1s}
1912
- .fx-animate-delay-2{transition-delay:.2s}
1913
- .fx-animate-delay-3{transition-delay:.3s}
1914
- .fx-animate-stagger>*{opacity:0;transform:translateY(16px);transition:opacity .5s cubic-bezier(.4,0,.2,1),transform .5s cubic-bezier(.4,0,.2,1)}
1915
- .fx-animate-stagger.fx-visible>*:nth-child(1){opacity:1;transform:none;transition-delay:.05s}
1916
- .fx-animate-stagger.fx-visible>*:nth-child(2){opacity:1;transform:none;transition-delay:.15s}
1917
- .fx-animate-stagger.fx-visible>*:nth-child(3){opacity:1;transform:none;transition-delay:.25s}
1918
- .fx-animate-stagger.fx-visible>*:nth-child(4){opacity:1;transform:none;transition-delay:.35s}
1919
- .fx-animate-stagger.fx-visible>*:nth-child(5){opacity:1;transform:none;transition-delay:.45s}
1920
- .fx-animate-stagger.fx-visible>*:nth-child(6){opacity:1;transform:none;transition-delay:.55s}
1921
- /* ── number counter ── */
1922
- .fx-count{display:inline-block}
1923
- /* ── hero badge ── */
1924
- .fx-hero-badge{display:inline-flex;align-items:center;gap:.5rem;font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;padding:.3rem 1rem;border-radius:999px;border:1px solid rgba(255,255,255,.12);background:rgba(255,255,255,.04);margin-bottom:1.25rem}
1925
- .fx-hero-badge-dot{width:6px;height:6px;border-radius:50%;background:var(--accent,#ff5722);animation:fx-blink 2s ease infinite}
1926
- @keyframes fx-blink{0%,100%{opacity:1}50%{opacity:.2}}
1927
- .fx-year{font-variant-numeric:tabular-nums}
1928
- .fx-hero-minimal{min-height:50vh!important}
1929
- .fx-hero-minimal .fx-hero-inner{gap:1rem}
1930
- .fx-hero-tall{min-height:98vh!important}
1931
- .fx-hero-left .fx-hero-inner{text-align:left;align-items:flex-start;max-width:none;padding-left:2.5rem}
1932
- .fx-hero-left{justify-content:flex-start}
1933
- .fx-hero-dark-cta .fx-hero-ctas-dark{display:flex;gap:.75rem;flex-wrap:wrap;justify-content:center;padding:.75rem;background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.08);border-radius:.875rem;margin-top:.5rem}
1934
- .fx-spacer{width:100%}
1935
- .fx-divider{display:flex;align-items:center;gap:1rem;padding:2rem 2.5rem;opacity:.4}
1936
- .fx-divider::before,.fx-divider::after{content:'';flex:1;height:1px;background:currentColor}
1937
- .fx-divider-label{font-size:.75rem;font-family:monospace;white-space:nowrap;letter-spacing:.08em;text-transform:uppercase}
1938
- .fx-hr{border:none;border-top:1px solid rgba(255,255,255,.08);margin:1.5rem 2.5rem}
1939
- .fx-badge-row{padding:.5rem 2.5rem;display:flex;flex-wrap:wrap;gap:.5rem}
1940
- .fx-badge-tag{display:inline-block;font-size:.75rem;font-weight:600;padding:.3rem .875rem;border-radius:999px;background:rgba(37,99,235,.12);border:1px solid rgba(37,99,235,.25);color:#60a5fa;letter-spacing:.03em}
1941
- .fx-cols{display:grid;gap:1.5rem;padding:1rem 2.5rem}
1942
- .fx-cols-2{grid-template-columns:1fr 1fr}
1943
- .fx-cols-3{grid-template-columns:1fr 1fr 1fr}
1944
- .fx-cols-4{grid-template-columns:repeat(4,1fr)}
1945
- @media(max-width:640px){.fx-cols-2,.fx-cols-3,.fx-cols-4{grid-template-columns:1fr}}
2482
+ .fx-video{width:100%;border-radius:var(--radius-xl);border:1px solid var(--ds-gray-alpha-400)}
2483
+
2484
+ /* ═══════════════════════════════════════════
2485
+ TESTIMONIAL
2486
+ ═══════════════════════════════════════════ */
2487
+ .fx-testi-wrap{padding:80px 40px;display:flex;justify-content:center}
2488
+ .fx-testi{max-width:560px;text-align:center;display:flex;flex-direction:column;align-items:center;gap:20px}
2489
+ .fx-testi-img,.fx-testi-avatar{width:48px;height:48px;border-radius:50%;object-fit:cover}
2490
+ .fx-testi-avatar{
2491
+ display:flex;align-items:center;justify-content:center;
2492
+ font-size:18px;font-weight:700;
2493
+ background:var(--ds-background-200);
2494
+ border:1px solid var(--ds-gray-alpha-400);
2495
+ color:var(--ds-gray-1000);
2496
+ }
2497
+ .fx-testi-quote{font-size:18px;line-height:1.65;color:var(--ds-gray-900);letter-spacing:-.01em}
2498
+ .fx-testi-author{font-size:13px;font-weight:500;color:var(--ds-gray-700)}
2499
+
2500
+ /* ═══════════════════════════════════════════
2501
+ GALLERY
2502
+ ═══════════════════════════════════════════ */
2503
+ .fx-gallery{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:10px;padding:16px 40px 64px}
2504
+ .fx-gallery-item{border-radius:var(--radius-lg);overflow:hidden;aspect-ratio:4/3;border:1px solid var(--ds-gray-alpha-400)}
2505
+ .fx-gallery-item img{width:100%;height:100%;object-fit:cover;transition:transform var(--duration-slow) var(--ease-out)}
2506
+ .fx-gallery-item:hover img{transform:scale(1.03)}
2507
+
2508
+ /* ═══════════════════════════════════════════
2509
+ MISC COMPONENTS
2510
+ ═══════════════════════════════════════════ */
2511
+ .fx-divider{
2512
+ display:flex;align-items:center;gap:12px;
2513
+ padding:12px 40px;color:var(--ds-gray-700);font-size:12px;font-weight:500;
2514
+ }
2515
+ .fx-divider::before,.fx-divider::after{content:'';flex:1;height:1px;background:var(--ds-gray-alpha-400)}
2516
+ .fx-hr{border:none;height:1px;background:var(--ds-gray-alpha-400);margin:0 40px}
2517
+ .fx-badge-row{padding:6px 40px}
2518
+ .fx-badge-tag{
2519
+ font-size:11px;font-weight:600;padding:3px 8px;border-radius:var(--radius-full);
2520
+ background:rgba(var(--aip-accent-rgb),.08);color:rgba(var(--aip-accent-rgb),1);
2521
+ border:1px solid rgba(var(--aip-accent-rgb),.2);letter-spacing:.03em;
2522
+ }
2523
+ .fx-spacer{flex-shrink:0}
2524
+ .fx-html{padding:0 40px}
2525
+ .fx-cols{display:grid;gap:24px;padding:16px 40px 48px}
1946
2526
  .fx-col{min-width:0}
1947
- .fx-each{padding:.5rem 2.5rem}
1948
- .fx-each-list{display:flex;flex-direction:column;gap:.5rem}
1949
- .fx-each-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:.75rem}
1950
- .fx-html{padding:.5rem 2.5rem}
1951
- .fx-card-badge{display:inline-block;font-size:.65rem;font-weight:700;padding:.2rem .6rem;border-radius:999px;background:rgba(37,99,235,.15);color:#93c5fd;margin-bottom:.5rem;letter-spacing:.04em}
1952
- .fx-form-inline{padding:.75rem 2.5rem}.fx-form-inline-form{display:flex;align-items:flex-end;gap:.75rem;flex-wrap:wrap;background:none;border:none;padding:0;max-width:none}.fx-form-inline-form .fx-field{flex:1;min-width:160px;margin-bottom:0}.fx-btn-inline{width:auto;margin-top:0;flex-shrink:0}
1953
- .fx-form-minimal{padding:.5rem 2.5rem;max-width:24rem}.fx-form-minimal form{background:none;border:none;padding:0}
1954
- .fx-sect-accent{background:rgba(37,99,235,.06);border-left:3px solid #2563eb;padding-left:2rem}
1955
- .fx-sect-dark{background:rgba(0,0,0,.4)}
1956
- .fx-sect-full{padding:6rem 2.5rem}
1957
- .fx-pricing-compact{border-radius:.875rem;padding:1.25rem;display:flex;align-items:center;gap:1rem;border:1px solid rgba(255,255,255,.08)}
1958
- .fx-pricing-price-sm{font-size:1.5rem;font-weight:800;letter-spacing:-.04em}
1959
- .fx-grid-numbered>.fx-card{counter-increment:card-counter}
1960
- .fx-chart-wrap{padding:1rem 2.5rem;position:relative}.fx-chart-title{font-family:monospace;font-size:.65rem;letter-spacing:.1em;text-transform:uppercase;color:#475569;margin-bottom:.75rem}.fx-chart{max-height:320px}
1961
- .fx-kanban{display:flex;gap:1rem;padding:1rem 2.5rem;overflow-x:auto;align-items:flex-start}.fx-kanban-col{flex:0 0 280px;background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.08);border-radius:.875rem;padding:1rem}.fx-kanban-col-title{font-family:monospace;font-size:.65rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:#64748b;margin-bottom:.875rem}.fx-kanban-cards{min-height:80px;display:flex;flex-direction:column;gap:.5rem}.fx-kanban-card{background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.1);border-radius:.5rem;padding:.75rem;cursor:grab;font-size:.8125rem;line-height:1.5;transition:transform .15s,box-shadow .15s}.fx-kanban-card:hover{transform:translateY(-1px);box-shadow:0 4px 12px rgba(0,0,0,.3)}.fx-kanban-card.dragging{opacity:.5;cursor:grabbing}
1962
- .fx-editor-wrap{padding:.75rem 2.5rem}.fx-editor-toolbar{display:flex;gap:.25rem;margin-bottom:.5rem;flex-wrap:wrap}.fx-editor-btn{background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.1);color:#e2e8f0;border-radius:.375rem;padding:.25rem .625rem;cursor:pointer;font-size:.8125rem;font-family:inherit;transition:background .1s}.fx-editor-btn:hover{background:rgba(255,255,255,.12)}.fx-editor{min-height:160px;padding:1rem;background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.1);border-radius:.625rem;color:#e2e8f0;font-size:.875rem;line-height:1.7;outline:none}.fx-editor:empty::before{content:attr(placeholder);color:#475569;pointer-events:none}.fx-editor-save{margin-left:auto}
1963
- .fx-grid-numbered>.fx-card::before{content:counter(card-counter,decimal-leading-zero);font-size:2rem;font-weight:900;opacity:.15;font-family:monospace;line-height:1}
1964
- .fx-grid-bordered>.fx-card{border:1px solid rgba(255,255,255,.08)}@keyframes fx-fade-up{from{opacity:0;transform:translateY(20px)}to{opacity:1;transform:none}}@keyframes fx-fade-in{from{opacity:0}to{opacity:1}}@keyframes fx-slide-left{from{opacity:0;transform:translateX(30px)}to{opacity:1;transform:none}}@keyframes fx-slide-right{from{opacity:0;transform:translateX(-30px)}to{opacity:1;transform:none}}@keyframes fx-zoom-in{from{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes fx-blur-in{from{opacity:0;filter:blur(8px)}to{opacity:1;filter:blur(0)}}.fx-anim-fade-up{animation:fx-fade-up .6s cubic-bezier(.4,0,.2,1) both}.fx-anim-fade-in{animation:fx-fade-in .6s ease both}.fx-anim-slide-left{animation:fx-slide-left .6s cubic-bezier(.4,0,.2,1) both}.fx-anim-slide-right{animation:fx-slide-right .6s cubic-bezier(.4,0,.2,1) both}.fx-anim-zoom-in{animation:fx-zoom-in .5s cubic-bezier(.4,0,.2,1) both}.fx-anim-blur-in{animation:fx-blur-in .7s ease both}.fx-anim-stagger>.fx-card:nth-child(1){animation:fx-fade-up .5s 0s both}.fx-anim-stagger>.fx-card:nth-child(2){animation:fx-fade-up .5s .1s both}.fx-anim-stagger>.fx-card:nth-child(3){animation:fx-fade-up .5s .2s both}.fx-anim-stagger>.fx-card:nth-child(4){animation:fx-fade-up .5s .3s both}.fx-anim-stagger>.fx-card:nth-child(5){animation:fx-fade-up .5s .4s both}.fx-anim-stagger>.fx-card:nth-child(6){animation:fx-fade-up .5s .5s both}`
1965
-
1966
- const T={
1967
- dark: `body{background:#030712;color:#f1f5f9}.fx-nav{border-bottom:1px solid #1e293b;background:rgba(3,7,18,.85)}.fx-nav-link{color:#cbd5e1}.fx-sub{color:#94a3b8}.fx-cta{background:#2563eb;color:#fff;box-shadow:0 8px 24px rgba(37,99,235,.35)}.fx-stat-lbl{color:#64748b}.fx-card{background:#0f172a;border:1px solid #1e293b}.fx-card:hover{box-shadow:0 20px 40px rgba(0,0,0,.5)}.fx-card-body{color:#64748b}.fx-sect-body{color:#64748b}.fx-form{background:#0f172a;border:1px solid #1e293b}.fx-label{color:#94a3b8}.fx-input{background:#020617;border:1px solid #1e293b;color:#f1f5f9}.fx-input::placeholder{color:#334155}.fx-btn{background:#2563eb;color:#fff;box-shadow:0 4px 14px rgba(37,99,235,.4)}.fx-th{color:#475569;border-bottom:1px solid #1e293b}.fx-tr:hover{background:#0f172a}.fx-td{border-bottom:1px solid rgba(255,255,255,.03)}.fx-footer{border-top:1px solid #1e293b}.fx-footer-text{color:#334155}.fx-pricing-card{background:#0f172a;border:1px solid #1e293b}.fx-faq-item{background:#0f172a}.fx-faq-item:hover{background:#111827}`,
1968
- light: `body{background:#fff;color:#0f172a}.fx-nav{border-bottom:1px solid #e2e8f0;background:rgba(255,255,255,.85)}.fx-nav-link{color:#475569}.fx-sub{color:#475569}.fx-cta{background:#2563eb;color:#fff}.fx-stat-lbl{color:#94a3b8}.fx-card{background:#f8fafc;border:1px solid #e2e8f0}.fx-card:hover{box-shadow:0 20px 40px rgba(0,0,0,.08)}.fx-card-body{color:#475569}.fx-sect-body{color:#475569}.fx-form{background:#f8fafc;border:1px solid #e2e8f0}.fx-label{color:#475569}.fx-input{background:#fff;border:1px solid #cbd5e1;color:#0f172a}.fx-btn{background:#2563eb;color:#fff}.fx-th{color:#94a3b8;border-bottom:1px solid #e2e8f0}.fx-tr:hover{background:#f8fafc}.fx-footer{border-top:1px solid #e2e8f0}.fx-footer-text{color:#94a3b8}.fx-pricing-card{background:#f8fafc;border:1px solid #e2e8f0}.fx-faq-item{background:#f8fafc}`,
1969
- acid: `body{background:#000;color:#a3e635}.fx-nav{border-bottom:1px solid #1a2e05;background:rgba(0,0,0,.9)}.fx-nav-link{color:#86efac}.fx-sub{color:#4d7c0f}.fx-cta{background:#a3e635;color:#000;font-weight:800}.fx-stat-lbl{color:#365314}.fx-card{background:#0a0f00;border:1px solid #1a2e05}.fx-card-body{color:#365314}.fx-sect-body{color:#365314}.fx-form{background:#0a0f00;border:1px solid #1a2e05}.fx-label{color:#4d7c0f}.fx-input{background:#000;border:1px solid #1a2e05;color:#a3e635}.fx-btn{background:#a3e635;color:#000;font-weight:800}.fx-th{color:#365314;border-bottom:1px solid #1a2e05}.fx-footer{border-top:1px solid #1a2e05}.fx-footer-text{color:#1a2e05}.fx-pricing-card{background:#0a0f00;border:1px solid #1a2e05}.fx-faq-item{background:#0a0f00}`,
1970
- }
1971
- return base+(T[theme]||T.dark)
2527
+ .fx-chart-container{padding:0 40px 48px}
2528
+ .fx-select-wrap{padding:6px 40px}
2529
+ .fx-select-block{width:auto;min-width:180px;height:36px;margin-top:0}
2530
+ .fx-each{padding:0 40px 24px}
2531
+ .fx-each-empty{padding:48px;text-align:center;color:var(--ds-gray-700);font-size:13px}
2532
+ .fx-if-wrap{display:contents}
2533
+ .fx-editor-wrap{padding:0 40px 24px}
2534
+
2535
+ /* ═══════════════════════════════════════════
2536
+ SCROLL ANIMATIONS — GPU only per Vercel guidelines
2537
+ ═══════════════════════════════════════════ */
2538
+ .fx-animate{
2539
+ opacity:0;transform:translateY(12px);
2540
+ transition:opacity .5s var(--ease-out),transform .5s var(--ease-out);
2541
+ }
2542
+ .fx-animate.fx-visible{opacity:1;transform:none}
2543
+ .fx-animate-stagger>*{
2544
+ opacity:0;transform:translateY(8px);
2545
+ transition:opacity .45s var(--ease-out),transform .45s var(--ease-out);
2546
+ }
2547
+ .fx-animate-stagger.fx-visible>*:nth-child(1){opacity:1;transform:none;transition-delay:.04s}
2548
+ .fx-animate-stagger.fx-visible>*:nth-child(2){opacity:1;transform:none;transition-delay:.1s}
2549
+ .fx-animate-stagger.fx-visible>*:nth-child(3){opacity:1;transform:none;transition-delay:.16s}
2550
+ .fx-animate-stagger.fx-visible>*:nth-child(4){opacity:1;transform:none;transition-delay:.22s}
2551
+ .fx-animate-stagger.fx-visible>*:nth-child(5){opacity:1;transform:none;transition-delay:.28s}
2552
+ .fx-animate-stagger.fx-visible>*:nth-child(6){opacity:1;transform:none;transition-delay:.34s}
2553
+
2554
+ /* Counter + year */
2555
+ .fx-count,.fx-year{font-variant-numeric:tabular-nums;display:inline-block}
2556
+
2557
+ /* ═══════════════════════════════════════════
2558
+ FOOTER — Geist footer style
2559
+ ═══════════════════════════════════════════ */
2560
+ .fx-footer{padding:32px 40px;border-top:1px solid var(--ds-gray-alpha-400)}
2561
+ .fx-footer-inner{
2562
+ max-width:1200px;margin:0 auto;
2563
+ display:flex;justify-content:space-between;align-items:center;
2564
+ flex-wrap:wrap;gap:16px;
2565
+ }
2566
+ .fx-footer-brand{font-size:13px;font-weight:600;letter-spacing:-.02em;color:var(--ds-gray-1000)}
2567
+ .fx-footer-links{display:flex;gap:24px;flex-wrap:wrap}
2568
+ .fx-footer-link{font-size:13px;color:var(--ds-gray-700);transition:color var(--duration-normal)}
2569
+ .fx-footer-link:hover{color:var(--ds-gray-1000)}
2570
+ .fx-footer-note{font-size:12px;color:var(--ds-gray-600);font-family:var(--geist-mono)}
2571
+ .fx-footer-text{font-size:13px;color:var(--ds-gray-700)}
2572
+ @media(max-width:640px){.fx-footer{padding:24px}.fx-footer-inner{flex-direction:column;align-items:flex-start;gap:12px}}
2573
+ `
2574
+
2575
+ // ════════════════════════════════════════════════════════════════
2576
+ // GEIST COLOR TOKENS — Semantic scale, light + dark
2577
+ // Based on vercel.com/geist/colors
2578
+ // Backgrounds → Surfaces → Borders → Text
2579
+ // ════════════════════════════════════════════════════════════════
2580
+ const T = {
2581
+ dark: `
2582
+ :root {
2583
+ /* Backgrounds */
2584
+ --ds-background-100:#000000;
2585
+ --ds-background-100-rgb:0,0,0;
2586
+ --ds-background-200:#0a0a0a;
2587
+
2588
+ /* Gray scale (Geist) */
2589
+ --ds-gray-100:#0a0a0a;
2590
+ --ds-gray-200:#111111;
2591
+ --ds-gray-300:#1a1a1a;
2592
+ --ds-gray-400:#222222;
2593
+ --ds-gray-500:#2a2a2a;
2594
+ --ds-gray-600:#666666;
2595
+ --ds-gray-700:#888888;
2596
+ --ds-gray-800:#999999;
2597
+ --ds-gray-900:#aaaaaa;
2598
+ --ds-gray-1000:#ededed;
2599
+
2600
+ /* Gray alpha */
2601
+ --ds-gray-alpha-100:rgba(255,255,255,.04);
2602
+ --ds-gray-alpha-200:rgba(255,255,255,.07);
2603
+ --ds-gray-alpha-400:rgba(255,255,255,.12);
2604
+ --ds-gray-alpha-700:rgba(255,255,255,.24);
2605
+
2606
+ /* Accent colors */
2607
+ --ds-blue-100:rgba(0,112,243,.08);
2608
+ --ds-blue-200:rgba(0,112,243,.15);
2609
+ --ds-blue-700:#0070f3;
2610
+ --ds-blue-rgb:0,112,243;
2611
+ --ds-red-100:rgba(255,0,0,.08);
2612
+ --ds-red-200:rgba(255,0,0,.15);
2613
+ --ds-red-700:#ff0000;
2614
+ --ds-green-100:rgba(0,188,112,.08);
2615
+ --ds-green-700:#00bc70;
2616
+ }`,
2617
+ light: `
2618
+ :root {
2619
+ --ds-background-100:#ffffff;
2620
+ --ds-background-100-rgb:255,255,255;
2621
+ --ds-background-200:#fafafa;
2622
+
2623
+ --ds-gray-100:#fafafa;
2624
+ --ds-gray-200:#f5f5f5;
2625
+ --ds-gray-300:#ebebeb;
2626
+ --ds-gray-400:#e6e6e6;
2627
+ --ds-gray-500:#e0e0e0;
2628
+ --ds-gray-600:#888888;
2629
+ --ds-gray-700:#666666;
2630
+ --ds-gray-800:#444444;
2631
+ --ds-gray-900:#333333;
2632
+ --ds-gray-1000:#111111;
2633
+
2634
+ --ds-gray-alpha-100:rgba(0,0,0,.04);
2635
+ --ds-gray-alpha-200:rgba(0,0,0,.07);
2636
+ --ds-gray-alpha-400:rgba(0,0,0,.12);
2637
+ --ds-gray-alpha-700:rgba(0,0,0,.24);
2638
+
2639
+ --ds-blue-100:rgba(0,112,243,.06);
2640
+ --ds-blue-200:rgba(0,112,243,.12);
2641
+ --ds-blue-700:#0070f3;
2642
+ --ds-blue-rgb:0,112,243;
2643
+ --ds-red-100:rgba(255,0,0,.06);
2644
+ --ds-red-200:rgba(255,0,0,.12);
2645
+ --ds-red-700:#c00;
2646
+ --ds-green-100:rgba(0,188,112,.06);
2647
+ --ds-green-700:#007a45;
2648
+ }`,
2649
+ }
2650
+ return base + (T[theme] || T.dark)
1972
2651
  }
2652
+
2653
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aiplang",
3
- "version": "2.11.7",
3
+ "version": "2.11.9",
4
4
  "description": "AI-first web language. One .aip file = complete app. Frontend + backend + database + auth.",
5
5
  "keywords": [
6
6
  "aiplang",
package/server/server.js CHANGED
@@ -2432,7 +2432,7 @@ async function startServer(aipFile, port = 3000) {
2432
2432
  })
2433
2433
 
2434
2434
  srv.addRoute('GET', '/health', (req, res) => res.json(200, {
2435
- status:'ok', version:'2.11.7',
2435
+ status:'ok', version:'2.11.9',
2436
2436
  models: app.models.map(m=>m.name),
2437
2437
  routes: app.apis.length, pages: app.pages.length,
2438
2438
  admin: app.admin?.prefix || null,