/*
 * NEXTMRKT Theme Tokens
 * Single source of truth for all CSS custom properties.
 * Applied via [data-theme="dark"] and [data-theme="light"] on <html>.
 * Do not define :root tokens anywhere else in the codebase.
 */

/* ─── Shared tokens (both themes) ─────────────────────────── */
:root {
  --color-accent:      #E46B1F;
  /* v4: fills, borders and structural frames only. Never text — #4E7C9B on
     #080a0f measures ~4.4:1, which clears the 3:1 non-text threshold but not
     the 4.5:1 text one. Blue text uses --color-secondary-text, per theme. */
  --color-secondary:   #4E7C9B;
  --color-accent-hover:#c9541a;   /* primary button hover */
  --color-on-accent:   #1A1A1A;   /* text on orange fills — ~5.3:1, both themes */
  --danger:            #ef4444;
  --success:           #22c55e;
  --warning:           #f59e0b;
  /* v4 type stack. --font-family is the v3 name, kept so pages not yet migrated
     keep rendering; new work uses --font-sans / --font-serif. */
  --font-sans:         "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  --font-serif:        "Source Serif 4", Georgia, "Times New Roman", serif;
  --font-family:       var(--font-sans);
  --color-danger-text: #ffb3b3;
  --color-danger-bg:   #4a1f1f;
  --color-danger-dark: #8b3434;
  --color-info:        #60a5fa;
  --color-info-light:  #93c5fd;
  --color-info-bright: #5bbcff;
  --color-info-soft:   #7eb3e0;
  --color-success-text:#bbf7d0;
  --color-success-bg:  #3a5a3a;
  --color-internal:    #e5a04b;
  --danger-soft:       rgba(255, 92, 92, 0.12);
  --color-white:       #ffffff;
  --color-secondary-bg:       rgba(78,124,155,0.12);
  --color-secondary-bg-hover: rgba(78,124,155,0.22);
  --color-secondary-border:   rgba(78,124,155,0.25);
  --color-secondary-shadow:   rgba(78,124,155,0.15);
  --color-accent-bg-subtle:   rgba(228,107,31,0.08);

  /* NEX-225 extended tokens — semantic tints (same in both themes) */
  --color-blue-tint-5:        rgba(74,142,207,0.05);
  --color-blue-tint-10:       rgba(74,142,207,0.10);
  --color-blue-tint-18:       rgba(74,142,207,0.18);
  --color-blue-tint-20:       rgba(74,142,207,0.20);
  --color-blue-tint-25:       rgba(74,142,207,0.25);
  --color-blue-tint-35:       rgba(74,142,207,0.35);
  --color-blue-tint-45:       rgba(74,142,207,0.45);
  --color-info-border-50:     rgba(91,188,255,0.5);
  --color-info-border-60:     rgba(91,188,255,0.6);
  --color-steel-tint-6:       rgba(70,130,180,0.06);
  --color-steel-border-20:    rgba(70,130,180,0.2);
  --color-steel-border-60:    rgba(70,130,180,0.6);
  --color-info-tint-12:       rgba(96,165,250,0.12);
  --color-accent-tint-18:     rgba(249,115,22,0.18);
  --color-accent-tint-25:     rgba(249,115,22,0.25);
  --color-accent-border-32:   rgba(249,115,22,0.32);
  --color-accent-border-45:   rgba(249,115,22,0.45);
  --color-accent-border-50:   rgba(249,115,22,0.50);
  --color-danger-tint-15:     rgba(255,92,92,0.15);
  --color-danger-tint-20:     rgba(255,92,92,0.20);
  --color-danger-border-30:   rgba(255,92,92,0.3);
  --color-danger-border-50:   rgba(255,92,92,0.5);
  --color-danger-border-60:   rgba(255,92,92,0.6);
  --color-danger-border-70:   rgba(255,92,92,0.7);
  --color-red400-tint-8:      rgba(248,113,113,0.08);
  --color-red400-tint-10:     rgba(248,113,113,0.1);
  --color-red400-tint-12:     rgba(248,113,113,0.12);
  --color-red400-border-40:   rgba(248,113,113,0.4);
  --color-red-error-border-40: rgba(249,115,115,0.4);
  --color-success-tint-10:    rgba(70,196,111,0.1);
  --color-success-tint-12:    rgba(70,196,111,0.12);
  --color-success-tint-15:    rgba(70,196,111,0.15);
  --color-success-tint-20:    rgba(70,196,111,0.2);
  --color-success-border-40:  rgba(70,196,111,0.4);
  --color-success-border-50:  rgba(70,196,111,0.5);
  --color-success-border-60:  rgba(70,196,111,0.6);
  --color-green-tint-8:       rgba(34,197,94,0.08);
  --color-green-tint-10:      rgba(34,197,94,0.1);
  --color-green-tint-12:      rgba(34,197,94,0.12);
  --color-green-tint-15:      rgba(34,197,94,0.15);
  --color-green-border-50:    rgba(34,197,94,0.5);
  --color-green-light-tint-12:    rgba(74,222,128,0.12);
  --color-green-light-border-40:  rgba(74,222,128,0.4);
  --color-warning-tint-12:    rgba(245,158,11,0.12);
  --color-warning-tint-15:    rgba(245,158,11,0.15);
  --color-warning-border-30:  rgba(245,158,11,0.3);
  --color-warning-bright-border-40: rgba(251,191,36,0.4);
  --color-gray-tint-15:       rgba(107,114,128,0.15);
  --color-muted-tint-8:       rgba(150,160,181,0.08);
  --color-muted-border-60:    rgba(150,160,181,0.6);
}

