:root {
  /* Ink: a cold, deep navy rather than black — it reads as instrumentation, not retail. */
  --nx-ink-900: #071320;
  --nx-ink-800: #0d2033;
  --nx-ink-700: #17324b;
  --nx-ink-500: #48627b;
  --nx-ink-400: #6b8299;
  --nx-ink-200: #c3d0dc;
  --nx-ink-100: #dfe6ee;
  --nx-ink-50: #eef2f7;
  --nx-white: #ffffff;

  /* Signal: NEXORA's own accent. Aqua-teal, saturated enough to carry the mark and
     restrained enough to sit beside product photography without competing with it. */
  --nx-signal-700: #06635c;
  --nx-signal-600: #0a8177;
  --nx-signal-500: #10a396;
  --nx-signal-300: #6fd6cb;
  --nx-signal-100: #d7f3ef;
  --nx-signal-50: #eefaf8;

  /* Reason: reserved for explainability surfaces — why an option won, on what basis two
     products were comparable. Nothing commercial is ever allowed to use it. */
  --nx-reason-600: #4b3fbb;
  --nx-reason-100: #e9e6fb;

  --nx-amber-700: #7a4b06;
  --nx-amber-300: #e2b35d;
  --nx-amber-50: #fff6e6;
  --nx-red-600: #a3282f;
  --nx-red-50: #fbeceb;
  --nx-green-700: #1d6b3f;
  --nx-green-50: #e8f5ed;

  --nx-font-sans: 'Inter', 'Segoe UI', system-ui, -apple-system, 'Helvetica Neue', sans-serif;
  --nx-font-numeric: 'Inter', ui-monospace, 'SF Mono', system-ui, sans-serif;
  --nx-font-mono: ui-monospace, 'SF Mono', 'Cascadia Mono', 'Roboto Mono', monospace;
}


:root {
  --nx-color-ink: var(--nx-ink-900);
  --nx-color-ink-soft: var(--nx-ink-500);
  --nx-color-ink-faint: var(--nx-ink-400);
  --nx-color-ink-invert: var(--nx-white);
  --nx-color-surface: var(--nx-white);
  --nx-color-surface-sunken: var(--nx-ink-50);
  --nx-color-surface-inverse: var(--nx-ink-900);
  --nx-color-canvas: #f7f9fb;
  --nx-color-line: var(--nx-ink-100);
  --nx-color-line-strong: var(--nx-ink-200);

  --nx-color-accent: var(--nx-signal-600);
  --nx-color-accent-strong: var(--nx-signal-700);
  --nx-color-accent-bright: var(--nx-signal-500);
  --nx-color-accent-soft: var(--nx-signal-100);
  --nx-color-accent-faint: var(--nx-signal-50);

  --nx-color-reason: var(--nx-reason-600);
  --nx-color-reason-soft: var(--nx-reason-100);

  --nx-color-positive: var(--nx-green-700);
  --nx-color-positive-soft: var(--nx-green-50);
  --nx-color-caution: var(--nx-amber-700);
  --nx-color-caution-soft: var(--nx-amber-50);
  --nx-color-caution-line: var(--nx-amber-300);
  --nx-color-danger: var(--nx-red-600);
  --nx-color-danger-soft: var(--nx-red-50);

  /* A fluid type scale: one set of sizes serves a 360px phone and a 1440px desktop,
     so no breakpoint has to restate typography. */
  --nx-text-2xs: 0.6875rem;
  --nx-text-xs: 0.75rem;
  --nx-text-sm: 0.875rem;
  --nx-text-md: 1rem;
  --nx-text-lg: clamp(1.0625rem, 1rem + 0.3vw, 1.1875rem);
  --nx-text-xl: clamp(1.25rem, 1.15rem + 0.5vw, 1.5rem);
  --nx-text-2xl: clamp(1.6rem, 1.4rem + 1vw, 2.1rem);
  --nx-text-3xl: clamp(2.1rem, 1.7rem + 2.2vw, 3.25rem);
  --nx-leading: 1.55;
  --nx-leading-tight: 1.18;
  --nx-tracking-display: -0.025em;
  --nx-tracking-label: 0.11em;
  --nx-weight-regular: 400;
  --nx-weight-medium: 550;
  --nx-weight-bold: 680;

  /* A 4px rhythm. Every gap, pad and inset in the product is one of these. */
  --nx-space-1: 0.25rem;
  --nx-space-2: 0.5rem;
  --nx-space-3: 0.75rem;
  --nx-space-4: 1rem;
  --nx-space-5: 1.25rem;
  --nx-space-6: 1.5rem;
  --nx-space-8: 2rem;
  --nx-space-10: 2.5rem;
  --nx-space-12: 3rem;
  --nx-space-16: 4rem;

  --nx-radius-sm: 8px;
  --nx-radius-md: 12px;
  --nx-radius-lg: 20px;
  --nx-radius-pill: 999px;
  --nx-shadow-raised: 0 1px 2px rgba(7, 19, 32, 0.05), 0 10px 30px -12px rgba(7, 19, 32, 0.18);
  --nx-shadow-overlay: 0 20px 50px -20px rgba(7, 19, 32, 0.35);
  --nx-ring: 0 0 0 3px var(--nx-color-accent-soft);

  --nx-shell: 1200px;
  --nx-measure: 66ch;
  --nx-header-height: 4.5rem;
  --nx-motion-fast: 120ms;
  --nx-motion: 220ms;
  --nx-ease: cubic-bezier(0.2, 0.7, 0.3, 1);
}

/* The palette inverts on request; no component rule participates in the decision. */
@media (prefers-color-scheme: dark) {
  :root {
    --nx-color-ink: #eaf1f8;
    --nx-color-ink-soft: #a3b6c9;
    --nx-color-ink-faint: #8298ad;
    --nx-color-ink-invert: var(--nx-ink-900);
    --nx-color-surface: #0f2233;
    --nx-color-surface-sunken: #0b1a28;
    --nx-color-surface-inverse: #061019;
    --nx-color-canvas: #071320;
    --nx-color-line: #1d3549;
    --nx-color-line-strong: #2b4761;
    --nx-color-accent: var(--nx-signal-300);
    --nx-color-accent-strong: var(--nx-signal-300);
    --nx-color-accent-bright: var(--nx-signal-500);
    --nx-color-accent-soft: rgba(16, 163, 150, 0.18);
    --nx-color-accent-faint: rgba(16, 163, 150, 0.1);
    --nx-color-reason: #b9b0ff;
    --nx-color-reason-soft: rgba(75, 63, 187, 0.25);
    --nx-color-positive: #7bd39d;
    --nx-color-positive-soft: rgba(29, 107, 63, 0.28);
    --nx-color-caution: #f0c375;
    --nx-color-caution-soft: rgba(226, 179, 93, 0.16);
    --nx-color-caution-line: rgba(226, 179, 93, 0.5);
    --nx-color-danger: #f2938f;
    --nx-color-danger-soft: rgba(163, 40, 47, 0.22);
    --nx-shadow-raised: 0 1px 2px rgba(0, 0, 0, 0.4), 0 12px 32px -16px rgba(0, 0, 0, 0.7);
  }
}


