/* ---------------------------------------------------------------------------
   Outsource China — the sourcing console

   The homepage hero and the signed-in assistant share every rule in this file.
   One animation language: a visitor who watches the console on the homepage and
   then signs up must land on something they recognise.

   The console keeps its own dark plate in both themes. It is an instrument,
   not a card — the same decision the spotlight band already makes — so its
   colours are literal here rather than pulled from the light/dark tokens. The
   page around it still follows the theme.

   Everything expensive is a transform or an opacity. Nothing animates layout.
--------------------------------------------------------------------------- */

.aiconsole,
.aistage {
  --ac:        #5ad7ef;   /* the working colour — cyan reads as machine    */
  --ac-soft:   rgba(90, 215, 239, .18);
  --ac-line:   rgba(90, 215, 239, .42);
  --plate:     #0c141f;
  --plate-2:   #121d2b;
  --plate-3:   #172436;
  --edge:      rgba(255, 255, 255, .10);
  --edge-2:    rgba(255, 255, 255, .16);
  --ink:       #eef3f8;
  --ink-dim:   #93a4b8;
  --ok:        #56d99a;
}

/* --- Hero ------------------------------------------------------------------
   The console is the argument, so it gets the larger half. */

.aihero {
  background:
    radial-gradient(900px 420px at 88% -10%, rgba(90, 215, 239, .16) 0%, transparent 62%),
    radial-gradient(700px 380px at 6% 110%, rgba(242, 160, 50, .14) 0%, transparent 60%),
    linear-gradient(150deg, var(--nav) 0%, var(--nav-2) 58%, #22405f 100%);
  color: var(--nav-text);
  border-radius: var(--radius-lg);
  padding: 34px 34px 30px;
  margin: 18px 0 26px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr);
  gap: 34px;
  align-items: center;
  position: relative;
  overflow: hidden;
}

/* A slow drift behind the whole hero. Decorative, so it is hidden from
   assistive tech and stopped outright for reduced motion. */
.aihero::after {
  content: "";
  position: absolute; inset: -40%;
  background: conic-gradient(from 0deg, transparent 0deg, rgba(90, 215, 239, .07) 90deg,
              transparent 180deg, rgba(242, 160, 50, .06) 280deg, transparent 360deg);
  animation: ai-drift 34s linear infinite;
  pointer-events: none;
}

.aihero__copy { position: relative; z-index: 1; }

.aihero__eyebrow {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 11.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: #cfe9f2;
  background: var(--ac-soft);
  border: 1px solid var(--ac-line);
  border-radius: 999px; padding: 5px 12px; margin-bottom: 16px;
}
.aihero__eyebrow i {
  width: 7px; height: 7px; border-radius: 50%; background: var(--ac);
  box-shadow: 0 0 0 0 rgba(90, 215, 239, .6);
  animation: ai-beacon 2.4s ease-out infinite;
}

.aihero h1 {
  font-size: 40px; line-height: 1.1; letter-spacing: -.03em; margin-bottom: 14px;
}
/* The second line of the headline. Painted, not clipped: a gradient clipped to
   text disappears entirely the moment anything upstream — a compositing quirk,
   a printer, a browser that only half-supports it — declines to paint the
   background, and a headline that can vanish is not worth the gradient. */
