/* landing-pages.css - the homepage's landing components, for /pages/ documents.
 *
 * WHY THIS FILE EXISTS: the marketing homepage and the generated /pages/ tree
 * were built on two different design systems - `landing-*` (app.css) and `md-*`
 * (modules.css). They shared an accent colour and a similar font stack, which
 * made them look related in a diff and plainly different on screen.
 *
 * app.css cannot simply be linked from a document page: it opens with
 *   body { height: 100%; overflow: hidden; }
 * which is right for an application shell and fatal for a scrolling page. So the
 * landing COMPONENTS are extracted here and the shell is left behind.
 *
 * GENERATED by scripts/tests/extract-landing-css.js from app.css. Edit the
 * source rules in app.css, not this file, or the next extraction drops them.
 *
 * Pair with flux.css (tokens) and theme-bridge.css (aliases), and set
 * data-theme="light" on <html> - flux defaults to dark, and the landing is
 * always light.
 */

/* Document base. Replaces the app-shell body rule that was deliberately not
   carried over. */
body.landing-doc {
  margin: 0;
  min-height: 100%;
  overflow-x: hidden;
  overflow-y: auto;
  background: var(--surface-0);
  color: var(--text-primary);
  font-family: var(--ff-sans, 'Segoe UI', -apple-system, BlinkMacSystemFont, sans-serif);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}
/* NO blanket anchor rule here, deliberately.
   A `body.landing-doc a { color: ... }` rule carries specificity 0,0,1,2 and
   outranks every component that sets its own link colour - .landing-btn-primary
   (0,0,1,0) lost its label to it, and .landing-nav-link lost the homepage's
   grey and rendered teal, which is what made the nav look different from the
   homepage despite identical markup and identical nav CSS.
   Components own their colours; prose links are coloured where prose lives. */
.gap-split-copy p a, .gap-close a, .gap-boundary a, .gap-tool p a { color: var(--accent); }