*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--nx-font-sans);
  font-size: var(--nx-text-md);
  line-height: var(--nx-leading);
  color: var(--nx-color-ink);
  background: var(--nx-color-canvas);
  -webkit-font-smoothing: antialiased;
}
a { color: var(--nx-color-accent-strong); text-underline-offset: 0.15em; }
a:hover { color: var(--nx-color-accent-bright); }
h1, h2, h3, h4 {
  line-height: var(--nx-leading-tight);
  letter-spacing: var(--nx-tracking-display);
  font-weight: var(--nx-weight-bold);
  margin: 0 0 var(--nx-space-3);
  text-wrap: balance;
}
h1 { font-size: var(--nx-text-3xl); }
h2 { font-size: var(--nx-text-2xl); }
h3 { font-size: var(--nx-text-lg); letter-spacing: -0.015em; }
h4 { font-size: var(--nx-text-md); letter-spacing: 0; }
p { margin: 0 0 var(--nx-space-4); max-width: var(--nx-measure); }
img { max-width: 100%; height: auto; }
code { font-family: var(--nx-font-mono); font-size: 0.9em; overflow-wrap: anywhere; }
:focus-visible {
  outline: 3px solid var(--nx-color-accent-bright);
  outline-offset: 2px;
  border-radius: var(--nx-radius-sm);
}
::selection { background: var(--nx-color-accent-soft); }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}


.shell { width: 100%; max-width: var(--nx-shell); margin: 0 auto; padding: 0 var(--nx-space-5); }
.stack > * + * { margin-top: var(--nx-space-4); }
.stack-lg > * + * { margin-top: var(--nx-space-10); }
.cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--nx-space-2); }
.cluster.gap-4 { gap: var(--nx-space-4); }
.grid-auto { display: grid; gap: var(--nx-space-5); grid-template-columns: repeat(auto-fill, minmax(min(15.5rem, 100%), 1fr)); }
main { display: block; padding: var(--nx-space-8) 0 var(--nx-space-16); }
main > .shell > * + * { margin-top: var(--nx-space-10); }
.section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--nx-space-4); flex-wrap: wrap; margin-bottom: var(--nx-space-5);
}
.section-head h2 { margin: 0; }
.eyebrow {
  margin: 0 0 var(--nx-space-2); font-size: var(--nx-text-xs); font-weight: var(--nx-weight-bold);
  text-transform: uppercase; letter-spacing: var(--nx-tracking-label); color: var(--nx-color-accent-strong);
}
.meta { font-size: var(--nx-text-sm); color: var(--nx-color-ink-soft); margin: 0; }
.meta-xs { font-size: var(--nx-text-xs); color: var(--nx-color-ink-faint); margin: 0; }
.prose { max-width: var(--nx-measure); }
.prose h2 { font-size: var(--nx-text-xl); margin-top: var(--nx-space-8); }
.lead { font-size: var(--nx-text-lg); color: var(--nx-color-ink-soft); max-width: 46ch; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: var(--nx-space-4); top: -4rem; z-index: 50;
  background: var(--nx-color-surface); color: var(--nx-color-ink);
  padding: var(--nx-space-3) var(--nx-space-4); border-radius: var(--nx-radius-md);
  box-shadow: var(--nx-shadow-overlay); transition: top var(--nx-motion) var(--nx-ease);
}
.skip-link:focus { top: var(--nx-space-3); }


.site-header {
  background: color-mix(in srgb, var(--nx-color-surface) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--nx-color-line);
  position: sticky; top: 0; z-index: 20;
}
.site-header > .shell {
  min-height: var(--nx-header-height);
  display: flex; align-items: center; gap: var(--nx-space-5); flex-wrap: wrap;
  padding-top: var(--nx-space-3); padding-bottom: var(--nx-space-3);
}
.brand { display: inline-flex; align-items: center; gap: var(--nx-space-2); text-decoration: none; color: var(--nx-color-ink); }
.brand:hover { color: var(--nx-color-ink); }
.wordmark svg { display: block; height: 26px; width: auto; color: currentColor; }
.site-nav { margin-left: auto; display: flex; gap: var(--nx-space-5); font-size: var(--nx-text-sm); font-weight: var(--nx-weight-medium); }
.site-nav a { color: var(--nx-color-ink-soft); text-decoration: none; padding: var(--nx-space-1) 0; border-bottom: 2px solid transparent; }
.site-nav a:hover, .site-nav a[aria-current='page'] { color: var(--nx-color-ink); border-bottom-color: var(--nx-color-accent); }
/* How many products are waiting on the comparison page, carried in the chrome. */
.nav-count {
  display: inline-block; min-width: 1.25rem; padding: 0 var(--nx-space-1);
  border-radius: var(--nx-radius-pill); background: var(--nx-color-accent-faint);
  color: var(--nx-color-accent-strong); font-size: var(--nx-text-2xs);
  font-weight: var(--nx-weight-bold); text-align: center; line-height: 1.25rem;
}
/* Two languages, read as two choices: without this the anchors touch and say "EnglishEspañol". */
.lang-switch {
  display: flex; align-items: center; gap: var(--nx-space-1);
  border: 1px solid var(--nx-color-line); border-radius: var(--nx-radius-pill);
  padding: 2px; font-size: var(--nx-text-xs); font-weight: var(--nx-weight-medium);
}
.lang-switch a {
  display: inline-block; padding: 2px var(--nx-space-3); border-radius: var(--nx-radius-pill);
  color: var(--nx-color-ink-soft); text-decoration: none; white-space: nowrap; border-bottom: 0;
}
.lang-switch a:hover { color: var(--nx-color-ink); }
.lang-switch a[aria-current='true'] {
  background: var(--nx-color-accent-faint); color: var(--nx-color-accent-strong);
}
.destination-list { display: flex; flex-wrap: wrap; gap: var(--nx-space-3); list-style: none; padding: 0; margin: 0 0 var(--nx-space-8); }
.destination-list li { flex: 1 1 100%; }
.destination-list .button { width: 100%; justify-content: center; }
@media (min-width: 40rem) {
  .destination-list li { flex: 0 0 auto; }
  .destination-list .button { width: auto; }
}
.source-list { display: grid; gap: var(--nx-space-3); list-style: none; padding: 0; margin: 0 0 var(--nx-space-8); max-width: 60ch; }
.source-list li { display: grid; gap: var(--nx-space-1); }
.source-list strong { color: var(--nx-color-ink); }
.source-list .meta { color: var(--nx-color-ink-soft); }
.site-header .search.header { flex: 1 1 20rem; min-width: 0; max-width: 32rem; margin: 0; }
/* A finger is not a cursor: on a touch screen every link in the chrome is given a target
   tall enough to hit without aiming. */