.aihero h1 em { font-style: normal; color: #9ae8f7; }
.aihero__lede { color: var(--nav-text-muted); font-size: 15.5px; max-width: 46ch; }

.aihero__points { list-style: none; margin: 18px 0 0; padding: 0; display: grid; gap: 9px; }
.aihero__points li {
  display: flex; gap: 10px; align-items: flex-start;
  font-size: 13.5px; color: var(--nav-text);
}
.aihero__points li::before {
  content: "";
  flex: none; width: 16px; height: 16px; margin-top: 2px; border-radius: 50%;
  background: var(--ac-soft);
  box-shadow: inset 0 0 0 1px var(--ac-line);
  background-image: linear-gradient(var(--ac), var(--ac));
  background-size: 6px 6px; background-repeat: no-repeat; background-position: center;
}

.aihero__actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 22px; }
.btn--glass {
  background: rgba(255, 255, 255, .10); border-color: rgba(255, 255, 255, .22); color: #fff;
}
.btn--glass:hover { background: rgba(255, 255, 255, .18); color: #fff; }

.aihero__trust {
  display: flex; flex-wrap: wrap; gap: 8px 22px; margin-top: 20px;
  font-size: 12px; color: var(--nav-text-muted);
}
.aihero__trust span { display: flex; align-items: center; gap: 6px; }
.aihero__trust b { color: var(--nav-text); font-weight: 700; }

/* --- The console -----------------------------------------------------------
   Window chrome, a transcript, an animated work area and a spec sheet that
   fills in as the model records things. */

.aiconsole {
  position: relative; z-index: 1;
  background: linear-gradient(180deg, var(--plate-2) 0%, var(--plate) 100%);
  border: 1px solid var(--edge);
  border-radius: var(--radius-lg);
  box-shadow: 0 24px 60px rgba(0, 0, 0, .45), inset 0 1px 0 rgba(255, 255, 255, .05);
  color: var(--ink);
  display: flex; flex-direction: column;
  overflow: hidden;
  min-height: 520px;
}

.aiconsole__bar {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px;
  background: rgba(255, 255, 255, .03);
  border-bottom: 1px solid var(--edge);
  font-size: 12px;
}
.aiconsole__dots { display: flex; gap: 5px; flex: none; }
.aiconsole__dots i { width: 9px; height: 9px; border-radius: 50%; background: rgba(255, 255, 255, .16); }
.aiconsole__name { font-weight: 650; letter-spacing: -.01em; }
.aiconsole__mode {
  margin-left: auto; display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px; border-radius: 999px;
  border: 1px solid var(--edge-2); color: var(--ink-dim);
  font-size: 11px; letter-spacing: .04em; text-transform: uppercase; font-weight: 700;
}
.aiconsole__mode i { width: 6px; height: 6px; border-radius: 50%; background: var(--ink-dim); }
.aiconsole__mode.is-live { color: #bdf0ff; border-color: var(--ac-line); background: var(--ac-soft); }
.aiconsole__mode.is-live i { background: var(--ac); animation: ai-beacon 2.4s ease-out infinite; }

.aiconsole__main {
  display: grid; grid-template-columns: minmax(0, 1fr) 252px;
  flex: 1 1 auto; min-height: 0;
}
/* Grid and flex children size to their content by default, so one long product
   title in the transcript would widen the whole console — and with it the page.
   Every track in here is allowed to be narrower than what is inside it. */
.aiconsole__main > *,
.aihero > * { min-width: 0; }

.aiconsole__thread {
  padding: 16px; min-width: 0;
  display: flex; flex-direction: column; gap: 12px;
  overflow-y: auto;
  max-height: 430px;
  scrollbar-width: thin;
}
.aiconsole__thread::-webkit-scrollbar { width: 7px; }
.aiconsole__thread::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, .14); border-radius: 4px; }

/* --- Transcript bubbles ---------------------------------------------------- */

/* 100% minus the avatar and its gap: at 94% the avatar of a long message hung
   over the spec rail, because the bubble's own width is measured before it. */
