/* =========================================================
   GEXI — core.css   (CLEANUP B5, 2026-07-16)
   The LEAN sheet for the HOT surfaces (/app shell + /chat): design
   tokens (light+dark) + base resets + the floating theme toggle + the
   auth modal — extracted VERBATIM from styles.css (the 389KB legacy
   monolith those pages no longer load). The three sections below are
   byte-copies of the @CORE-marked spans in styles.css; edit styles.css
   first, then mirror here — test/coreCssB5.test.js FAILS on drift.
   ========================================================= */

/* @CORE-BEGIN tokens-base — extracted VERBATIM into public/core.css (the lean sheet the shell + chat pages load instead of this monolith). Edit HERE, then mirror into core.css — test/coreCssB5.test.js FAILS on drift. */
/* =========================================================
   DESIGN TOKENS
   --------------------------------------------------------
   Single source of truth for every visual decision.
   Tweak a colour or spacing here → propagates everywhere.
   ========================================================= */

:root {
  /* ---- Brand palette: gecko-green ramp. ----
     Reads "GEX = gecko" — fresh, bright, distinctive vs the violet/pink
     sea every other AI tool uses. The 500 stop is the primary brand;
     accent (lime) is the warmer end of the gradient. */
  --brand-50:   #ecfdf5;
  --brand-100:  #d1fae5;
  --brand-200:  #a7f3d0;
  --brand-300:  #6ee7b7;
  --brand-400:  #34d399;
  --brand-500:  #10b981;   /* emerald — primary brand */
  /* ⭐ THE INK THAT GOES ON THE BRAND FILL. It was REFERENCED but never DEFINED — `var(--on-brand, #fff)`
     appeared on the header's brand button and always fell through to its #fff fallback, giving white on
     emerald at 2.54:1 in light and 1.92:1 in dark, both under the 3:1 floor for a non-text UI control.
     Defined dark, and INTENTIONALLY THE SAME IN BOTH THEMES: --brand-500 is bright in each of them
     (#10b981 / #34d399), so the readable ink does not flip with the theme the way --ink does. Measured:
     7.50:1 on the light brand, 9.90:1 on the dark one. */
  --on-brand:   #0f0f1a;
  --brand-600:  #059669;
  --brand-700:  #047857;
  --brand-800:  #065f46;
  --brand-900:  #064e3b;
  --accent:     #22c55e;   /* vibrant gecko green — the bright tip of the gradient */
  --accent-2:   #84cc16;   /* lime — used in creative surfaces + secondary highlights */

  /* Gradients: the signature look across hero, primary buttons, badges */
  --grad-brand:      linear-gradient(135deg, #10b981 0%, #22c55e 100%);
  --grad-brand-soft: linear-gradient(135deg, rgba(16,185,129,0.10) 0%, rgba(34,197,94,0.10) 100%);
  --grad-creative:   linear-gradient(135deg, #10b981 0%, #22c55e 50%, #84cc16 100%);

  /* Legacy aliases — keep these so existing rules referring to --indigo* still work */
  --indigo:        var(--brand-500);
  --indigo-hover:  var(--brand-600);
  --indigo-active: var(--brand-700);
  --indigo-soft:   var(--brand-50);

  /* ---- Surfaces + text (light mode) ---- */
  --ink:           #0f0f1a;
  --ink-2:         #2a2a3d;
  --muted:         #5e5e72;
  --line:          #ececf4;
  --line-strong:   #d8d8e3;
  --bg:            #fafafd;
  --card:          #ffffff;
  --card-alt:      #f6f6fb;

  /* ---- Status colours ---- */
  --green:         #059669;
  --green-soft:    #d1fae5;
  --amber:         #d97706;
  --amber-soft:    #fef3c7;
  --red:           #dc2626;
  --red-soft:      #fee2e2;
  --slate:         #475569;
  --slate-soft:    #e2e8f0;

  /* ---- Elevation ---- */
  --shadow-sm:     0 1px 2px rgba(15,15,26,0.04), 0 1px 1px rgba(15,15,26,0.03);
  --shadow:        0 4px 12px rgba(15,15,26,0.05), 0 1px 3px rgba(15,15,26,0.04);
  --shadow-md:     0 8px 24px rgba(15,15,26,0.07), 0 2px 6px rgba(15,15,26,0.04);
  --shadow-lg:     0 24px 48px rgba(15,15,26,0.10), 0 0 0 1px rgba(15,15,26,0.04);
  --shadow-glow:   0 0 0 4px rgba(16,185,129,0.18);

  /* ---- Geometry ---- */
  --radius-sm:     6px;
  --radius:        10px;
  --radius-md:     14px;
  --radius-lg:     20px;
  --radius-xl:     28px;
  --radius-pill:   999px;

  /* ---- Type ---- */
  --font-sans:     'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Noto Sans JP', 'Noto Sans KR', 'Noto Sans SC', 'Noto Sans TC', 'Segoe UI Arabic', 'Nirmala UI', sans-serif;
  --font-mono:     'JetBrains Mono', ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, 'Liberation Mono', monospace;

  /* ---- Spacing scale — every layout pulls from this so rhythm stays consistent.
     4 / 8 / 12 / 16 / 24 / 32 / 48 / 64 / 96 — multiples of 4, geometric-ish. */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;
  --space-9: 96px;

  /* ---- Motion — tokens so micro-interactions stay coherent across pages.
     Easing curves taken from Material 3 + Linear's playbook. */
  --ease-out:      cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out:   cubic-bezier(0.4, 0, 0.2, 1);
  --ease-spring:   cubic-bezier(0.34, 1.56, 0.64, 1);
  --dur-fast:      120ms;
  --dur:           180ms;
  --dur-slow:      280ms;

  /* ---- Focus ring (a11y) — consistent visual signal on tab/keyboard nav.
     Tinted to brand so it reads as part of the design, not a browser default. */
  --focus-ring:    0 0 0 3px rgba(34,197,94,0.35);

  /* ---- P2 (premium feel) additions — the surfaces/text tiers the chat assistant + reading
     columns need, so EVERY remapped --cv-* aliases onto a real brand token (no hardcoded
     literals), plus the one primitive styles.css was missing: a type scale. Themeable tokens
     get a matching dark value in the [data-theme="dark"] block below. ---- */
  --card-alt-2:    #edeef4;   /* a 2nd-level panel, one step deeper than --card-alt */
  --faint:         #9090a4;   /* the 3rd text tier — fainter than --muted (preserves a real hierarchy) */
  --bubble-user:   #e9f6ef;   /* the user message bubble: a subtle GECKO-GREEN tint (our take on Gemini's bubble) */
  --code-bg:       #f4f6f9;   /* code-block fill */
  --code-border:   #e6e9f0;
  --content-readw: 760px;     /* the comfortable reading column (chat transcript, briefs) */

  /* Type scale — surfaces stop re-inventing hero/body/caption sizes as per-file clamp() magic. */
  --text-2xs:       11px;   /* the smallest legible tier — nav-rail / chip labels (>= the comfortable-read floor) */
  --text-xs:        12px;
  --text-sm:        13.5px;
  --text-base:      15px;
  --text-lg:        18px;
  --text-xl:        22px;
  --text-2xl:       28px;
  --text-3xl:       clamp(30px, 5vw, 44px);
  --leading-tight:  1.15;
  --leading-snug:   1.35;
  --leading-normal: 1.6;

  /* ---- P0.3 (Phase 7 front-end) — the 2030 DARK-CANVAS token set (additive). Powers the chat-first shell/Stage:
     deeper-than-bg "void" surfaces, a neon-green glow, hairlines, the $0-editor-vs-paid-AI cost tokens, the
     streamed-reasoning rail, and the ○●✓⚠ task-glyph status colours. Every themeable token has a LIGHT fallback HERE
     so an off-theme surface that consumes one still renders safely; the richer values live in [data-theme="dark"].
     --grad-neon is the ONE new electric emerald->lime gradient, defined ONCE here (NOT a re-decl of --grad-creative).
     Dark-canvas v1 = the enriched existing dark theme (one toggle, no new mode); inert until a P1+ surface reads a
     var(--*). All values resolve onto the gecko ramp — no off-brand literal. ---- */
  --void:                 var(--bg);          /* the canvas surface (deeper than --card in dark) */
  --void-2:               var(--card-alt);    /* a 2nd void tier */
  --glow-accent:          0 0 0 1px rgba(16,185,129,0.20);   /* neon-green glow (subtle in light) */
  --hairline-neon:        rgba(16,185,129,0.28);
  --grad-neon:            linear-gradient(135deg, #10b981 0%, #34d399 45%, #84cc16 100%);
  --cost-free:            var(--muted);       /* $0 editor op — neutral/muted */
  --cost-paid:            var(--brand-600);   /* paid AI op — brand-tinted */
  --reason-rail:          var(--line);        /* the streamed-reasoning rail edge */
  --reason-tint-producer: var(--brand-50);    /* the producer-reasoning tint */
  --glyph-pending:        var(--muted);       /* ○ queued */
  --glyph-making:         var(--accent);      /* ● in-flight (bright gecko) */
  --glyph-ready:          var(--green);       /* ✓ secured */
  --glyph-failed:         var(--red);         /* ⚠ failed */
}

/* =========================================================
   DARK THEME — confident "AI lab" surfaces.
   Same brand gradient, but on deeper backgrounds with a
   subtle violet undertone so it doesn't feel like a flat
   mid-grey app.
   ========================================================= */
[data-theme="dark"] {
  /* Keep the brand GREEN in dark mode — the violet override was a legacy
     from pre-rebrand. Lift the mid-tones so they pop against the deep
     navy backgrounds without losing the gecko identity. */
  --brand-500:  #34d399;   /* brand green, slightly brightened for dark */
  --brand-600:  #10b981;
  --brand-700:  #059669;

  --indigo:        var(--brand-500);
  --indigo-hover:  var(--brand-400);
  --indigo-active: var(--brand-300);
  --indigo-soft:   rgba(34,197,94,0.12);

  /* Surfaces — slightly cooler navy so green on top has high contrast. */
  --ink:           #f5f5fa;
  --ink-2:         #c4c4d4;
  --muted:         #8d8da3;
  --line:          #1f1f33;
  --line-strong:   #2e2e46;
  --bg:            #08080f;
  --card:          #11112a;
  --card-alt:      #181830;

  --green:         #4ade80;
  --green-soft:    rgba(34,197,94,0.16);
  --amber:         #fbbf24;
  --amber-soft:    rgba(245,158,11,0.16);
  --red:           #f87171;
  --red-soft:      rgba(239,68,68,0.16);
  --slate:         #cbd5e1;
  --slate-soft:    rgba(148,163,184,0.16);

  --shadow-sm:     0 1px 2px rgba(0,0,0,0.4);
  --shadow:        0 4px 12px rgba(0,0,0,0.5), 0 1px 3px rgba(0,0,0,0.3);
  --shadow-md:     0 8px 24px rgba(0,0,0,0.6), 0 2px 6px rgba(0,0,0,0.4);
  --shadow-lg:     0 24px 48px rgba(0,0,0,0.7), 0 0 0 1px rgba(255,255,255,0.06);
  --shadow-glow:   0 0 0 4px rgba(52,211,153,0.30);
  --focus-ring:    0 0 0 3px rgba(52,211,153,0.45);

  /* P2 premium-feel additions — dark counterparts (the type scale + --content-readw are
     size-only, so they live once in :root; these are the themeable surface/text tiers). */
  --card-alt-2:    #1f1f38;
  --faint:         #6b6b82;   /* fainter than dark --muted (#8d8da3) */
  --bubble-user:   #17281f;   /* dark gecko-green-tinted user bubble (replaces chat's blue #2b3a55) */
  --code-bg:       #0e1220;
  --code-border:   #20203a;

  /* P0.3 dark-canvas — the real 2030 values: a near-black "void" below --bg (#08080f), a bioluminescent neon-green
     glow, and brighter glyph/cost tints that pop on the void. --grad-neon is NOT re-declared here (defined once in
     :root). All green/neutral — no off-brand literal. */
  --void:                 #050509;          /* near-black canvas, one step below --bg (same cool surface family) */
  --void-2:               #0c0c18;
  --glow-accent:          0 0 18px rgba(52,211,153,0.42);
  --hairline-neon:        rgba(52,211,153,0.40);
  --cost-free:            var(--muted);     /* $0 editor — muted but WCAG AA over --void (6.27:1); NOT --faint (3.9:1, sub-AA) */
  --cost-paid:            var(--brand-500); /* paid AI — bright brand */
  --reason-rail:          rgba(52,211,153,0.30);   /* intentionally NEUTRAL in light / brand-tinted in dark — a THIN edge (1-2px) + the low-alpha --reason-tint-producer fill, never a saturated fill */
  --reason-tint-producer: rgba(52,211,153,0.08);
  --glyph-pending:        var(--muted);     /* ○ queued — AA over --void (see --cost-free) */
  --glyph-making:         var(--brand-500); /* ● in-flight — tracks the dark brand (==#34d399). making/ready are near-tone greens BY DESIGN; disambiguate by glyph SHAPE (●/✓) + aria, NEVER colour alone (enforced P0.5/P5) */
  --glyph-ready:          var(--green);     /* ✓ secured */
  --glyph-failed:         var(--red);       /* ⚠ failed */

  color-scheme:    dark;
}

/* P2 — the floating dark-toggle theme.js mounts on app-shell surfaces with no .hero-nav (the chat
   SPA). A clean brand-tokened circle, top-right, safe-area aware; above the chat overlays (z 60). */
.theme-toggle-float {
  position: fixed;
  top: calc(env(safe-area-inset-top, 0px) + 10px);
  right: calc(env(safe-area-inset-right, 0px) + 12px);
  z-index: 60; width: 38px; height: 38px; border-radius: var(--radius-pill);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 17px; line-height: 1; cursor: pointer; padding: 0;
  background: var(--card); color: var(--ink);
  border: 1px solid var(--line); box-shadow: var(--shadow-sm);
  transition: box-shadow var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}
.theme-toggle-float:hover  { box-shadow: var(--shadow-md); transform: translateY(-1px); }
.theme-toggle-float:focus-visible { outline: none; box-shadow: var(--focus-ring); }

* { box-sizing: border-box; }

/* =========================================================
   MOBILE SAFETY NET — site-wide horizontal-overflow guard.

   The "screen pans sideways / page zooms out / logo shrinks into the
   top-left corner" class of bug is caused by ANY single element being
   wider than the viewport. The browser then sets the document width
   to that element's width, and the user gets a layout that pans.

   These rules make that mathematically impossible without explicitly
   opting in (e.g. .compare-wrap which keeps its own scroll). Position:
   fixed children (modals, banners) are unaffected because they're
   positioned relative to viewport, not body.
   ========================================================= */
html, body { max-width: 100%; }
html       { overflow-x: clip; }      /* clip > hidden — preserves sticky */
body       { overflow-x: clip; }
/* Media + tables + code never push wider than their parent. */
img, video, iframe, canvas, svg:not(.gecko-print):not(.gecko-tracks) { max-width: 100%; height: auto; }
table { max-width: 100%; }
pre, code, kbd, samp { white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-word; }
/* Long URLs / hashes / filenames break correctly inside paragraphs and
   list items — common offender on profile / billing / admin pages. */
p, li, td, dt, dd { overflow-wrap: anywhere; }

/* Make sure [hidden] always wins, even on flex/grid elements. */
[hidden] { display: none !important; }

/* Visually hidden — keeps content for assistive tech but removes from layout. */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

html, body { height: 100%; }
/* Body uses a column flex layout so the footer can pin to the viewport
   bottom on short pages (homepage in particular). main grows to fill
   available space; footer doesn't shrink. Standard "sticky footer" pattern. */
body {
  margin: 0;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  font-family: var(--font-sans);
  color: var(--ink);
  background: var(--bg);
  line-height: 1.55;
  font-feature-settings: 'cv02', 'cv03', 'cv04', 'cv11'; /* Inter alternates: cleaner letterforms */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
/* main always grows to fill the gap between header and footer */
body > main { flex: 1 0 auto; }
/* Footer is pinned at the natural bottom of the flow — but flex 0 means
   it can never push beyond the viewport, so on tall content it sits
   below content, on short content it sits at the viewport bottom. */
body > .site-footer { flex: 0 0 auto; margin-top: auto; }

/* Subtle violet glow behind the page on dark mode — gives it the "AI lab" depth */
[data-theme="dark"] body {
  background:
    radial-gradient(1200px 600px at 80% -10%, rgba(16,185,129,0.12), transparent 60%),
    radial-gradient(1000px 500px at -10% 110%, rgba(132,204,22,0.10), transparent 60%),
    var(--bg);
  background-attachment: fixed;
}

a { color: inherit; text-decoration: none; }
/* @CORE-END tokens-base */

/* @CORE-BEGIN auth-forgot — extracted VERBATIM into public/core.css (the lean sheet the shell + chat pages load instead of this monolith). Edit HERE, then mirror into core.css — test/coreCssB5.test.js FAILS on drift. */
.auth-forgot {
  display: inline-block;
  margin-top: 6px;
  color: var(--indigo);
  font-weight: 600;
  text-decoration: underline;
  cursor: pointer;
}
/* @CORE-END auth-forgot */

/* @CORE-BEGIN auth-modal — extracted VERBATIM into public/core.css (the lean sheet the shell + chat pages load instead of this monolith). Edit HERE, then mirror into core.css — test/coreCssB5.test.js FAILS on drift. */
.auth-modal {
  position: fixed;
  inset: 0;
  background: rgba(15, 15, 35, 0.6);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  animation: fadeIn 0.2s ease;
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.auth-modal-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 36px 32px 32px;
  width: 100%;
  max-width: 440px;
  position: relative;
  box-shadow: var(--shadow-lg);
  animation: slideUp 0.25s var(--ease-out);
  overflow: hidden;
}
/* Subtle brand-gradient accent stripe at the top of the card. */
.auth-modal-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: var(--grad-brand);
}
@keyframes slideUp { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
.auth-close {
  position: absolute;
  top: 12px; right: 16px;
  background: transparent;
  border: none;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  color: var(--muted);
  width: 32px; height: 32px;
  border-radius: var(--radius-pill);
  transition: all 0.15s ease;
}
.auth-close:hover { color: var(--ink); background: var(--card-alt); }

.auth-tabs {
  display: flex;
  gap: 4px;
  background: var(--card-alt);
  padding: 4px;
  border-radius: var(--radius-pill);
  margin-bottom: 22px;
}
.auth-tab {
  flex: 1;
  background: transparent;
  border: none;
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
  color: var(--muted);
  padding: 9px 12px;
  cursor: pointer;
  border-radius: var(--radius-pill);
  transition: all 0.15s ease;
}
.auth-tab:hover { color: var(--ink); }
.auth-tab.active {
  background: var(--card);
  color: var(--ink);
  box-shadow: var(--shadow-sm), 0 0 0 1px rgba(15,15,26,0.04);
  font-weight: 700;
}
[data-theme="dark"] .auth-tab.active {
  box-shadow: var(--shadow-sm), 0 0 0 1px rgba(255,255,255,0.04);
}

.auth-form { display: grid; gap: 12px; }
.auth-form input {
  padding: 13px 16px;
  font-size: 16px;            /* 16px+ avoids iOS Safari auto-zoom on focus */
  border: 1.5px solid var(--line);
  border-radius: var(--radius-md);
  font-family: var(--font-sans);
  background: var(--card);
  color: var(--ink);
  transition: border-color var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}
.auth-form input:hover:not(:focus) { border-color: var(--line-strong); }
.auth-form input:focus {
  outline: none;
  border-color: var(--brand-400);
  box-shadow: var(--focus-ring);
}

.auth-error {
  background: #fee2e2;
  color: #991b1b;
  border: 1px solid #fecaca;
  padding: 8px 12px;
  border-radius: 8px;
  font-size: 13.5px;
}

/* Password strength meter */
.pw-meter {
  display: grid;
  gap: 6px;
  margin-top: -2px;
}
.pw-meter-bars {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 4px;
}
.pw-meter-bars span {
  height: 5px;
  border-radius: 999px;
  background: #e7eaf3;
  transition: background 0.2s ease;
}
.pw-meter[data-score="1"] .pw-meter-bars span:nth-child(-n+1) { background: #dc2626; }
.pw-meter[data-score="2"] .pw-meter-bars span:nth-child(-n+2) { background: #d97706; }
.pw-meter[data-score="3"] .pw-meter-bars span:nth-child(-n+3) { background: #ca8a04; }
.pw-meter[data-score="4"] .pw-meter-bars span                 { background: #15803d; }
.pw-meter-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
}
.pw-meter[data-score="0"] .pw-meter-label { color: #dc2626; }
.pw-meter[data-score="1"] .pw-meter-label { color: #dc2626; }
.pw-meter[data-score="2"] .pw-meter-label { color: #d97706; }
.pw-meter[data-score="3"] .pw-meter-label { color: #ca8a04; }
.pw-meter[data-score="4"] .pw-meter-label { color: #15803d; }

/* Honeypot — visually hidden but technically focusable for accessibility */
.honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.auth-submit {
  background: var(--grad-brand);
  color: #fff;
  border: none;
  border-radius: var(--radius-md);
  padding: 14px;
  font-family: var(--font-sans);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.1px;
  cursor: pointer;
  margin-top: 6px;
  box-shadow: 0 4px 14px rgba(16,185,129,0.22), 0 1px 2px rgba(15,15,26,0.06);
  transition: transform var(--dur-fast) var(--ease-out), box-shadow var(--dur) var(--ease-out), filter var(--dur) var(--ease-out);
}
.auth-submit:hover {
  transform: translateY(-1px);
  box-shadow: 0 8px 20px rgba(16,185,129,0.28), 0 2px 4px rgba(15,15,26,0.08);
  filter: brightness(1.05);
}
.auth-submit:active { transform: translateY(0); }
.auth-submit:disabled { background: var(--card-alt); color: var(--muted); cursor: not-allowed; transform: none; box-shadow: none; }

.auth-help {
  margin: 16px 0 0;
  font-size: 13px;
  color: var(--muted);
  line-height: 1.5;
}
/* @CORE-END auth-modal */