@media (max-width: 720px) {
  .site-header > .shell { gap: var(--nx-space-3); }
  .site-header .search.header { order: 3; flex-basis: 100%; max-width: none; }
  .site-nav { gap: var(--nx-space-4); font-size: var(--nx-text-xs); }
  .site-nav a { display: inline-flex; align-items: center; min-height: 2.75rem; }
  .lang-switch a { padding: var(--nx-space-2) var(--nx-space-3); min-height: 2.75rem; display: inline-flex; align-items: center; }
  .site-footer nav a { display: inline-flex; align-items: center; min-height: 2.75rem; }
}
.site-footer {
  border-top: 1px solid var(--nx-color-line);
  background: var(--nx-color-surface);
  padding: var(--nx-space-12) 0 var(--nx-space-10);
  font-size: var(--nx-text-sm);
  color: var(--nx-color-ink-soft);
}
.footer-grid { display: grid; gap: var(--nx-space-8); grid-template-columns: minmax(14rem, 1fr) 2fr; align-items: start; }
@media (max-width: 720px) { .footer-grid { grid-template-columns: 1fr; } }
.site-footer nav { display: flex; gap: var(--nx-space-5); flex-wrap: wrap; margin-bottom: var(--nx-space-4); }
.site-footer a { color: var(--nx-color-ink-soft); }
.footer-link {
  background: none; border: 0; padding: 0; font: inherit; color: var(--nx-color-ink-soft);
  text-decoration: underline; cursor: pointer; min-height: 2.75rem;
}
.consent-bar {
  position: fixed; left: var(--nx-space-4); right: var(--nx-space-4); bottom: var(--nx-space-4);
  z-index: 50; max-width: 44rem; margin-inline: auto; display: flex; flex-wrap: wrap;
  gap: var(--nx-space-3); align-items: center; padding: var(--nx-space-4);
  background: var(--nx-color-surface); border: 1px solid var(--nx-color-line);
  border-radius: var(--nx-radius-md); box-shadow: var(--nx-shadow-overlay);
  font-size: var(--nx-text-sm); color: var(--nx-color-ink);
}
.consent-bar[hidden] { display: none; }
.consent-bar p { margin: 0; flex: 1 1 18rem; }
.consent-actions { display: flex; gap: var(--nx-space-2); flex-wrap: wrap; }


.button {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--nx-space-2);
  border: 1px solid transparent; cursor: pointer; text-align: center;
  padding: var(--nx-space-3) var(--nx-space-5);
  min-height: 2.75rem;
  border-radius: var(--nx-radius-pill);
  font: inherit; font-size: var(--nx-text-sm); font-weight: var(--nx-weight-bold);
  letter-spacing: 0.005em;
  background: var(--nx-color-accent); color: #fff; text-decoration: none;
  transition: background var(--nx-motion-fast) var(--nx-ease), transform var(--nx-motion-fast) var(--nx-ease), box-shadow var(--nx-motion-fast) var(--nx-ease);
}
.button:hover { background: var(--nx-color-accent-strong); color: #fff; box-shadow: var(--nx-ring); }
.button:active { transform: translateY(1px); }
.button.secondary { background: var(--nx-color-surface); color: var(--nx-color-accent-strong); border-color: var(--nx-color-line-strong); }
.button.secondary:hover { background: var(--nx-color-accent-faint); color: var(--nx-color-accent-strong); }
.button.quiet { background: transparent; color: var(--nx-color-ink-soft); border-color: transparent; padding-inline: var(--nx-space-2); }
.button.quiet:hover { background: var(--nx-color-surface-sunken); color: var(--nx-color-ink); box-shadow: none; }
.button.block { width: 100%; }
.button .icon { width: 1.05em; height: 1.05em; }
.icon { width: 1em; height: 1em; flex: none; vertical-align: -0.125em; }

.search { display: flex; gap: var(--nx-space-2); flex-wrap: wrap; margin: 0; }
/* The dictation button lives inside the field, so it reads as part of the search box
   rather than as a second action competing with send. */
.search .button.mic {
  align-self: center; border-radius: var(--nx-radius-pill); padding: var(--nx-space-2);
  color: var(--nx-color-accent-strong); background: var(--nx-color-accent-faint);
  border: 1px solid var(--nx-color-accent); flex: none;
}
/* A wrapping row must not let the box push the submit onto its own line: a zero basis keeps
   the field shrinking, so only the status text below it ever takes a second row. */
.search .field { flex: 1 1 0; }
.search .button.mic .icon { color: inherit; }
.search .button.mic:hover { color: var(--nx-color-accent-strong); }
/* Dictation says nothing until it has something to say, so an idle search box keeps the
   single line it has today. */
.search .composer-status { flex: 1 0 100%; margin: 0; }
.search .composer-status:empty { display: none; }
.search.listening .composer-status { color: var(--nx-color-accent-strong); font-weight: 600; }
.field {
  display: flex; align-items: center; gap: var(--nx-space-2); flex: 1 1 auto; min-width: 0;
  background: var(--nx-color-surface); border: 1px solid var(--nx-color-line-strong);
  border-radius: var(--nx-radius-pill); padding: 0 var(--nx-space-4);
  transition: border-color var(--nx-motion-fast) var(--nx-ease), box-shadow var(--nx-motion-fast) var(--nx-ease);
}
.field:focus-within { border-color: var(--nx-color-accent); box-shadow: var(--nx-ring); }
.field .icon { color: var(--nx-color-ink-faint); }
.field input[type='search'], .field input[type='text'] {
  flex: 1 1 auto; min-width: 0; border: 0; background: transparent; color: inherit;
  font: inherit; padding: var(--nx-space-3) 0; min-height: 2.75rem;
}
.field input[type='search']:focus, .field input[type='text']:focus { outline: none; }
.search.hero .field { padding: 0 var(--nx-space-5); }
.search.hero input[type='search'] { font-size: var(--nx-text-lg); min-height: 3.25rem; }
@media (max-width: 520px) {
  .search .button span { display: none; }
  .search .button { padding-inline: var(--nx-space-4); }
}

.filters { display: grid; gap: var(--nx-space-5); }
.filter-card {
  background: var(--nx-color-surface); border: 1px solid var(--nx-color-line);
  border-radius: var(--nx-radius-lg); padding: var(--nx-space-5);
}
.filters fieldset { border: 0; padding: 0; margin: 0; }
.filters legend {
  font-size: var(--nx-text-xs); font-weight: var(--nx-weight-bold); text-transform: uppercase;
  letter-spacing: var(--nx-tracking-label); color: var(--nx-color-ink-faint); padding: 0 0 var(--nx-space-2);
}
.filters label {
  display: flex; gap: var(--nx-space-3); align-items: center; font-size: var(--nx-text-sm);
  padding: var(--nx-space-2) 0; cursor: pointer; min-height: 2.25rem;
}
.filters input[type='checkbox'], .filters input[type='radio'] { width: 1.05rem; height: 1.05rem; accent-color: var(--nx-color-accent); flex: none; }
.filters .count { margin-left: auto; color: var(--nx-color-ink-faint); font-variant-numeric: tabular-nums; font-size: var(--nx-text-xs); }
.filters fieldset + fieldset, .filters .filter-foot { border-top: 1px solid var(--nx-color-line); margin-top: var(--nx-space-4); padding-top: var(--nx-space-4); }

/* The filter panel is a column beside the results on a desktop and a collapsible
   disclosure under them on a phone, where the results deserve the first screen. It is
   served open, because only the reader — never a script — should close it. */
.filter-disclosure > summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; gap: var(--nx-space-2);
  padding: var(--nx-space-3) var(--nx-space-5); border-radius: var(--nx-radius-pill);
  border: 1px solid var(--nx-color-line-strong); background: var(--nx-color-surface);
  font-weight: var(--nx-weight-bold); font-size: var(--nx-text-sm); min-height: 2.75rem;
}
.filter-disclosure > summary::-webkit-details-marker { display: none; }
.filter-disclosure[open] > summary { margin-bottom: var(--nx-space-4); }
@media (min-width: 861px) {
  .filter-disclosure > summary { display: none; }
  .filter-disclosure > .filters { display: grid !important; }
}