/* ─── Dark theme (default) ─────────────────────────────────── */
[data-theme="dark"] {
  --color-bg:                  #080a0f;
  --color-panel:               #0d0f16;
  --color-text:                #e8eaf0;
  /* v4: serif strokes are thinner than Inter and lose apparent weight on dark. */
  --color-text-serif:          #dfe2ea;
  /* v4: the text-weight tint of the brand blue. ~8.6:1 here. Theme-dependent —
     this value measures ~2.3:1 on white, so light theme carries a darker one. */
  --color-secondary-text:      #7FB0D4;
  --color-muted:               #9ca3af;
  --color-placeholder:         #9ca3af;
  --color-border:              #1a1d24;
  --color-border-hover:        #2a2d35;
  --color-accent-bg:           rgba(228,107,31,0.12);
  --color-accent-border:       rgba(228,107,31,0.35);
  --color-border-dark-surface: rgba(255,255,255,0.25);
  --color-emphasis:            var(--color-accent);
  --color-nav-bg:              var(--color-panel);

  /* NEX-225 extended tokens */
  --color-glass-3:        rgba(255,255,255,0.03);
  --color-glass-4:        rgba(255,255,255,0.04);
  --color-glass-6:        rgba(255,255,255,0.06);
  --color-glass-7:        rgba(255,255,255,0.07);
  --color-glass-8:        rgba(255,255,255,0.08);
  --color-glass-10:       rgba(255,255,255,0.10);
  --color-glass-12:       rgba(255,255,255,0.12);
  --color-glass-15:       rgba(255,255,255,0.15);
  --color-glass-20:       rgba(255,255,255,0.20);
  --color-surface-raised:     rgba(10,12,18,0.95);
  --color-surface-sunken:     rgba(10,12,18,0.7);
  --color-surface-inset:      rgba(15,17,21,0.9);
  --color-surface-inset-soft: rgba(15,17,21,0.6);
  --color-surface-sticky:     rgba(13,15,19,0.95);
  --color-thead-bg:           rgba(21,25,34,0.9);
  --color-row-hover:          rgba(40,46,66,0.5);
  --color-row-alt:            rgba(21,25,34,0.6);
  --color-divider-subtle:     rgba(50,56,76,0.85);
  --color-overlay:        rgba(0,0,0,0.65);
  --color-overlay-heavy:  rgba(0,0,0,0.7);
  --color-overlay-medium: rgba(0,0,0,0.6);
  --color-shadow-lg:      rgba(0,0,0,0.7);
  --color-shadow-md:      rgba(0,0,0,0.65);
  --color-shadow-sm:      rgba(0,0,0,0.5);
  --color-input-well:     rgba(0,0,0,0.3);
}