.aimsg { display: flex; gap: 9px; max-width: 100%; animation: ai-rise .34s cubic-bezier(.2, .7, .3, 1) both; }
.aimsg__body { min-width: 0; }
.aimsg--user { margin-left: auto; flex-direction: row-reverse; }
.aimsg__who {
  flex: none; width: 26px; height: 26px; border-radius: 8px;
  display: grid; place-items: center;
  font-size: 10px; font-weight: 800; letter-spacing: .02em;
  background: var(--ac-soft); color: #bdf0ff; box-shadow: inset 0 0 0 1px var(--ac-line);
}
.aimsg--user .aimsg__who { background: rgba(242, 160, 50, .16); color: var(--brand-on-dark); box-shadow: inset 0 0 0 1px rgba(242, 160, 50, .32); }
.aimsg__body {
  background: var(--plate-3);
  border: 1px solid var(--edge);
  border-radius: 12px; padding: 10px 13px;
  font-size: 13.5px; line-height: 1.55;
}
.aimsg--user .aimsg__body { background: rgba(242, 160, 50, .10); border-color: rgba(242, 160, 50, .22); }
.aimsg__body p { margin: 0 0 8px; }
.aimsg__body p:last-child { margin-bottom: 0; }
.aimsg__body strong { font-weight: 650; }
.aimsg__body a { color: #9ae8f7; }
.aimsg__body ul, .aimsg__body ol { margin: 0 0 8px; padding-left: 18px; }

/* The caret that trails text as it types itself in. */
.ai-caret {
  display: inline-block; width: 2px; height: 1em; margin-left: 1px;
  background: var(--ac); vertical-align: -2px;
  animation: ai-blink 1s steps(1) infinite;
}

/* --- The work area ---------------------------------------------------------
   A mesh that lights up, a sweep across it, and the real step list. */

.aistage {
  border: 1px solid var(--ac-line);
  border-radius: 12px;
  background:
    radial-gradient(420px 140px at 50% 0%, rgba(90, 215, 239, .10) 0%, transparent 70%),
    var(--plate-2);
  overflow: hidden;
  animation: ai-rise .34s cubic-bezier(.2, .7, .3, 1) both;
}

.aistage__head {
  display: flex; align-items: center; gap: 9px;
  padding: 9px 12px; border-bottom: 1px solid var(--edge);
  font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: #bdf0ff;
}
.aistage__spin {
  flex: none; width: 13px; height: 13px; border-radius: 50%;
  border: 2px solid var(--ac-line); border-top-color: var(--ac);
  animation: ai-spin .8s linear infinite;
}
/* The clock is a reading, not a heading — the uppercase of the row around it
   turns "3.5s" into "3.5S", which reads as a unit nobody uses. */
.aistage__elapsed {
  margin-left: auto; font-variant-numeric: tabular-nums;
  color: var(--ink-dim); letter-spacing: .02em; text-transform: none;
}

/* The mesh. Decorative: aria-hidden in the markup. */
.aistage__mesh { position: relative; height: 84px; overflow: hidden; }
.aistage__mesh svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.aistage__mesh .ai-edge {
  stroke: var(--ac); stroke-width: 1; fill: none; opacity: .14;
  stroke-dasharray: 5 7;
  animation: ai-flow 2.6s linear infinite;
}
.aistage__mesh .ai-node { fill: var(--ac); opacity: .34; transform-box: fill-box; transform-origin: center; }
.aistage__mesh .ai-node.is-hot { opacity: 1; animation: ai-node-pop 1.1s ease-out infinite; }

/* The sweep. One element, moved with transform only. */
.aistage__sweep {
  position: absolute; top: 0; bottom: 0; width: 130px;
  background: linear-gradient(90deg, transparent, rgba(90, 215, 239, .22), transparent);
  animation: ai-sweep 2.2s ease-in-out infinite;
  pointer-events: none;
}

.aistage__count {
  position: absolute; right: 10px; bottom: 7px;
  font-family: var(--mono); font-size: 10.5px; color: #9fe3f4;
  letter-spacing: .03em; font-variant-numeric: tabular-nums;
  background: rgba(12, 20, 31, .72); border-radius: 5px; padding: 2px 6px;
}

.aistage__steps { list-style: none; margin: 0; padding: 8px 12px 11px; display: grid; gap: 2px; }
.aistage__steps li {
  display: grid; grid-template-columns: 16px minmax(0, 1fr) auto;
  align-items: center; gap: 9px;
  padding: 5px 0;
  font-size: 12.5px; color: var(--ink-dim);
  animation: ai-rise .3s cubic-bezier(.2, .7, .3, 1) both;
}
.aistage__steps li + li { border-top: 1px dashed rgba(255, 255, 255, .07); }
.aistage__mark {
  width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid var(--ac-line);
  display: grid; place-items: center;
  font-size: 11px; line-height: 1; color: var(--plate); font-weight: 800;
}
.is-running .aistage__mark { border-top-color: var(--ac); animation: ai-spin .8s linear infinite; }
.is-done .aistage__mark { background: var(--ok); border-color: var(--ok); animation: ai-pop .3s ease-out; }
.is-done .aistage__mark::after { content: "✓"; }
.is-running > .aistage__label { color: var(--ink); }
.is-done > .aistage__label { color: var(--ink); }
.aistage__label { min-width: 0; }
.aistage__label small {
  display: block; color: var(--ink-dim); font-size: 11px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.aistage__hits {
  font-family: var(--mono); font-size: 10.5px; color: #9fe3f4;
  background: var(--ac-soft); border-radius: 999px; padding: 2px 7px;
  animation: ai-pop .3s ease-out;
}

/* --- Product matches -------------------------------------------------------
   They arrive one at a time with a confidence bar that fills. */

.aihits { display: grid; gap: 8px; margin-top: 10px; }
.aihit {
  display: grid; grid-template-columns: 46px minmax(0, 1fr); gap: 10px; align-items: center;
  padding: 8px; border-radius: 10px;
  background: var(--plate-3); border: 1px solid var(--edge);
  color: var(--ink); text-decoration: none;
  animation: ai-hit .42s cubic-bezier(.2, .7, .3, 1) both;
}
.aihit:hover { border-color: var(--ac-line); color: var(--ink); text-decoration: none; background: #1b2a3d; }
.aihit__shot {
  width: 46px; height: 46px; border-radius: 7px; overflow: hidden;
  background: var(--photo-plate); flex: none;
}
.aihit__shot img { width: 100%; height: 100%; object-fit: cover; }
.aihit__title { font-size: 12.5px; font-weight: 600; line-height: 1.35; }
.aihit__meta { font-size: 11px; color: var(--ink-dim); display: flex; gap: 10px; flex-wrap: wrap; margin-top: 2px; }
.aihit__bar { height: 3px; border-radius: 2px; background: rgba(255, 255, 255, .10); margin-top: 6px; overflow: hidden; }
.aihit__bar i { display: block; height: 100%; width: 0; background: linear-gradient(90deg, var(--ac), var(--ok)); animation: ai-fill .9s .15s cubic-bezier(.2, .7, .3, 1) forwards; }

/* --- Live spec sheet -------------------------------------------------------
   The right rail. This is the point of the whole animation: the visitor watches
   a quotable specification assemble itself out of a sentence they typed. */

.aispec {
  border-left: 1px solid var(--edge);
  background: rgba(0, 0, 0, .18);
  padding: 14px;
  display: flex; flex-direction: column; gap: 10px;
  min-width: 0;
}
.aispec__head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.aispec__head h3 { margin: 0; font-size: 12px; text-transform: uppercase; letter-spacing: .07em; color: var(--ink-dim); }
.aispec__pct { font-family: var(--mono); font-size: 12px; color: #9fe3f4; font-variant-numeric: tabular-nums; }

.aispec__meter { height: 5px; border-radius: 999px; background: rgba(255, 255, 255, .09); overflow: hidden; }
.aispec__meter i {
  display: block; height: 100%; width: 3%;
  background: linear-gradient(90deg, var(--ac), var(--brand));
  transition: width .7s cubic-bezier(.2, .7, .3, 1);
}

.aispec__rows { display: grid; gap: 1px; margin: 0; }
/* Both columns can shrink. With an `auto` value column a long answer — a full
   product title, a list of certifications — grew past the panel and printed
   itself over its own label. */
.aispec__row {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr); gap: 8px;
  align-items: baseline;
  padding: 6px 0; border-bottom: 1px dashed rgba(255, 255, 255, .07);
  font-size: 12px;
}
.aispec__row dt { color: var(--ink-dim); min-width: 0; overflow-wrap: anywhere; }
.aispec__row dd { margin: 0; text-align: right; font-weight: 600; color: var(--ink); min-width: 0; overflow-wrap: anywhere; }
.aispec__row.is-empty dd { color: #6f8095; font-weight: 400; font-style: italic; }
.aispec__row.is-fresh { animation: ai-flash 1.1s ease-out; }

.aispec__note { font-size: 11.5px; color: var(--ink-dim); margin: auto 0 0; }
.aispec__note b { color: var(--ink); }

/* --- Composer -------------------------------------------------------------- */

.aiform {
  border-top: 1px solid var(--edge);
  padding: 11px;
  display: flex; gap: 8px; align-items: flex-end;
  background: rgba(255, 255, 255, .02);
}
.aiform textarea {
  flex: 1 1 auto; min-width: 0;
  background: var(--plate-3); color: var(--ink);
  border: 1px solid var(--edge-2); border-radius: 10px;
  padding: 10px 12px; font: inherit; font-size: 13.5px; line-height: 1.45;
  resize: none; min-height: 44px; max-height: 130px;
}
.aiform textarea::placeholder { color: #6f8095; }
.aiform textarea:focus-visible { outline: none; border-color: var(--ac); box-shadow: 0 0 0 3px rgba(90, 215, 239, .18); }
.aiform .btn { flex: none; }
.aiform.is-busy { opacity: .65; }

.aistarters { display: flex; flex-wrap: wrap; gap: 7px; padding: 0 11px 11px; }
.aistarter {
  background: rgba(255, 255, 255, .05); border: 1px solid var(--edge-2); color: var(--ink-dim);
  border-radius: 999px; padding: 5px 11px; font: inherit; font-size: 11.5px; cursor: pointer;
  transition: border-color .15s, color .15s, background .15s;
}
.aistarter:hover { border-color: var(--ac-line); color: #bdf0ff; background: var(--ac-soft); }

.aiconsole__foot {
  padding: 9px 13px; border-top: 1px solid var(--edge);
  font-size: 11.5px; color: var(--ink-dim);
  display: flex; justify-content: space-between; gap: 10px; flex-wrap: wrap;
}
.aiconsole__foot b { color: var(--ink); }

/* --- The sign-up gate ------------------------------------------------------
   Slides over the console once the trial is used up. The conversation stays
   visible and blurred underneath, because what is behind the glass is the
   reason to sign up. */

.aigate {
  position: absolute; inset: 0; z-index: 3;
  display: grid; place-items: center; padding: 22px;
  background: linear-gradient(180deg, rgba(12, 20, 31, .42) 0%, rgba(12, 20, 31, .92) 46%);
  backdrop-filter: blur(7px);
  animation: ai-gate .5s cubic-bezier(.2, .7, .3, 1) both;
}
.aigate__card {
  max-width: 400px; text-align: center;
  background: var(--plate-2); border: 1px solid var(--ac-line);
  border-radius: var(--radius-lg); padding: 22px 22px 20px;
  box-shadow: 0 20px 50px rgba(0, 0, 0, .5);
}
.aigate__card h3 { margin: 0 0 8px; font-size: 18px; letter-spacing: -.02em; color: var(--ink); }
.aigate__card p { margin: 0 0 14px; font-size: 13px; color: var(--ink-dim); line-height: 1.55; }
.aigate__card .btn { width: 100%; }
.aigate__carry {
  display: grid; gap: 5px; margin: 0 0 14px; padding: 10px 12px;
  border-radius: 10px; background: rgba(86, 217, 154, .08); border: 1px solid rgba(86, 217, 154, .24);
  font-size: 12px; color: #cfeede; text-align: left;
}
.aigate__carry b { color: #eafff3; }
.aigate__alt { margin: 10px 0 0; font-size: 12px; color: var(--ink-dim); }
.aigate__alt a { color: #9ae8f7; }

.aiconsole.is-gated .aiconsole__thread,
.aiconsole.is-gated .aispec { filter: saturate(.7); }

/* --- In-chat stage, signed-in assistant -------------------------------------
   Same component, dropped into a light bubble. Only the plate changes. */

.msg__bubble .aistage {
  --plate-2: var(--surface-sunken);
  --plate-3: var(--surface);
  --ink: var(--text);
  --ink-dim: var(--text-muted);
  --edge: var(--border);
  --ac: var(--accent);
  --ac-soft: var(--accent-subtle);
  --ac-line: var(--border-strong);
  margin: 2px 0;
  min-width: 268px;
}
/* A row of the brief that just changed. One flash, then it settles — the panel
   updates on every turn, and a panel that is permanently highlighted tells the
   buyer nothing about which answer landed. */
.brief__row.is-fresh,
.bitem.is-fresh { animation: ai-flash-light 1.3s ease-out; }
@keyframes ai-flash-light {
  0%   { background: var(--accent-subtle); }
  100% { background: transparent; }
}

.msg__bubble .aistage__head { color: var(--accent); }
.msg__bubble .aistage__count { background: var(--surface); color: var(--accent); }

/* On the dark plate a pale tick and a tinted pill read clearly. On paper-white
   they wash out, so the light variant takes the solid status colours the rest
   of the site uses. */
.msg__bubble .aistage { --ok: var(--success); }
.msg__bubble .is-done .aistage__mark { color: #fff; }
.msg__bubble .aistage__hits {
  color: #fff; background: var(--accent); font-weight: 700;
}
.msg__bubble .aistage__mesh .ai-edge { opacity: .3; }
.msg__bubble .aistage__mesh .ai-node { opacity: .5; }

/* --- Keyframes -------------------------------------------------------------- */

@keyframes ai-drift   { to { transform: rotate(360deg); } }
@keyframes ai-spin    { to { transform: rotate(360deg); } }
@keyframes ai-blink   { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
@keyframes ai-sweep   { 0% { transform: translateX(-140px); } 100% { transform: translateX(calc(100% + 140px)); } }
@keyframes ai-flow    { to { stroke-dashoffset: -24; } }
@keyframes ai-rise    { from { opacity: 0; transform: translateY(7px); } to { opacity: 1; transform: none; } }
@keyframes ai-hit     { from { opacity: 0; transform: translateY(10px) scale(.97); } to { opacity: 1; transform: none; } }
@keyframes ai-pop     { from { transform: scale(.4); } to { transform: scale(1); } }
@keyframes ai-fill    { to { width: var(--w, 82%); } }
@keyframes ai-gate    { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@keyframes ai-flash   { 0% { background: rgba(90, 215, 239, .22); } 100% { background: transparent; } }
@keyframes ai-node-pop{ 0%, 100% { opacity: .45; transform: scale(1); } 50% { opacity: 1; transform: scale(1.9); } }
@keyframes ai-beacon  {
  0%   { box-shadow: 0 0 0 0 rgba(90, 215, 239, .55); }
  70%  { box-shadow: 0 0 0 7px rgba(90, 215, 239, 0); }
  100% { box-shadow: 0 0 0 0 rgba(90, 215, 239, 0); }
}

/* --- Responsive ------------------------------------------------------------- */

@media (max-width: 1180px) {
  .aihero { grid-template-columns: 1fr; padding: 28px 24px; }
  .aihero h1 { font-size: 33px; }
  .aiconsole { min-height: 0; }
}

@media (max-width: 900px) {
  .aiconsole__main { grid-template-columns: 1fr; }
  .aispec { border-left: none; border-top: 1px solid var(--edge); }
}

@media (max-width: 760px) {
  .aihero { padding: 22px 16px; border-radius: var(--radius); }
  .aihero h1 { font-size: 27px; }
  .aiconsole__thread { max-height: 340px; }
}

/* --- Reduced motion ---------------------------------------------------------
   The console still works: steps still appear, the spec sheet still fills. What
   stops is everything that moves for effect. */

@media (prefers-reduced-motion: reduce) {
  .aihero::after,
  .aistage__sweep,
  .aistage__mesh .ai-node.is-hot,
  .aistage__mesh .ai-edge,
  .aihero__eyebrow i,
  .aiconsole__mode.is-live i { animation: none !important; }

  .aimsg, .aistage, .aistage__steps li, .aihit, .aigate { animation: none !important; }
  .aihit__bar i { animation: none; width: 82%; }
  .ai-caret { animation: none; opacity: 0; }
  .aistage__spin, .is-running .aistage__mark { animation: none; }
  .aispec__meter i { transition: none; }
}