.chips { display: flex; flex-wrap: wrap; gap: var(--nx-space-2); list-style: none; padding: 0; margin: 0; }
.chip {
  display: inline-flex; align-items: center; gap: var(--nx-space-2);
  padding: var(--nx-space-2) var(--nx-space-4); min-height: 2.25rem;
  border: 1px solid var(--nx-color-line-strong); border-radius: var(--nx-radius-pill);
  background: var(--nx-color-surface); font-size: var(--nx-text-sm); text-decoration: none;
  color: var(--nx-color-ink);
  transition: border-color var(--nx-motion-fast) var(--nx-ease), background var(--nx-motion-fast) var(--nx-ease);
}
.chip:hover { border-color: var(--nx-color-accent); background: var(--nx-color-accent-faint); color: var(--nx-color-ink); }
.chip .count { color: var(--nx-color-ink-faint); font-variant-numeric: tabular-nums; }
.chip.removable { background: var(--nx-color-accent-soft); border-color: transparent; color: var(--nx-color-accent-strong); font-weight: var(--nx-weight-medium); }
.chip.clear { color: var(--nx-color-ink-soft); border-style: dashed; }

/* Worked briefs: a sentence a shopper can hand to the assistant, one tap wide on a phone. */
.briefs { display: grid; gap: var(--nx-space-3); list-style: none; padding: 0; margin: var(--nx-space-4) 0 0; }
@media (min-width: 46rem) { .briefs { grid-template-columns: repeat(3, 1fr); } }
.brief-example {
  display: flex; align-items: flex-start; gap: var(--nx-space-3); height: 100%;
  padding: var(--nx-space-4); border: 1px solid var(--nx-color-line);
  border-radius: var(--nx-radius-lg); background: var(--nx-color-surface);
  color: var(--nx-color-ink); text-decoration: none; font-size: var(--nx-text-sm);
  transition: border-color var(--nx-motion-fast) var(--nx-ease), background var(--nx-motion-fast) var(--nx-ease);
}
.brief-example:hover { border-color: var(--nx-color-accent); background: var(--nx-color-accent-faint); }
.brief-example svg { flex: none; color: var(--nx-color-accent-strong); }

.badge {
  display: inline-flex; align-items: center; gap: var(--nx-space-1);
  font-size: var(--nx-text-xs); font-weight: var(--nx-weight-bold); line-height: 1.4;
  padding: 3px var(--nx-space-3); border-radius: var(--nx-radius-pill);
  background: var(--nx-color-accent-soft); color: var(--nx-color-accent-strong);
}
.badge.muted { background: var(--nx-color-surface-sunken); color: var(--nx-color-ink-soft); }
.badge.positive { background: var(--nx-color-positive-soft); color: var(--nx-color-positive); }
.badge.warn { background: var(--nx-color-caution-soft); color: var(--nx-color-caution); }
.badge.danger { background: var(--nx-color-danger-soft); color: var(--nx-color-danger); }
.badge.reason { background: var(--nx-color-reason-soft); color: var(--nx-color-reason); }
.badge.deal { background: var(--nx-color-accent); color: #fff; }


.media {
  position: relative; display: block; overflow: hidden;
  aspect-ratio: 4 / 3; background: var(--nx-color-surface-sunken);
  border-radius: var(--nx-radius-md);
}
.media img { width: 100%; height: 100%; object-fit: contain; display: block; padding: var(--nx-space-3); }
.media.tall { aspect-ratio: 1 / 1; }
.media.hero-media { aspect-ratio: 4 / 3; border: 1px solid var(--nx-color-line); background: var(--nx-color-surface); }
.media-empty {
  display: grid; place-content: center; gap: var(--nx-space-2); height: 100%; text-align: center;
  padding: var(--nx-space-4);
  background:
    radial-gradient(120% 120% at 20% 0%, var(--nx-color-accent-faint) 0%, transparent 65%),
    var(--nx-color-surface-sunken);
  color: var(--nx-color-ink-faint);
}
.media-empty.tint-1 { background: radial-gradient(120% 120% at 80% 0%, var(--nx-color-reason-soft) 0%, transparent 65%), var(--nx-color-surface-sunken); }
.media-empty.tint-2 { background: radial-gradient(120% 120% at 0% 100%, var(--nx-color-accent-soft) 0%, transparent 60%), var(--nx-color-surface-sunken); }
.media-empty.tint-3 { background: radial-gradient(130% 130% at 100% 100%, var(--nx-color-caution-soft) 0%, transparent 65%), var(--nx-color-surface-sunken); }
.media-empty.tint-4 { background: linear-gradient(135deg, var(--nx-color-accent-faint) 0%, var(--nx-color-surface-sunken) 70%); }
.media-empty.tint-5 { background: linear-gradient(200deg, var(--nx-color-reason-soft) 0%, var(--nx-color-surface-sunken) 65%); }
.media-empty .monogram {
  justify-self: center; width: 2.75rem; height: 2.75rem; opacity: 0.55; color: var(--nx-color-ink-faint);
}
.media-empty span { font-size: var(--nx-text-2xs); text-transform: uppercase; letter-spacing: var(--nx-tracking-label); }
/* The category schematic drawn where a photograph is missing. It is deliberately quiet:
   it must furnish the frame without ever competing with a real photograph elsewhere on
   the page, and the words beneath it are what carry the meaning. */
.media-empty .artwork {
  justify-self: center; width: min(62%, 11rem); height: auto; max-height: 60%;
  color: var(--nx-color-ink-faint); opacity: 0.85;
}
.media-empty .artwork .accent { color: var(--nx-color-accent); stroke: currentColor; opacity: 0.9; }
.media-empty .artwork .fill { fill: var(--nx-color-surface); }
.media.hero-media .media-empty .artwork { width: min(52%, 15rem); }
.gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(4.5rem, 1fr)); gap: var(--nx-space-2); margin-top: var(--nx-space-2); }
.gallery .media { aspect-ratio: 1 / 1; border: 1px solid var(--nx-color-line); }