/* ─── Light theme ──────────────────────────────────────────── */
[data-theme="light"] {
  --color-bg:                  #FFFFFF;
  --color-panel:               #FFFFFF;
  --color-text:                #000000;
  --color-text-serif:          #000000;   /* no compensation needed on white */
  --color-secondary-text:      #446E8A;   /* ~5.5:1 on white */
  --color-muted:               #6B7280;
  --color-placeholder:         #6B7280;
  --color-border:              #E5E5E5;
  --color-border-hover:        #000000;
  --color-accent-bg:           rgba(228,107,31,0.08);
  --color-accent-border:       rgba(228,107,31,0.25);
  --color-border-dark-surface: rgba(255,255,255,0.25);
  /* v4: --color-emphasis is consumed as a `color:` on detail-page section
     headers, so it must resolve to a text-safe blue. The fill blue measures
     ~4.49:1 on white — a marginal fail at the 20px/600 those headers use. */
  --color-emphasis:            var(--color-secondary-text);
  --color-nav-bg:              #F9FAFB;

  /* NEX-225 extended tokens */
  --color-glass-3:        rgba(0,0,0,0.03);
  --color-glass-4:        rgba(0,0,0,0.04);
  --color-glass-6:        rgba(0,0,0,0.06);
  --color-glass-7:        rgba(0,0,0,0.07);
  --color-glass-8:        rgba(0,0,0,0.08);
  --color-glass-10:       rgba(0,0,0,0.10);
  --color-glass-12:       rgba(0,0,0,0.12);
  --color-glass-15:       rgba(0,0,0,0.15);
  --color-glass-20:       rgba(0,0,0,0.20);
  --color-surface-raised:     #ffffff;
  --color-surface-sunken:     rgba(0,0,0,0.02);
  --color-surface-inset:      rgba(0,0,0,0.02);
  --color-surface-inset-soft: rgba(0,0,0,0.015);
  --color-surface-sticky:     rgba(255,255,255,0.95);
  --color-thead-bg:           rgba(0,0,0,0.03);
  --color-row-hover:          rgba(0,0,0,0.04);
  --color-row-alt:            rgba(0,0,0,0.02);
  --color-divider-subtle:     rgba(0,0,0,0.1);
  --color-overlay:        rgba(0,0,0,0.45);
  --color-overlay-heavy:  rgba(0,0,0,0.5);
  --color-overlay-medium: rgba(0,0,0,0.4);
  --color-shadow-lg:      rgba(0,0,0,0.15);
  --color-shadow-md:      rgba(0,0,0,0.12);
  --color-shadow-sm:      rgba(0,0,0,0.08);
  --color-input-well:     rgba(0,0,0,0.03);

  /* NEX-235 status pill light-mode overrides */
  --color-success-text:       #15803d;
  --color-success-bg:         #dcfce7;
  --color-danger-text:        #b91c1c;
  --color-danger-bg:          #fee2e2;
  --color-info:               #2563eb;
  --color-info-light:         #1d4ed8;
  --color-internal:           #92400e;
  --warning:                  #b45309;
  --color-success-tint-10:    rgba(22,163,74,0.12);
  --color-success-tint-12:    rgba(22,163,74,0.14);
  --color-success-tint-15:    rgba(22,163,74,0.18);
  --color-success-tint-20:    rgba(22,163,74,0.22);
  --color-danger-tint-15:     rgba(185,28,28,0.12);
  --color-danger-tint-20:     rgba(185,28,28,0.16);
  --color-info-tint-12:       rgba(29,78,216,0.10);
  --color-warning-tint-12:    rgba(217,119,6,0.12);
  --color-warning-tint-15:    rgba(217,119,6,0.16);
  --color-green-light-tint-12:    rgba(22,163,74,0.12);
  --color-gray-tint-15:       rgba(75,85,99,0.12);
}