.landing-wrap { display: flex; flex-direction: column; min-height: 100%; }
.landing-accent { color: var(--accent); }
/* --- Nav --- */
.landing-nav {
  position: sticky; top: 0; z-index: 100;
  background: color-mix(in oklch, var(--surface-0) 90%, transparent); backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
}
.landing-nav-inner {
  max-width: 1200px; margin: 0 auto; padding: 0 2rem;
  height: 60px; display: flex; align-items: center; gap: 2rem;
}
.landing-logo {
  display: flex; align-items: center; gap: 10px;
  font-size: 20px; font-weight: 300; color: var(--text-primary); white-space: nowrap;
}
.landing-logo i { color: var(--accent); font-size: 22px; }
.landing-logo span { font-size: 20px; }
.landing-nav-links { display: flex; gap: 0.25rem; flex: 1; }
.landing-nav-link {
  padding: 6px 14px; color: var(--text-secondary); font-size: 13px;
  border-radius: 4px; transition: all 0.2s; text-decoration: none;
}
.landing-nav-link:hover { color: var(--text-primary); background: color-mix(in oklch, var(--accent) 12%, transparent); text-decoration: none; }
.landing-nav-actions { display: flex; gap: 0.5rem; }
/* --- Buttons --- */
.landing-btn-primary {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 20px; background: var(--accent); color: var(--accent-text, #fff);
  border: none; border-radius: 5px; font-size: 13px; font-weight: 600;
  cursor: pointer; transition: all 0.2s; white-space: nowrap;
}
.landing-btn-primary i, .landing-btn-primary svg { color: inherit; }
.landing-btn-primary:hover { background: var(--accent-hover); }
.landing-btn-outline {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 18px; background: transparent; color: var(--text-bright);
  border: 1px solid var(--border-light); border-radius: 5px; font-size: 13px;
  cursor: pointer; transition: all 0.2s; white-space: nowrap;
}
.landing-btn-outline:hover { background: var(--bg-hover); border-color: var(--accent); color: var(--accent); }
.landing-btn-ghost {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 20px; background: transparent; color: var(--text-bright);
  border: 1px solid var(--border); border-radius: 5px; font-size: 13px;
  cursor: pointer; transition: all 0.2s; text-decoration: none; white-space: nowrap;
}
.landing-btn-ghost:hover { background: color-mix(in oklch, var(--text-primary) 7%, transparent); text-decoration: none; color: var(--text-primary); }
.landing-btn-lg { padding: 12px 28px; font-size: 15px; border-radius: 6px; }
.landing-btn-full { width: 100%; justify-content: center; padding: 12px; font-size: 15px; border-radius: 6px; }
/* --- Hero --- */
.landing-hero {
  background: radial-gradient(ellipse at 60% 40%, rgba(79,195,247,0.07) 0%, transparent 60%),
              radial-gradient(ellipse at 20% 80%, rgba(129,196,132,0.05) 0%, transparent 50%),
              var(--bg);
  padding: 100px 2rem 80px;
  border-bottom: 1px solid var(--border);
}
.landing-hero-inner { max-width: 1200px; margin: 0 auto; text-align: center; }
.landing-badge-pill {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 5px 14px; background: color-mix(in oklch, var(--accent) 12%, transparent);
  border: 1px solid color-mix(in oklch, var(--accent) 32%, transparent); border-radius: 20px;
  font-size: 12px; color: var(--accent); margin-bottom: 1.5rem;
}
.landing-h1 {
  font-size: 44px; /* fallback for browsers without clamp() (older Android) */
  font-size: clamp(32px, 5vw, 58px); font-weight: 300;
  color: var(--text-bright); line-height: 1.2; margin-bottom: 1.25rem;
}
.landing-hero-sub {
  max-width: 640px; margin: 0 auto 2.5rem;
  font-size: 16px; color: var(--text-dim); line-height: 1.7;
}
.landing-hero-ctas { display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap; margin-bottom: 4rem; }
.landing-hero-stats {
  display: flex; justify-content: center; gap: 3rem; flex-wrap: wrap;
  padding-top: 2.5rem; border-top: 1px solid var(--border);
}
.landing-stat { text-align: center; }
.landing-stat span { display: block; font-size: 36px; font-weight: 300; color: #4fc3f7; line-height: 1; margin-bottom: 0.5rem; }
.landing-stat small { font-size: 12px; color: var(--text-dim); line-height: 1.5; }
/* --- Sections --- */
.landing-section { padding: 80px 2rem; }
.landing-section-alt { background: var(--bg-alt); }
.landing-section-inner { max-width: 1200px; margin: 0 auto; }
.landing-section-label {
  font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 2px; color: #4fc3f7; margin-bottom: 1rem;
}
.landing-h2 { font-size: 30px; font-size: clamp(24px, 3vw, 36px); font-weight: 300; color: var(--text-bright); margin-bottom: 1rem; }
.landing-section-sub { font-size: 15px; color: var(--text-dim); line-height: 1.7; max-width: 680px; margin-bottom: 3rem; }
/* --- Features grid --- */
.landing-features-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1.5rem; }
.landing-feature-card {
  background: var(--bg-panel); border: 1px solid var(--border);
  border-radius: 8px; padding: 1.75rem; transition: border-color 0.2s;
}
.landing-feature-card:hover { border-color: var(--border-light); }
.landing-feature-icon { font-size: 28px; margin-bottom: 1rem; }
.landing-feature-card h3 { font-size: 15px; font-weight: 600; color: var(--text-bright); margin-bottom: 0.75rem; }
.landing-feature-card p { font-size: 13px; color: var(--text-dim); line-height: 1.6; margin: 0; }
/* --- Domains grid --- */
.landing-domains-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; }
.landing-domain-card {
  background: var(--bg-panel); border: 1px solid var(--border);
  border-radius: 8px; padding: 1.5rem 1.25rem;
  display: flex; flex-direction: column; gap: 0.5rem;
  transition: all 0.2s; cursor: default;
}
.landing-domain-card:hover { border-color: var(--border-light); background: var(--bg-hover); }
.landing-domain-card i { font-size: 24px; }
.landing-domain-card span { font-size: 14px; font-weight: 600; color: var(--text-bright); }
.landing-domain-card small { font-size: 11px; color: var(--text-dim); line-height: 1.4; }
/* --- Tiers grid --- */
.landing-tiers-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1.25rem; align-items: stretch; }
.landing-tier-card {
  background: var(--bg-panel); border: 1px solid var(--border);
  border-radius: 8px; padding: 1.75rem; display: flex; flex-direction: column; gap: 0.75rem;
}
.landing-tier-card-highlight {
  border-color: rgba(245,158,11,0.4);
  box-shadow: 0 0 0 1px rgba(245,158,11,0.15);
}
.landing-tier-label {
  display: inline-block; padding: 4px 10px; border-radius: 12px;
  font-size: 11px; font-weight: 700; letter-spacing: 1px; align-self: flex-start;
}
.landing-tier-price { font-size: 32px; font-weight: 300; color: var(--text-bright); }
.landing-tier-price small { font-size: 14px; color: var(--text-dim); }
.landing-tier-desc { font-size: 13px; color: var(--text-dim); line-height: 1.6; }
.landing-tier-features { list-style: none; display: flex; flex-direction: column; gap: 8px; font-size: 13px; color: var(--text); flex: 1; }
.landing-tier-features li { display: flex; align-items: center; gap: 8px; }
.landing-tier-features li i { width: 14px; font-size: 12px; }
.landing-tier-features li i.fa-check { color: #4ec964; }
.landing-tier-features li i.fa-times { color: #555; }
.landing-tier-features li.muted { color: var(--text-dim); }
.landing-tier-btn {
  margin-top: auto; padding: 10px 16px; width: 100%;
  background: var(--bg-input); border: 1px solid var(--border);
  border-radius: 5px; color: var(--text); font-size: 13px; font-weight: 500;
  cursor: pointer; transition: all 0.2s;
}
.landing-tier-btn:hover { background: var(--bg-hover); border-color: var(--border-light); color: var(--text-bright); }
.landing-tier-btn-accent {
  background: rgba(245,158,11,0.15); border-color: rgba(245,158,11,0.4); color: #f59e0b;
}
.landing-tier-btn-accent:hover { background: rgba(245,158,11,0.25); }
/* --- Feedback section --- */
.landing-feedback-wrap { display: grid; grid-template-columns: 1fr 1fr; gap: 4rem; align-items: start; }
@media (max-width: 768px) { .landing-feedback-wrap { grid-template-columns: 1fr; } }
.landing-contact-list { display: flex; flex-direction: column; gap: 1.25rem; margin-top: 2rem; }
.landing-contact-item {
  display: flex; align-items: flex-start; gap: 1rem;
  padding: 1rem 1.25rem; background: var(--bg-panel);
  border: 1px solid var(--border); border-radius: 6px;
}
.landing-contact-item i { color: #4fc3f7; font-size: 16px; margin-top: 2px; }
.landing-contact-item strong { display: block; color: var(--text-bright); font-size: 13px; margin-bottom: 3px; }
.landing-contact-item a { font-size: 12px; color: var(--text-dim); }
.landing-contact-item a:hover { color: #4fc3f7; }
.landing-form { display: flex; flex-direction: column; gap: 1rem; }
.landing-form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
@media (max-width: 540px) { .landing-form-row { grid-template-columns: 1fr; } }
.landing-field { display: flex; flex-direction: column; gap: 5px; }
.landing-field label { font-size: 12px; color: var(--text-dim); font-weight: 500; }
.landing-field input,
.landing-field select,
.landing-field textarea {
  background: var(--bg-input); border: 1px solid var(--border);
  border-radius: 5px; padding: 9px 12px; color: var(--text); font-size: 13px;
}
.landing-field input:focus,
.landing-field select:focus,
.landing-field textarea:focus { border-color: #4fc3f7; outline: none; }
.landing-field textarea { resize: vertical; min-height: 100px; }
/* --- Demo / GIF section --- */
.landing-demo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 1.5rem;
  margin-top: 0.5rem;
}
.landing-demo-card {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  transition: border-color 0.2s, transform 0.2s;
}
.landing-demo-card:hover { border-color: rgba(79,195,247,0.4); transform: translateY(-2px); }
.landing-demo-card img {
  width: 100%; display: block;
  border-bottom: 1px solid var(--border);
  background: #111;
}
.landing-demo-card-body { padding: 1rem 1.25rem; }
.landing-demo-card-body h4 { font-size: 14px; font-weight: 600; color: var(--text-bright); margin-bottom: 4px; }
.landing-demo-card-body p { font-size: 12px; color: var(--text-dim); line-height: 1.5; margin: 0; }
/* --- Footer --- */
.landing-footer {
  margin-top: auto; padding: 2rem;
  border-top: 1px solid var(--border); background: var(--bg-alt);
}
.landing-footer-inner {
  max-width: 1200px; margin: 0 auto;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
}
.landing-footer-copy { font-size: 12px; color: var(--text-dim); }
.landing-footer-copy a { color: var(--text-dim); }
.landing-footer-copy a:hover { color: #4fc3f7; }
.landing-footer-citation { font-size: 11px; color: var(--text-dim); margin-top: 6px; opacity: 0.7; }
.landing-footer-citation a { color: #81c784; text-decoration: none; }
.landing-footer-citation a:hover { color: #a5d6a7; text-decoration: underline; }
.landing-footer-toggle { display: none; }
/* desktop: footer shows fully; the toggle is mobile-only */

/* FAQ Accordion */
.landing-faq-section { background: var(--bg-surface); }
/* ── GDBS Free section ── */
.landing-free-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin: 32px 0 28px;
}
@media (max-width: 760px) { .landing-free-grid { grid-template-columns: 1fr; } }
.landing-free-card {
  background: var(--bg-card); border: 1px solid var(--border); border-radius: 10px; padding: 20px;
}
.landing-free-card-header {
  display: flex; align-items: center; gap: 10px; font-size: 13px; font-weight: 600;
  color: var(--text-bright); margin-bottom: 10px;
}
.landing-free-card-header i { font-size: 18px; }
.landing-free-card p { font-size: 13px; color: var(--text-muted); line-height: 1.65; margin: 0; }
.landing-free-actions {
  display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 32px; align-items: center;
}
.landing-free-snippet {
  background: #0d1117; border: 1px solid rgba(255,255,255,0.1); border-radius: 8px;
  overflow: hidden; max-width: 680px;
}
.landing-free-snippet-label {
  padding: 8px 16px; font-size: 11px; color: #8b949e;
  background: rgba(255,255,255,0.04); border-bottom: 1px solid rgba(255,255,255,0.07);
  font-family: var(--mono);
}
`,
   which is near-white in the flux light theme and rendered the code white-on-white. */
.landing-free-snippet pre { margin: 0; padding: 16px; overflow-x: auto; background: transparent; border: 0; border-radius: 0; }
.landing-free-snippet code { font-family: var(--mono); font-size: 13px; color: #e6edf3; background: transparent; line-height: 1.6; }
.landing-free-note { font-size: 12px; color: var(--text-dim); margin-top: 20px; }
/* ── Try Live nav button ── */
.landing-btn-ghost-sm {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 6px 14px; background: rgba(79,195,247,0.08); color: #4fc3f7;
  border: 1px solid rgba(79,195,247,0.3); border-radius: 5px; font-size: 12px;
  cursor: pointer; transition: all 0.2s; white-space: nowrap;
}
.landing-btn-ghost-sm:hover { background: rgba(79,195,247,0.15); border-color: #4fc3f7; }
@media (max-width: 768px) {
  /* Hide connected status, Report and Print on mobile */
  .topbar-center { display: none; }
  .topbar-left { min-width: 0; }
  .topbar-right { min-width: 0; gap: 6px; }
  #btn-global-report, #btn-print-view { display: none; }

  /* ── De-cram the topbar ────────────────────────────────────────────────
     Everything (brand, product tabs, admin Share, 3D, tier badge, user chip)
     sat in one 36px row and overlapped into an unreadable blend. Product tabs
     go ICON-ONLY (the brand already names the product; the active tab keeps its
     highlight) and the nav SCROLLS instead of overflowing; the user chip drops
     its "User:" prefix and truncates the long email so nothing blends. */
  .topbar { padding: 0 8px; gap: 4px; }
  .topbar-left { flex-shrink: 0; }
  .topbar-left .brand { font-size: 13px; }
  .product-tabs { margin-left: 4px; min-width: 0; flex-shrink: 1; overflow-x: auto; scrollbar-width: none; gap: 1px; }
  .product-tabs::-webkit-scrollbar { display: none; }
  .product-tab { padding: 0 9px; }
  .product-tab span { display: none; }                 /* icon-only tabs */
  .topbar-right { flex-shrink: 0; gap: 4px; }
  .topbar-right .user-prefix { display: none; }        /* drop the "User:" label */
  #user-display { display: inline-block; max-width: 88px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: middle; }
  #btn-view-3d { margin-right: 2px !important; }

  /* ── Collapsible landing footer ────────────────────────────────────────
     The subscribe form + legal link list made a tall footer on phones. Collapse
     them behind a toggle so the footer is a compact strip (logo + button); tap
     to expand. */
  .landing-footer-toggle {
    display: inline-flex; align-items: center; gap: 8px; margin: 8px auto 0;
    background: none; border: 1px solid var(--border); color: var(--text-dim);
    border-radius: 6px; padding: 8px 14px; font-size: 13px; font-family: inherit; cursor: pointer;
  }
  .landing-footer-toggle i { transition: transform 0.15s; }
  .landing-footer.footer-open .landing-footer-toggle i { transform: rotate(180deg); }
  .landing-footer-collapse { display: none; }
  .landing-footer.footer-open .landing-footer-collapse { display: block; }

  /* Charts fill the width on mobile; the vchart legend is moved below the plot (see vchart.js). */
  .chart-wrap, .chart-wrap canvas { width: 100% !important; }

  /* ── Fly-up module navigation ──────────────────────────────────────────
     The 52px bottom bar crammed all ~20 modules across every tier into one
     scroll with no way to jump between Standard / Pro / HPC Lab. Replace it
     with a bottom-sheet: a single "Modules" button flies up a sheet with the
     STD / PRO / HPC tabs on top and the active tier's modules as big rows. */
  .main-layout { flex-direction: column; }

  #mobile-nav-toggle {
    display: flex; align-items: center; justify-content: center; gap: 8px;
    position: fixed; bottom: 0; left: 0; width: 100%; height: 52px; z-index: 60;
    background: var(--bg-alt); border: none; border-top: 1px solid var(--border);
    color: var(--accent); font-size: 14px; font-weight: 600; font-family: inherit; cursor: pointer;
  }
  #mobile-nav-toggle i { font-size: 16px; }

  #mobile-nav-backdrop { display: none; position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 70; background: rgba(0,0,0,0.5); }
  #mobile-nav-backdrop.show { display: block; }

  /* the sidebar becomes the fly-up sheet */
  .sidebar {
    position: fixed; left: 0; bottom: 0; width: 100%; height: auto; max-height: 78vh;
    flex-direction: column; overflow-y: auto; z-index: 80;
    background: var(--bg-alt); border: none; border-top: 1px solid var(--border);
    border-radius: 14px 14px 0 0; box-shadow: 0 -8px 30px rgba(0,0,0,0.5);
    transform: translateY(100%); transition: transform 0.28s ease; padding-bottom: 12px;
  }
  .sidebar.flyup-open { transform: translateY(0); }
  .sidebar-nav { flex-direction: column; flex: none; overflow: visible; }

  /* STD / PRO / HPC tabs as the sticky sheet header */
  .tier-dots {
    display: flex; flex-direction: row; justify-content: center; gap: 8px;
    position: sticky; top: 0; z-index: 2; background: var(--bg-alt);
    padding: 14px 12px 10px; border-bottom: 1px solid var(--border);
  }
  .tier-dot { flex: 1; max-width: 110px; text-align: center; padding: 11px 8px; font-size: 13px; font-weight: 700; border-radius: 8px; }

  /* module rows */
  .nav-item {
    flex-direction: row; align-items: center; justify-content: flex-start; gap: 14px;
    width: 100%; padding: 14px 22px; font-size: 15px; text-align: left;
    border-left: 3px solid transparent; border-top: none;
  }
  .nav-item i { font-size: 18px; width: 24px; text-align: center; }
  .nav-item.active { border-left-color: var(--accent); border-top-color: transparent; background: var(--bg); }
  .nav-item-bottom { margin-top: 0; border-top: none; border-left: 3px solid transparent; }
  .nav-tier-section { display: none; }
  .nav-tier-section.active { display: flex; flex-direction: column; }

  /* ── Module sub-tab bars: icon-only on small screens ───────────────────
     The flat tab rows (Molecular / Cosmos / Materials / Geophysics / Fluids /
     Quantum / Anomaly / Theory) ran off the right edge in portrait. Collapse
     each tab to its icon (the label is a bare text node, so font-size:0 on the
     button hides it while the icon keeps its own size) and let the row wrap, so
     every tab is visible without left-right scroll. The full label is set as a
     title (hover / long-press) by app.js setTabTitles(). */
  .molecular-tabs, .cosmic-tabs, .materials-tabs, .geo-tabs,
  .fluids-tabs, .quantum-tabs, .tukey-tabs, .theory-tabs {
    flex-wrap: wrap; overflow-x: visible; justify-content: center;
    gap: 2px; padding: 6px 4px;
  }
  .mtab, .ctab, .mattab, .geotab, .fltab, .qtab, .tukeytab, .theory-tab {
    font-size: 0 !important; padding: 9px 12px; gap: 0; white-space: nowrap;
  }
  .mtab > i, .ctab > i, .mattab > i, .geotab > i,
  .fltab > i, .qtab > i, .tukeytab > i, .theory-tab > i {
    font-size: 17px !important; margin: 0; width: auto;
  }
  /* The ACTIVE sub-tab keeps its label so you always know which tool is running
     (icon-only tabs otherwise hide the selection on mobile - you can't tell what
     you're looking at). The active pill shows "<icon> Name"; the rest stay icons. */
  .mtab.active, .ctab.active, .mattab.active, .geotab.active,
  .fltab.active, .qtab.active, .tukeytab.active, .theory-tab.active {
    font-size: 12px !important; gap: 6px; padding: 9px 14px; font-weight: 600;
  }
  .mtab.active > i, .ctab.active > i, .mattab.active > i, .geotab.active > i,
  .fltab.active > i, .qtab.active > i, .tukeytab.active > i, .theory-tab.active > i {
    font-size: 13px !important;
  }

  /* pad content above the fixed toggle bar */
  .content-area, .plasma-panel, .module-panel,
  .pane-content, .detail-pane, .query-pane, .content, .view { padding-bottom: 60px; }

  /* Charts — ensure min size on small screens */
  .chart-wrap { min-height: 200px; height: 220px; }
  canvas { min-height: 160px; min-width: 0; }
  .md-chart-cell { min-height: 180px; }
  .theory-subpanel canvas { min-height: 160px; }

  /* Landing nav hamburger */
  .landing-hamburger {
    display: flex; align-items: center; justify-content: center;
    background: none; border: 1px solid var(--border); color: var(--text-dim);
    border-radius: 4px; padding: 6px 10px; cursor: pointer; font-size: 16px;
    margin-left: 8px;
  }
  .landing-nav-links { display: none; }
  /* Keep the primary "Get Started" (signup) visible in the mobile top bar;
     Try Live / Sign In live in the hamburger menu. */
  .landing-nav-actions { display: flex; align-items: center; gap: 8px; margin-left: auto; }
  .landing-nav-actions .landing-btn-outline { display: none; }
  .landing-nav-actions .landing-btn-primary { display: inline-flex; align-items: center; }
  .landing-mobile-menu {
    display: none; flex-direction: column;
    background: var(--bg-panel); border-top: 1px solid var(--border);
    padding: 8px 16px 12px;
  }
  .landing-mobile-menu.open { display: flex; }
  .landing-mobile-menu .landing-nav-link { padding: 10px 4px; font-size: 14px; border-bottom: 1px solid var(--border-faint, rgba(255,255,255,0.05)); }
  .landing-mobile-actions { display: flex; gap: 8px; flex-wrap: wrap; padding-top: 12px; }
}
@media (min-width: 769px) {
  .landing-hamburger { display: none; }
  .landing-mobile-menu { display: none !important; }
}


/* The dropdown primitives. These were authored in an inline <style> inside
   index.html rather than in app.css, so extracting the .landing-* rules never
   picked them up - and a page without `.ln-menu{display:none}` renders every
   dropdown's contents as loose inline text beside the logo, which is exactly
   what the industry menu did on the gap pages.

   Copied verbatim from that inline block. They belong in a stylesheet, not in
   one page's <head>. */
.ln-item{position:relative;display:inline-flex;align-items:center}
.ln-trigger{cursor:pointer}
.ln-caret{font-size:9px;margin-left:5px;opacity:0.55}
.ln-menu{position:absolute;top:100%;left:0;min-width:196px;background:var(--bg-panel,#ffffff);border:1px solid var(--border,#e2e8f0);border-radius:10px;box-shadow:0 14px 34px rgba(15,23,42,0.14);padding:8px;display:none;flex-direction:column;gap:2px;z-index:1300}
.ln-item:hover > .ln-menu,.ln-item.open > .ln-menu{display:flex}
.ln-menu a{display:block;padding:8px 12px;border-radius:7px;font-size:13.5px;color:var(--text-primary,#334155);text-decoration:none;white-space:nowrap;transition:background .12s,color .12s}
.ln-menu a:hover{background:var(--bg-alt,#f1f5f9);color:var(--accent,#0078d4)}
.ln-mgroup{font-size:10px;text-transform:uppercase;letter-spacing:0.08em;color:var(--text-dim,#94a3b8);font-weight:700;margin:12px 0 2px;padding:0 2px}

/* The mobile menu is hidden until the hamburger opens it. Without this the
   whole mobile list renders inline under the desktop nav. */
.landing-mobile-menu{display:none;flex-direction:column;padding:12px 2rem 18px;border-top:1px solid var(--border,#e2e8f0);background:var(--surface-0,#fff)}
.landing-mobile-menu.open{display:flex}
@media (min-width: 861px){ .landing-mobile-menu{display:none !important} .landing-hamburger{display:none} }
@media (max-width: 860px){ .landing-nav-links{display:none} }

/* Solutions by Industry dropdown. Eleven entries is too many for the single
   narrow column the other menus use, so this one is wider and two-up on desktop.
   It links STRAIGHT to each industry page: a domain expert wants their own
   field, not a hub they then have to navigate down through. */
.ln-menu-wide {
  min-width: 460px;
  columns: 2;
  column-gap: 1.25rem;
}
.ln-menu-wide a { break-inside: avoid; }
.ln-menu-wide .ln-all {
  column-span: all;
  margin-top: 0.4rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--border);
  font-weight: 600;
  color: var(--accent);
}
@media (max-width: 720px) {
  .ln-menu-wide { min-width: 0; columns: 1; }
}


/* ═══ PER-DOMAIN IDENTITY ═══════════════════════════════════════════════════
   Each industry page needs to feel like its own place while staying obviously
   the same product. flux already computes every accent shade from a single
   --accent-hue, so a domain gets its identity by setting that ONE number: the
   hue cascades through headings, stats, links, borders and the hero wash with
   no per-domain colour ever hardcoded.

   It is scoped to .gap-page rather than :root on purpose. The nav and buttons
   keep the SITE accent - and the visitor's saved accent hue keeps working - so
   the chrome stays constant and only the content carries the domain colour.
   Overriding :root would have thrown away the user preference the whole theme
   bootstrap exists to honour. */

.gap-page { --accent-hue: var(--domain-hue, 195); }

/* Hero wash. No image assets: two radial tints in the domain hue over a fine
   grid, which reads as designed at any width, costs no request, and recolours
   itself when the hue changes. */
.gap-hero {
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(ellipse 70% 60% at 12% 0%,
      oklch(96% 0.05 var(--accent-hue) / 0.9), transparent 60%),
    radial-gradient(ellipse 50% 50% at 88% 20%,
      oklch(94% 0.07 var(--accent-hue) / 0.55), transparent 65%),
    var(--surface-0);
}
.gap-hero::before {
  content: '';
  position: absolute; inset: 0;
  background-image:
    linear-gradient(to right, oklch(60% 0.02 var(--accent-hue) / 0.07) 1px, transparent 1px),
    linear-gradient(to bottom, oklch(60% 0.02 var(--accent-hue) / 0.07) 1px, transparent 1px);
  background-size: 46px 46px;
  mask-image: radial-gradient(ellipse 80% 70% at 30% 0%, #000, transparent 75%);
  pointer-events: none;
}
.gap-hero > * { position: relative; }

/* The domain mark. Large, tinted, sitting with the label rather than floating. */
.gap-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px; height: 46px;
  margin-bottom: 1rem;
  border-radius: 12px;
  font-size: 20px;
  color: var(--accent);
  background: oklch(94% 0.06 var(--accent-hue) / 0.8);
  border: 1px solid oklch(85% 0.06 var(--accent-hue) / 0.7);
}

/* Sections were 80px top and bottom with little in them, which read as empty
   rather than airy. Tightened, and the alternating band gets the domain tint
   instead of flat grey so the page has rhythm. */
.gap-page .landing-section { padding: 56px 2rem; }
.gap-page .landing-section-alt {
  background: oklch(97% 0.014 var(--accent-hue));
  border-top: 1px solid oklch(90% 0.02 var(--accent-hue) / 0.6);
  border-bottom: 1px solid oklch(90% 0.02 var(--accent-hue) / 0.6);
}

/* Each tool card carries the domain mark, so a card is identifiable at a glance
   instead of being an undifferentiated block of text. */
.gap-tool { position: relative; padding-left: 3.25rem; }
.gap-tool::before {
  content: '\f0c3';
  font-family: 'Font Awesome 6 Free';
  font-weight: 900;
  position: absolute;
  left: 1.4rem; top: 1.85rem;
  font-size: 15px;
  color: var(--accent);
  opacity: 0.75;
}
.gap-tool[data-icon]::before { content: attr(data-icon); }

/* The statistic block gets a left rule in the domain hue - the figures are the
   reason the page exists, so they should read as a unit. */
.gap-stat {
  padding-left: 0.9rem;
  border-left: 2px solid oklch(80% 0.09 var(--accent-hue) / 0.55);
}

.gap-cta { text-align: left; }
.gap-btns { margin-top: 1.5rem; }


/* ═══ SPLIT HERO ════════════════════════════════════════════════════════════
   The pages read as empty because everything sat in a single left-aligned
   column with the right half unused. Technical B2B pages give text and a visual
   equal weight; here the visual is the page's lead FIGURE, which is more use to
   a reader than an illustration would be and needs no image asset. */

.gap-split {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.85fr);
  gap: 3.5rem;
  align-items: center;
}
.gap-split-copy .landing-section-sub { margin-bottom: 1.75rem; max-width: 34rem; }

.gap-proof {
  padding: 2rem 1.9rem;
  border-radius: 14px;
  background: var(--surface-0);
  border: 1px solid oklch(88% 0.04 var(--accent-hue) / 0.8);
  box-shadow: 0 18px 40px oklch(60% 0.05 var(--accent-hue) / 0.10);
}
.gap-proof-label {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--accent); margin-bottom: 0.9rem;
}
/* Tabular figures so a percentage and a currency amount sit on the same
   baseline grid rather than drifting against each other. */
.gap-proof-n {
  font-size: clamp(38px, 5vw, 56px); font-weight: 300; line-height: 1;
  color: var(--text-bright); font-variant-numeric: tabular-nums;
  letter-spacing: -0.03em; margin-bottom: 0.7rem;
}
.gap-proof-t { margin: 0 0 0.6rem; font-size: 14.5px; line-height: 1.6; color: var(--text-dim); }
.gap-proof-src {
  font-size: 12px; color: var(--text-muted, var(--text-dim));
  border-bottom: 1px dotted currentColor; text-decoration: none;
}
.gap-proof-src:hover { color: var(--accent); }
.gap-proof-rule { height: 1px; background: var(--border); margin: 1.4rem 0 1rem; }
.gap-proof-meta {
  display: flex; align-items: center; gap: 8px;
  font-size: 12.5px; color: var(--text-dim);
}
.gap-proof-meta i { color: var(--accent); }

/* The closing call to action, contained rather than floating in a full-width
   band with nothing beside it. */
.gap-cta {
  padding: 2.5rem 2.25rem;
  border-radius: 14px;
  background: oklch(97% 0.02 var(--accent-hue));
  border: 1px solid oklch(90% 0.03 var(--accent-hue) / 0.8);
}
.gap-cta .landing-h2 { margin-bottom: 0.6rem; }
.gap-cta .landing-section-sub { margin-bottom: 0; max-width: 46rem; }

@media (max-width: 900px) {
  .gap-split { grid-template-columns: 1fr; gap: 2.25rem; }
  .gap-proof { order: 2; }
}


/* ═══ GEOMETRY ══════════════════════════════════════════════════════════════
   The first pass was all right angles and hard section edges, which read as a
   document rather than a product. Rounder surfaces and softer section joins,
   applied consistently so the pages still feel like one system. */

.gap-page .gap-proof,
.gap-page .gap-cta { border-radius: 18px; }
.gap-page .gap-tool { border-radius: 14px; }
.gap-mark { border-radius: 14px; }

/* Curve the tinted band instead of butting it flat against its neighbours. The
   inset + radius reads as a panel; a full-bleed rectangle reads as a rule. */
.gap-page .landing-section-alt {
  border: 1px solid oklch(90% 0.025 var(--accent-hue) / 0.7);
  border-radius: 24px;
  margin: 0 1.5rem;
  padding: 52px 2rem;
}

/* Give the hero a soft base curve so the transition into the next section is a
   shape rather than a line. */
.gap-hero {
  border-bottom-left-radius: 28px;
  border-bottom-right-radius: 28px;
}

/* Tool cards lift slightly on hover - enough to read as interactive, not enough
   to bounce. */
.gap-tool {
  transition: transform 0.16s ease, box-shadow 0.16s ease, border-color 0.16s ease;
}
.gap-tool:hover {
  transform: translateY(-2px);
  border-color: oklch(80% 0.07 var(--accent-hue) / 0.8);
  box-shadow: 0 12px 28px oklch(60% 0.05 var(--accent-hue) / 0.13);
}

@media (max-width: 700px) {
  .gap-page .landing-section-alt { margin: 0 0.75rem; border-radius: 18px; }
}


/* ═══ LIVE HERO DEMO ════════════════════════════════════════════════════════
   The real tool, running, in the hero. Framed as an instrument panel rather
   than a marketing card: a status dot, the tool's name, the live mount, and the
   privacy line. Nothing here claims anything the page cannot immediately
   demonstrate. */

.gap-live {
  padding: 1.5rem 1.5rem 1.25rem;
  border-radius: 18px;
  background: var(--surface-0);
  border: 1px solid oklch(86% 0.05 var(--accent-hue) / 0.85);
  box-shadow: 0 20px 46px oklch(60% 0.05 var(--accent-hue) / 0.14);
}
.gap-live-head {
  display: flex; align-items: center; gap: 8px;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.11em;
  text-transform: uppercase; color: var(--accent); margin-bottom: 0.6rem;
}
/* A quiet pulse. It signals live without demanding attention, and it stops
   entirely for anyone who has asked for reduced motion. */
.gap-live-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 3px oklch(85% 0.09 var(--accent-hue) / 0.4);
  animation: gapPulse 2.4s ease-in-out infinite;
}
@keyframes gapPulse { 0%,100%{opacity:1} 50%{opacity:0.45} }
@media (prefers-reduced-motion: reduce) { .gap-live-dot { animation: none } }

.gap-live-name {
  font-size: 17px; font-weight: 600; color: var(--text-bright);
  margin-bottom: 0.9rem;
}
/* The mount is capped and scrolls internally: a plugin with a long form must
   not stretch the hero into a page of its own. */
.gap-live-mount {
  max-height: 430px; overflow: auto;
  border-radius: 12px;
  background: oklch(98% 0.008 var(--accent-hue));
  border: 1px solid var(--border);
  padding: 0.75rem;
}
.gap-live-foot {
  display: flex; align-items: center; gap: 8px;
  margin-top: 0.9rem; padding-top: 0.85rem;
  border-top: 1px solid var(--border);
  font-size: 12.5px; color: var(--text-dim);
}
.gap-live-foot i { color: var(--accent); }

@media (max-width: 900px) { .gap-live { order: 2; } }


/* ═══ SIGNATURE FIGURE ══════════════════════════════════════════════════════
   Each industry page carries a line figure drawn from its own subject - a decay
   curve for pharmacokinetics, a truss for structures, an orbit for aerospace.
   Generated inline, so there is no asset to ship, nothing to request, and it
   takes the domain hue automatically.

   It sits behind the copy at low opacity and is pinned to the right of the
   headline column, where the page previously had nothing. On narrow screens it
   is removed rather than shrunk: behind body text at phone width it would be
   noise, not texture. */

.gap-art {
  position: absolute;
  top: 50%;
  left: 46%;
  width: 300px;
  height: auto;
  transform: translateY(-50%);
  color: var(--accent);
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  opacity: 0.13;
  pointer-events: none;
}
@media (max-width: 1100px) { .gap-art { display: none; } }


/* ═══ LOW-POLY HERO BACKDROP ════════════════════════════════════════════════
   Sits behind everything in the hero at half strength, masked so it fades out
   across the left where the headline and body copy sit. At full opacity it
   competes with the text; at half, with the mask, it reads as material. */

.gap-hero { position: relative; }

.gap-mesh {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0.5;
  pointer-events: none;
  /* Copy space: transparent behind the headline at the left edge, ramping to
     full across the middle. The ramp reaches full BEFORE the demo panel starts,
     so the strongest faceting lands in the open band between the copy and the
     panel - the one part of the hero that was empty. */
  -webkit-mask-image: linear-gradient(100deg, transparent 3%, rgba(0,0,0,0.4) 26%, #000 52%);
  mask-image: linear-gradient(100deg, transparent 3%, rgba(0,0,0,0.4) 26%, #000 52%);
}

/* The fine grid was texture for a flat wash; against a faceted mesh it is
   clutter, so it goes. */
.gap-hero::before { display: none; }

/* The signature figure now sits ON the mesh, so it needs less presence. */
.gap-art { opacity: 0.09; }

@media (max-width: 900px) {
  .gap-mesh {
    -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 55%);
    mask-image: linear-gradient(180deg, transparent 0%, #000 55%);
    opacity: 0.38;
  }
}