.card {
  background: var(--nx-color-surface); border: 1px solid var(--nx-color-line);
  border-radius: var(--nx-radius-lg); padding: var(--nx-space-5);
  display: flex; flex-direction: column; gap: var(--nx-space-3);
}
.card.flush { padding: 0; overflow: hidden; }
.card.flush .card-body { padding: var(--nx-space-4) var(--nx-space-5) var(--nx-space-5); display: flex; flex-direction: column; gap: var(--nx-space-2); flex: 1 1 auto; }
.card h3 { margin: 0; font-size: var(--nx-text-md); }
.card h3 a { color: inherit; text-decoration: none; }
.card h3 a:hover { color: var(--nx-color-accent-strong); text-decoration: underline; }
.product-card { position: relative; transition: transform var(--nx-motion) var(--nx-ease), box-shadow var(--nx-motion) var(--nx-ease), border-color var(--nx-motion) var(--nx-ease); }
.product-card:hover { transform: translateY(-2px); box-shadow: var(--nx-shadow-raised); border-color: var(--nx-color-line-strong); }
.product-card .title-line { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.card-foot { margin-top: auto; padding-top: var(--nx-space-2); display: grid; gap: var(--nx-space-2); }
.card-foot form { display: contents; }
/* A form control that reads as a link: used where an action sits inside running text. */
.link-button {
  border: 0; background: none; padding: var(--nx-space-2) 0; min-height: 2.75rem;
  font: inherit; font-size: var(--nx-text-sm); color: var(--nx-color-ink-soft);
  text-decoration: underline; cursor: pointer;
}
.link-button:hover { color: var(--nx-color-ink); }

.price-block { display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--nx-space-2); }
.price {
  font-size: var(--nx-text-xl); font-weight: var(--nx-weight-bold);
  font-family: var(--nx-font-numeric); font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em; margin: 0;
}
.price.lg { font-size: var(--nx-text-2xl); }
.price.unknown { color: var(--nx-color-ink-faint); font-size: var(--nx-text-lg); }
.price-was { font-size: var(--nx-text-sm); color: var(--nx-color-ink-faint); text-decoration: line-through; }

.rating { display: inline-flex; align-items: center; gap: var(--nx-space-2); font-size: var(--nx-text-sm); color: var(--nx-color-ink-soft); }
.rating .stars { position: relative; display: inline-block; color: var(--nx-color-line-strong); line-height: 1; }
.rating .stars .filled { position: absolute; inset: 0; overflow: hidden; color: var(--nx-amber-300); white-space: nowrap; }
.rating .stars .icon { width: 0.95rem; height: 0.95rem; }
.rating .stars .filled[data-fill='0'] { width: 0%; }
.rating .stars .filled[data-fill='5'] { width: 5%; }
.rating .stars .filled[data-fill='10'] { width: 10%; }
.rating .stars .filled[data-fill='15'] { width: 15%; }
.rating .stars .filled[data-fill='20'] { width: 20%; }
.rating .stars .filled[data-fill='25'] { width: 25%; }
.rating .stars .filled[data-fill='30'] { width: 30%; }
.rating .stars .filled[data-fill='35'] { width: 35%; }
.rating .stars .filled[data-fill='40'] { width: 40%; }
.rating .stars .filled[data-fill='45'] { width: 45%; }
.rating .stars .filled[data-fill='50'] { width: 50%; }
.rating .stars .filled[data-fill='55'] { width: 55%; }
.rating .stars .filled[data-fill='60'] { width: 60%; }
.rating .stars .filled[data-fill='65'] { width: 65%; }
.rating .stars .filled[data-fill='70'] { width: 70%; }
.rating .stars .filled[data-fill='75'] { width: 75%; }
.rating .stars .filled[data-fill='80'] { width: 80%; }
.rating .stars .filled[data-fill='85'] { width: 85%; }
.rating .stars .filled[data-fill='90'] { width: 90%; }
.rating .stars .filled[data-fill='95'] { width: 95%; }
.rating .stars .filled[data-fill='100'] { width: 100%; }

.trust { display: flex; flex-wrap: wrap; gap: var(--nx-space-3); font-size: var(--nx-text-xs); color: var(--nx-color-ink-soft); list-style: none; padding: 0; margin: 0; }
.trust li { display: inline-flex; align-items: center; gap: var(--nx-space-1); }
.trust .icon { color: var(--nx-color-ink-faint); }

.panel {
  border-radius: var(--nx-radius-lg); padding: var(--nx-space-5);
  background: var(--nx-color-surface); border: 1px solid var(--nx-color-line);
}
.panel.reasoning {
  background: linear-gradient(180deg, var(--nx-color-reason-soft) 0%, var(--nx-color-surface) 60%);
  border-color: color-mix(in srgb, var(--nx-color-reason) 25%, transparent);
}
.panel.reasoning h2 { font-size: var(--nx-text-lg); display: flex; align-items: center; gap: var(--nx-space-2); }
.reasons { margin: 0; padding-left: var(--nx-space-5); font-size: var(--nx-text-sm); display: grid; gap: var(--nx-space-1); }
.reasons li::marker { color: var(--nx-color-accent); }

.trade-offs {
  display: grid; gap: var(--nx-space-1);
  border-left: 3px solid var(--nx-color-line); padding-left: var(--nx-space-3);
}
.trade-off { margin: 0; font-size: var(--nx-text-sm); overflow-wrap: anywhere; }
.trade-off.positive { color: var(--nx-color-positive); }
.trade-off.muted { color: var(--nx-color-ink-soft); }
.trade-off-label { font-weight: var(--nx-weight-bold); }

.offer-list { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--nx-space-4); }
.offer {
  background: var(--nx-color-surface); border: 1px solid var(--nx-color-line);
  border-radius: var(--nx-radius-lg); padding: var(--nx-space-5);
  display: grid; gap: var(--nx-space-3);
}
.offer.recommended { border-color: var(--nx-color-accent); box-shadow: var(--nx-shadow-raised); }
.offer-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--nx-space-3); flex-wrap: wrap; }
.offer-merchant { margin: 0; font-weight: var(--nx-weight-bold); display: flex; align-items: center; gap: var(--nx-space-2); flex-wrap: wrap; }
.offer .button { justify-self: start; }
@media (max-width: 520px) { .offer .button { justify-self: stretch; width: 100%; } }
.merchants { display: flex; flex-wrap: wrap; gap: var(--nx-space-1); list-style: none; padding: 0; margin: 0; }