/* ─── Light-mode section header accent bar ─────────────────── */
[data-theme="light"] .section-title--accent {
  border-left: 3px solid var(--color-accent);
  padding-left: 10px;
}

/* ─── Base styles ──────────────────────────────────────────── */
*, *::before, *::after {
  box-sizing: border-box;
}

body {
  background-color: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-family);
  margin: 0;
}

/* ─── NEX-557: checkboxes are brand-coloured, everywhere ─────
   This was set per page, so it drifted: nine pages named the accent, the
   members page named --color-info-bright, and four pages (billing-manage,
   buyer-rfq-new, company-setup, supplier-rfq — thirteen boxes between them)
   set nothing at all and got the browser's own blue.

   One rule instead, on the element rather than on a class, so a checkbox a
   page renders later through innerHTML is covered too and nobody has to
   remember. `input[type="checkbox"]` is (0,0,1,1), which outranks a bare
   class — the page-level declarations that agree with it are redundant rather
   than load-bearing.

   Radios are deliberately not included: the only ones in the app are the
   visually-replaced segmented control on request-access.html, where a native
   accent is not what is drawn. */
input[type="checkbox"] {
  accent-color: var(--color-accent);
}

/* ─── NEX-334: brand mark ───────────────────────────────────
   An SVG `fill` attribute cannot reference a custom property, so the lockup's
   paths take `currentColor` and the value arrives through inheritance instead.
   The mark is two colors in one SVG: accent is the default for the element,
   and the frame paths carry a class that overrides it for their subtree.
   Set `color` — never `fill` — on anything wrapping this. */
.nex-logo {
  color: var(--color-accent);
}
.nex-logo .nex-logo-frame {
  color: var(--color-secondary);
}

/* ─── NEX-202: inline contextual hints ──────────────────────
   A "?" affordance next to a label that reveals a short tooltip on hover
   or keyboard focus. CSS-only — no library, no JS, no positioning logic.

   Markup:
     <span class="nex-hint" tabindex="0" role="note"
           aria-label="Full tooltip text repeated for screen readers">?
       <span class="nex-hint-bubble">Tooltip copy.</span>
     </span>

   The bubble is inert to pointer events so it can never swallow a click on
   whatever sits underneath it. */
.nex-hint {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  margin-left: 6px;
  border: 1px solid var(--color-muted);
  border-radius: 50%;
  color: var(--color-muted);
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
  cursor: help;
  position: relative;
  vertical-align: middle;
  user-select: none;
  transition: color 0.15s ease, border-color 0.15s ease;
  flex: 0 0 auto;
}
.nex-hint:hover,
.nex-hint:focus-visible {
  color: var(--color-text);
  border-color: var(--color-text);
}
.nex-hint:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.nex-hint-bubble {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  width: max-content;
  max-width: 260px;
  padding: 9px 11px;
  border: 1px solid var(--color-border);
  border-radius: 7px;
  /* --color-panel is opaque in both themes; a translucent surface token would
     let the underlying text bleed through the tooltip. */
  background: var(--color-panel);
  color: var(--color-text);
  font-size: 12.5px;
  font-weight: 400;
  line-height: 1.5;
  text-align: left;
  letter-spacing: normal;
  text-transform: none;
  white-space: normal;
  box-shadow: 0 6px 20px rgba(0,0,0,0.28);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.14s ease, visibility 0.14s ease;
  pointer-events: none;
  z-index: 60;
}
.nex-hint:hover .nex-hint-bubble,
.nex-hint:focus-visible .nex-hint-bubble,
.nex-hint:focus .nex-hint-bubble {
  opacity: 1;
  visibility: visible;
}