.rank-list { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--nx-space-5); counter-reset: rank; }
.rank-item { display: grid; grid-template-columns: 12rem 1fr; gap: var(--nx-space-5); align-items: start; }
@media (max-width: 720px) { .rank-item { grid-template-columns: 1fr; } }
.rank-badge {
  display: inline-flex; align-items: center; justify-content: center; min-width: 2rem; height: 2rem;
  border-radius: var(--nx-radius-pill); background: var(--nx-color-surface-inverse); color: var(--nx-color-ink-invert);
  font-weight: var(--nx-weight-bold); font-size: var(--nx-text-sm); font-variant-numeric: tabular-nums;
}
.rank-item.leader .rank-badge { background: var(--nx-color-accent); color: #fff; }

.specs { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(18rem, 100%), 1fr)); gap: 0 var(--nx-space-6); margin: 0; }
.specs > div { display: flex; justify-content: space-between; gap: var(--nx-space-4); padding: var(--nx-space-3) 0; border-bottom: 1px solid var(--nx-color-line); }
.specs dt { color: var(--nx-color-ink-soft); font-size: var(--nx-text-sm); }
.specs dd { margin: 0; font-size: var(--nx-text-sm); font-weight: var(--nx-weight-medium); text-align: right; }

table.attributes { border-collapse: collapse; width: 100%; font-size: var(--nx-text-sm); }
table.attributes th, table.attributes td { text-align: left; padding: var(--nx-space-3); border-bottom: 1px solid var(--nx-color-line); vertical-align: top; }
table.attributes thead th { font-size: var(--nx-text-xs); text-transform: uppercase; letter-spacing: var(--nx-tracking-label); color: var(--nx-color-ink-faint); }
/* A table narrower than its content scrolls inside its own box; the page never does. */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; border: 1px solid var(--nx-color-line); border-radius: var(--nx-radius-lg); background: var(--nx-color-surface); }
.table-scroll table.attributes { min-width: 34rem; }
.table-scroll table.attributes th, .table-scroll table.attributes td { padding-inline: var(--nx-space-5); }
/* A phone cannot show four columns of prose, and a source directory whose commercial model
   is only reachable by sideways scrolling is a directory that hides half of what it says.
   Below the width where the columns stop fitting, every row becomes its own card and each
   cell carries its column name with it, so nothing is dropped and nothing is clipped. */
@media (max-width: 46rem) {
  .table-scroll.stacked { overflow-x: visible; border: 0; background: none; border-radius: 0; }
  .table-scroll.stacked table.attributes { min-width: 0; }
  table.attributes.stacked thead {
    position: absolute; inset-inline-start: 0; top: 0; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  }
  table.attributes.stacked tbody tr {
    display: block; margin-bottom: var(--nx-space-3);
    border: 1px solid var(--nx-color-line); border-radius: var(--nx-radius-lg);
    background: var(--nx-color-surface); padding: var(--nx-space-4) var(--nx-space-5);
  }
  table.attributes.stacked tbody th {
    display: block; padding: 0 0 var(--nx-space-3);
    font-size: var(--nx-text-base); font-weight: var(--nx-weight-semibold);
    border-bottom: 1px solid var(--nx-color-line); white-space: normal;
  }
  table.attributes.stacked tbody td {
    display: flex; flex-wrap: wrap; align-items: baseline;
    justify-content: space-between; gap: var(--nx-space-2) var(--nx-space-4);
    padding: var(--nx-space-3) 0 0; border-bottom: 0;
  }
  table.attributes.stacked tbody td::before {
    content: attr(data-label);
    font-size: var(--nx-text-xs); text-transform: uppercase;
    letter-spacing: var(--nx-tracking-label); color: var(--nx-color-ink-faint);
  }
  table.attributes.stacked tbody td > * { text-align: right; }
}
.differences { display: grid; gap: var(--nx-space-3); margin-block: var(--nx-space-7); }
.differences table.attributes tbody th { font-weight: 600; white-space: nowrap; }
.differences table.attributes thead th a { color: inherit; }


.hero {
  position: relative; overflow: hidden;
  padding: var(--nx-space-16) var(--nx-space-8);
  border-radius: var(--nx-radius-lg);
  background:
    radial-gradient(90% 120% at 8% 0%, var(--nx-color-accent-soft) 0%, transparent 55%),
    radial-gradient(70% 100% at 100% 100%, var(--nx-color-reason-soft) 0%, transparent 60%),
    var(--nx-color-surface);
  border: 1px solid var(--nx-color-line);
}
@media (max-width: 720px) { .hero { padding: var(--nx-space-10) var(--nx-space-5); } }
.hero h1 { max-width: 18ch; }
.hero .search { max-width: 40rem; margin-top: var(--nx-space-6); }
.hero .chips { margin-top: var(--nx-space-4); }
.hero-note { margin: var(--nx-space-6) 0 0; }

.pillars { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr)); gap: var(--nx-space-5); }
.pillar { background: var(--nx-color-surface); border: 1px solid var(--nx-color-line); border-radius: var(--nx-radius-lg); padding: var(--nx-space-5); }
.pillar .icon { width: 1.5rem; height: 1.5rem; color: var(--nx-color-accent); margin-bottom: var(--nx-space-2); }
.pillar h3 { font-size: var(--nx-text-md); }
.pillar p { margin: 0; font-size: var(--nx-text-sm); color: var(--nx-color-ink-soft); }

.results-layout { display: grid; grid-template-columns: 17rem 1fr; gap: var(--nx-space-8); align-items: start; }
.results-side { display: grid; gap: var(--nx-space-5); min-width: 0; }
@media (max-width: 860px) {
  .results-layout { grid-template-columns: 1fr; gap: var(--nx-space-5); }
  .results-layout > .results-side { order: 2; }
}
@media (min-width: 861px) { .results-layout > .results-side { position: sticky; top: calc(var(--nx-header-height) + var(--nx-space-4)); } }
/* The product page leads with the photograph: an equal split on a desktop, stacked with
   the image first on a phone. */
.product-layout { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--nx-space-10); align-items: start; }
@media (max-width: 860px) { .product-layout { grid-template-columns: 1fr; gap: var(--nx-space-6); } }
@media (min-width: 861px) { .product-layout > div:first-child { position: sticky; top: calc(var(--nx-header-height) + var(--nx-space-4)); } }
.results-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--nx-space-4); flex-wrap: wrap; margin-bottom: var(--nx-space-5); }
.result-count { margin: 0; font-weight: var(--nx-weight-bold); font-size: var(--nx-text-lg); }
/* A spoken request can be long even after it is shortened, so the heading wraps inside
   the column instead of pushing the page sideways, and gives the products room on a
   phone. */