/* Near the viewport edge the centered bubble would clip; these modifiers pin
   it to one side instead. */
.nex-hint--left .nex-hint-bubble { left: auto; right: -4px; transform: none; }
.nex-hint--right .nex-hint-bubble { left: -4px; transform: none; }

/* NEX-611: the bubble opens upward, which silently fails for any hint near the
   top of the page — there is nowhere above it to open into. Measured on
   buyer-rfq.html, where the status hint sits 26px from the top of the
   document: the bubble landed at y=-94, so all but its last 19px was above the
   viewport and it read as simply not appearing. supplier-quotes.html had the
   same thing at y=-91. This modifier opens it downward instead. It is a
   modifier rather than the default because every other hint on these pages has
   room above and reads better opening up, next to what it explains. */
.nex-hint--below .nex-hint-bubble { bottom: auto; top: calc(100% + 8px); }

/* On touch, hover never fires and a 260px bubble crowds a phone. Focus (tap)
   still reveals it, full width of the small screen. */
@media (max-width: 640px) {
  .nex-hint-bubble { max-width: 210px; font-size: 12px; }

  /* NEX-611: --left and --right are chosen for where the anchor sits on a wide
     screen, and the layouts stack at these widths and move it. buyer-rfq's
     status hint is --left because it is at the right edge of the desktop
     header; on a 390px viewport that header stacks, the hint lands at x=116,
     and a bubble pinned by its right edge ran off the left of the screen.
     Below 640px no anchor is near an edge on any of these pages — measured
     centres are 124, 179, 207, 213 and 260 of 390 — so the modifiers are
     dropped here and every bubble is centred on its anchor, which is the one
     placement that fits all five. The cap is what keeps it that way: at 210px
     a bubble centred anywhere from 105 to 285 stays on screen. */
  .nex-hint--left .nex-hint-bubble,
  .nex-hint--right .nex-hint-bubble {
    left: 50%;
    right: auto;
    transform: translateX(-50%);
  }
  .nex-hint-bubble { max-width: min(210px, calc(100vw - 32px)); }
}

/* ─── NEX-643: clickable help tips ──────────────────────────
   The NEX-202 hint above shows text on hover and can't hold a link, because
   its bubble ignores the pointer so it never swallows a click underneath.
   This one is a button: select it and a small panel opens with a sentence
   and a "Read more" link to the matching answer in the members' Help.
   Opening, closing, Escape and edge-clamping live in _nav-unified.js, which
   every app page loads.

   Markup:
     <span class="nex-tip">
       <button type="button" class="nex-tip-btn" aria-expanded="false"
               aria-controls="tip-x" aria-label="Help: topic">?</button>
       <span class="nex-tip-pop" id="tip-x" role="note" hidden>
         One or two sentences.
         <a href="/help/account#faq-x" target="_blank" rel="noopener">Read more in Help</a>
       </span>
     </span> */
.nex-tip { position: relative; display: inline-flex; vertical-align: middle; margin-left: 6px; }
.nex-tip-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; padding: 0; margin: 0;
  border: 1px solid var(--color-muted); border-radius: 50%;
  background: transparent; color: var(--color-muted);
  font: 700 11px/1 inherit; font-family: inherit; letter-spacing: 0; text-transform: none;
  cursor: pointer; flex: 0 0 auto;
  transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}