.query-heading { overflow-wrap: anywhere; }
@media (max-width: 520px) { .query-heading { font-size: var(--nx-text-xl); } }

.notice {
  border: 1px solid var(--nx-color-caution-line); background: var(--nx-color-caution-soft);
  border-radius: var(--nx-radius-md); padding: var(--nx-space-4) var(--nx-space-5);
  font-size: var(--nx-text-sm); display: flex; gap: var(--nx-space-3); align-items: flex-start;
}
.notice .icon { flex: none; margin-top: 0.15em; color: var(--nx-color-caution); }
.notice p { margin: 0; max-width: none; }
.notice.error { border-color: var(--nx-color-danger); background: var(--nx-color-danger-soft); }
.notice.error .icon { color: var(--nx-color-danger); }
.notice.neutral { border-color: var(--nx-color-line-strong); background: var(--nx-color-surface); }
.notice.neutral .icon { color: var(--nx-color-ink-faint); }

.state {
  background: var(--nx-color-surface); border: 1px dashed var(--nx-color-line-strong);
  border-radius: var(--nx-radius-lg); padding: var(--nx-space-12) var(--nx-space-6);
  text-align: center; display: grid; gap: var(--nx-space-3); justify-items: center;
}
.state .icon { width: 2rem; height: 2rem; color: var(--nx-color-ink-faint); }
.state h2 { margin: 0; font-size: var(--nx-text-xl); }
.state p { margin: 0; }

/* Reserved advertising inventory. It is a labelled, self-contained surface that never
   sits inside a ranked list, so a future placement cannot be mistaken for a result. */
.ad-slot {
  border: 1px dashed var(--nx-color-line-strong); border-radius: var(--nx-radius-lg);
  padding: var(--nx-space-5); background: var(--nx-color-surface-sunken);
  display: grid; gap: var(--nx-space-2); justify-items: start; align-content: start;
  /* The slot occupies its height whether or not it is sold, so a placement arriving
     later cannot push the page under the reader's finger. */
  min-height: 9rem;
}
@media (min-width: 60rem) { .ad-slot { min-height: 10.5rem; } }
.ad-slot .ad-label {
  font-size: var(--nx-text-2xs); font-weight: var(--nx-weight-bold); text-transform: uppercase;
  letter-spacing: var(--nx-tracking-label); color: var(--nx-color-ink-faint);
  display: inline-flex; align-items: center; gap: var(--nx-space-1);
}
.ad-slot p { margin: 0; font-size: var(--nx-text-sm); color: var(--nx-color-ink-soft); }
.ad-slot[data-ad-filled='true'] { border-style: solid; }
.ad-slot .ad-advertiser { font-weight: var(--nx-weight-semibold); color: var(--nx-color-ink); }
.ad-slot .ad-headline { font-size: var(--nx-text-lg); color: var(--nx-color-ink); }

/* The shopper's brief: what NEXORA was told, why a product fits it, and why one did not.
   Reasons are plain sentences rather than scores, because a shopper cannot audit a score. */
.brief {
  display: grid; gap: var(--nx-space-2); margin-bottom: var(--nx-space-5);
  padding: var(--nx-space-4) var(--nx-space-5); border-radius: var(--nx-radius-lg);
  background: var(--nx-color-accent-faint); border: 1px solid var(--nx-color-line);
}
.brief .meta { display: flex; align-items: center; gap: var(--nx-space-2); }
.brief .meta .icon { color: var(--nx-color-accent); }
.why-block { display: grid; gap: var(--nx-space-2); margin-top: var(--nx-space-3); padding-top: var(--nx-space-3); border-top: 1px solid var(--nx-color-line); }
.fit-badge {
  display: inline-flex; align-items: center; gap: var(--nx-space-1); align-self: start;
  font-size: var(--nx-text-2xs); font-weight: var(--nx-weight-bold); text-transform: uppercase;
  letter-spacing: var(--nx-tracking-label); padding: 0.2rem var(--nx-space-2);
  border-radius: var(--nx-radius-pill); background: var(--nx-color-accent-soft);
  color: var(--nx-color-accent-strong);
}
.fit-badge.weak { background: var(--nx-color-surface-sunken); color: var(--nx-color-ink-soft); }
.relax { display: grid; gap: var(--nx-space-2); margin-top: var(--nx-space-5); }
.relax h3 { margin: 0; font-size: var(--nx-text-sm); }
.relax .meta-xs { margin: 0; }
.relax .chip { align-items: baseline; gap: var(--nx-space-2); }
.relax .chip .meta-xs { color: var(--nx-color-ink-soft); }
.ruled-out { display: grid; gap: var(--nx-space-4); margin-top: var(--nx-space-8); }
.ruled-out li { list-style: none; }
.ruled-out ol { display: grid; gap: var(--nx-space-3); padding: 0; margin: 0; }
.ruled-out .why-block { margin: 0; padding: 0; border: 0; }

/* The guided brief form and the conversation share one column so that a phone shows the
   same sequence of questions the desktop does. */
.need-form { display: grid; gap: var(--nx-space-4); }
.need-form fieldset { border: 0; padding: 0; margin: 0; display: grid; gap: var(--nx-space-2); }
.need-form legend { font-size: var(--nx-text-xs); font-weight: var(--nx-weight-bold); text-transform: uppercase; letter-spacing: var(--nx-tracking-label); color: var(--nx-color-ink-soft); padding: 0; }
.need-form label { display: flex; align-items: center; gap: var(--nx-space-2); font-size: var(--nx-text-sm); }
.need-form input[type='number'], .need-form input[type='text'], .need-form select {
  font: inherit; color: inherit; background: var(--nx-color-surface); min-width: 0; width: 100%;
  border: 1px solid var(--nx-color-line-strong); border-radius: var(--nx-radius-sm);
  padding: var(--nx-space-2) var(--nx-space-3);
}
.need-form input[type='checkbox'], .need-form input[type='radio'] { width: 1.05rem; height: 1.05rem; accent-color: var(--nx-color-accent); flex: none; }
.need-form .pair { display: grid; grid-template-columns: 1fr 1fr; gap: var(--nx-space-3); }
.need-form .check-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr)); gap: var(--nx-space-2); }

.assistant { display: grid; gap: var(--nx-space-8); }
.transcript { display: grid; gap: var(--nx-space-3); margin: 0; padding: 0; list-style: none; }
.turn {
  background: var(--nx-color-surface); border: 1px solid var(--nx-color-line);
  border-radius: var(--nx-radius-lg); padding: var(--nx-space-4) var(--nx-space-5);
}
.turn.said { background: var(--nx-color-accent-faint); }
.turn p { margin: 0; }
/* The composer starts at two lines and grows with the request. Its cap is expressed in
   lines rather than pixels so a long dictated sentence scrolls inside the field instead
   of pushing the results off a phone screen. */
.composer { display: grid; grid-template-columns: 1fr auto; gap: var(--nx-space-3) var(--nx-space-3); align-items: start; }
.composer .field { min-width: 0; align-items: flex-start; border-radius: var(--nx-radius-lg); padding: var(--nx-space-2) var(--nx-space-4); }
.composer .field > .icon { margin-top: 0.85rem; }
.composer label.visually-hidden { grid-column: 1 / -1; }
.composer textarea {
  flex: 1 1 auto; min-width: 0; border: 0; background: transparent; color: inherit;
  font: inherit; resize: none; overflow-y: auto;
  padding: var(--nx-space-3) 0; min-height: 3.5rem; max-height: min(40vh, 22rem);
}
.composer textarea:focus { outline: none; }
.composer .button.mic {
  align-self: center; border-radius: var(--nx-radius-pill); padding: var(--nx-space-2);
  color: var(--nx-color-accent-strong); background: var(--nx-color-accent-faint);
  border: 1px solid var(--nx-color-accent);
}
.composer .button.mic .icon { color: inherit; }
.composer .button.mic:hover { color: var(--nx-color-accent-strong); }
.composer .button[type='submit'] { align-self: stretch; }
.composer .composer-status { grid-column: 1 / -1; margin: 0; }
.composer.listening .composer-status { color: var(--nx-color-accent-strong); font-weight: 600; }
/* An open microphone is recording, and a shopper should never have to guess whether it
   is: the button turns the colour every device uses for recording, the field is ringed
   in the same colour, and the status line carries a dot beside the word. */
.composer.listening .button.mic, .search.listening .button.mic {
  background: var(--nx-color-danger); border-color: var(--nx-color-danger);
  color: #fff; animation: nx-pulse 1.6s ease-in-out infinite;
}
.composer.listening .field, .search.listening .field {
  border-color: var(--nx-color-danger);
  box-shadow: 0 0 0 3px var(--nx-color-danger-soft);
}
.composer.listening .composer-status, .search.listening .composer-status {
  color: var(--nx-color-danger);
}
.composer.listening .composer-status::before, .search.listening .composer-status::before {
  content: ''; display: inline-block; width: 0.6em; height: 0.6em; margin-right: 0.45em;
  border-radius: 50%; background: var(--nx-color-danger);
  animation: nx-pulse 1.6s ease-in-out infinite;
}
/* The shopper has stopped and the last words are settling: plainly not recording any
   more, and plainly not finished either. */
.composer.finishing .composer-status, .search.finishing .composer-status {
  color: var(--nx-color-ink-soft); font-weight: 600;
}
/* A request already on its way: the button stays readable but plainly spent. */
.composer.sending .button[type='submit'], .search.sending .button[type='submit'] { opacity: 0.6; }
@keyframes nx-pulse { 50% { opacity: 0.72; } }

/* The camera sits beside the microphone inside the same field: one composer, three ways
   of saying the same thing. Everything it opens is laid out below the field, where no
   ancestor's clipping and no edge of the screen can take it away. */
.photo-pick { position: relative; flex: none; align-self: center; }
.composer .photo-pick { align-self: center; }
.photo-pick .button.camera {
  border-radius: var(--nx-radius-pill); padding: var(--nx-space-2);
  color: var(--nx-color-accent-strong); background: var(--nx-color-accent-faint);
  border: 1px solid var(--nx-color-accent);
}
.photo-pick .button.camera .icon { color: inherit; }
.photo-sources { display: flex; flex-wrap: wrap; gap: var(--nx-space-2); }
.photo-sources .button {
  white-space: nowrap; border: 1px solid var(--nx-color-line-strong);
  background: var(--nx-color-surface);
}
/* The search field hides its button labels on a phone; these two buttons are nothing
   without theirs. */
.photo-panel .photo-sources .button span { display: inline; }
/* What was read from the picture, beside the picture it was read from. */
.photo-panel {
  grid-column: 1 / -1; flex: 1 0 100%; display: grid;
  grid-template-columns: auto 1fr auto; gap: var(--nx-space-3); align-items: start;
  padding: var(--nx-space-3); border: 1px solid var(--nx-color-line);
  border-radius: var(--nx-radius-md); background: var(--nx-color-surface-sunken);
}
.photo-panel[hidden] { display: none; }
.photo-preview:empty { display: none; }
.photo-preview {
  width: 4.5rem; height: 4.5rem; overflow: hidden; border-radius: var(--nx-radius-sm);
  background: var(--nx-color-surface); border: 1px solid var(--nx-color-line);
}
.photo-preview img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo-read { display: grid; gap: var(--nx-space-2); min-width: 0; }
.photo-read p { margin: 0; }
.photo-read .read { font-weight: 600; color: var(--nx-color-ink); }
.photo-read .read:empty { display: none; }
.photo-objects { display: grid; gap: var(--nx-space-2); }
.photo-objects[hidden] { display: none; }
.photo-swatch {
  width: 0.85em; height: 0.85em; border-radius: 50%; display: inline-block;
  border: 1px solid var(--nx-color-line-strong);
}
.photo-note { display: flex; gap: var(--nx-space-2); align-items: flex-start; }
@media (max-width: 520px) {
  .photo-panel { grid-template-columns: auto 1fr; }
  .photo-panel .photo-remove { grid-row: 1; grid-column: 2; justify-self: end; }
  .photo-panel .photo-read { grid-column: 1 / -1; }
}
@media (prefers-reduced-motion: reduce) {
  .composer .button.mic[aria-pressed='true'], .search .button.mic[aria-pressed='true'] { animation: none; }
}
/* On a phone the send button and the brief cannot share a line and still leave room to
   type, so the field takes the width and the button sits under it. */
@media (max-width: 520px) {
  .composer { grid-template-columns: 1fr; }
  /* A dictated request is often several lines; let it use more of the phone screen so
     the whole thing can be read and corrected before sending, then scroll. */
  .composer textarea { max-height: 45vh; }
}
@media (max-width: 520px) { .need-form .pair { grid-template-columns: 1fr; } }

/* Skeletons stand in for content that is on its way, at the size of the content. */
.skeleton { border-radius: var(--nx-radius-sm); background: var(--nx-color-surface-sunken); position: relative; overflow: hidden; }
.skeleton::after {
  content: ''; position: absolute; inset: 0; transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--nx-color-surface) 70%, transparent), transparent);
  animation: nx-shimmer 1.4s infinite;
}
.skeleton.line { height: 0.75rem; margin-bottom: var(--nx-space-2); }
.skeleton.line.short { width: 40%; }
.skeleton.block { aspect-ratio: 4 / 3; }
@keyframes nx-shimmer { to { transform: translateX(100%); } }