.nex-tip-btn:hover,
.nex-tip-btn[aria-expanded="true"] { color: var(--color-text); border-color: var(--color-text); }
.nex-tip-btn:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
/* A bigger invisible target on touch screens without changing the look. */
@media (pointer: coarse) {
  .nex-tip-btn { position: relative; }
  .nex-tip-btn::after { content: ""; position: absolute; inset: -12px; }
}
.nex-tip-pop {
  position: absolute; top: calc(100% + 8px); left: 50%; transform: translateX(-50%);
  width: max-content; max-width: min(280px, calc(100vw - 32px));
  padding: 11px 13px; border: 1px solid var(--color-border); border-radius: 8px;
  background: var(--color-panel); color: var(--color-text);
  font-size: 13px; font-weight: 400; line-height: 1.5; text-align: left;
  letter-spacing: normal; text-transform: none; white-space: normal;
  box-shadow: 0 8px 24px rgba(0,0,0,0.3); z-index: 70;
}
.nex-tip-pop[hidden] { display: none; }
.nex-tip-pop a {
  display: inline-block; margin-top: 6px; color: var(--color-accent);
  font-weight: 600; text-decoration: none;
}
.nex-tip-pop a:hover { text-decoration: underline; }
/* Headings a script rewrites keep the tip beside them rather than inside. */
.nex-title-row { display: flex; align-items: center; gap: 2px; }

/* NEX-209 — toast for optimistic actions that failed and rolled back. Global
   because the notification bell and the supplier lists raise it too, and those
   have no page-local toast styles. */
.nex-toast {
  position: fixed;
  top: 20px;
  right: 20px;
  z-index: 10000;
  max-width: min(360px, calc(100vw - 40px));
  padding: 12px 20px;
  border-radius: 10px;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.4;
  box-shadow: 0 4px 20px var(--color-shadow-sm);
  transition: opacity 0.3s ease;
}
/* Uses the -text/-bg pairs rather than the raw --success/--danger brand colors.
   The page-local .ir-toast this replaces put --danger on a 12% tint, which is
   about 3:1 in the light theme — under AA for 14px text. These pairs are the
   ones the v4 contrast pass defined for both themes. */
.nex-toast--success {
  background: var(--color-success-bg);
  border: 1px solid var(--color-success-border-60);
  color: var(--color-success-text);
}
.nex-toast--error {
  background: var(--color-danger-bg);
  border: 1px solid var(--color-danger-border-60);
  color: var(--color-danger-text);
}

@media (prefers-reduced-motion: reduce) {
  .nex-toast { transition: none; }
}

/* NEX-164 (WCAG 2.4.1 Bypass Blocks) — skip navigation link.
   Off-screen until focused, then pinned top-left. Named .skip-to-main to
   avoid colliding with user-setup.html's .skip-link ("skip this step"). */
.skip-to-main {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 1000;
  padding: 10px 16px;
  background: var(--color-accent);
  color: var(--color-on-accent);
  font-size: 14px;
  font-weight: 600;
  border-radius: 0 0 6px 0;
  text-decoration: none;
}
.skip-to-main:focus {
  left: 0;
outline: 2px solid var(--color-on-accent);
  outline-offset: -4px;
}

/* NEX-592 — the iOS zoom floor.
   Mobile Safari zooms the viewport whenever a focused text-entry control
   renders below 16px. The page is then left zoomed and off-centre until the
   user pinches back out, and it happens on every field of every form in the
   product: sign-in, request access, company setup, create RFQ, build quote.
   Chrome on Android does not do this, so it is invisible unless you test on an
   iPhone — which is how 14px inputs got everywhere.

   This lives in theme.css because it is the only stylesheet every page loads:
   four pages with forms (buyer-quote, suppliers and the two debug pages) never
   link forms.css, and a page added tomorrow gets this for free.

   The `:is(...):not(...)` chain is about specificity, not filtering. Pages
   declare their own `input, textarea, select { font-size: 14px }` inside a
   <style> block that comes after this file, so an equal-specificity rule here
   loses the cascade. :is() takes the specificity of its most specific argument
   (0-0-1) and each :not() adds a class's worth, giving 0-3-1 — above the
   page-scoped element rules and above `.form-input`, without !important.

   Checkbox, radio and range carry no text, and raising their font-size moves
   the control itself in some engines. */
@media (max-width: 768px) {
  :is(input, textarea, select):not([type="checkbox"]):not([type="radio"]):not([type="range"]) {
    font-size: 16px;
  }
}
