/* NEO platform polish — shared foundation loaded by every page, BEFORE the page's own
   styles (so page CSS always wins any conflict). Everything here is additive stability/
   feedback polish: no colors, layouts or business styling. */

/* ── 1. No layout jump when the scrollbar appears/disappears ──────────────────
   The classic "the window moved" jitter: content grows past the viewport, the
   scrollbar appears, and the whole page shifts ~15px left. Reserve the gutter. */
html { scrollbar-gutter: stable; }

/* Calm, thin scrollbars everywhere (page CSS may still override). */
* { scrollbar-width: thin; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb { background: rgba(107,114,128,.35); border-radius: 8px; border: 2px solid transparent; background-clip: content-box; }
*::-webkit-scrollbar-thumb:hover { background-color: rgba(107,114,128,.55); }
*::-webkit-scrollbar-track { background: transparent; }

/* ── 2. Type rendering ──────────────────────────────────────────────────────── */
body { -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }

/* ── 3. Buttons: instant, consistent press feedback; no mobile tap jitter ───── */
button, .btn, [role="button"], input[type="submit"], input[type="button"] {
  touch-action: manipulation;              /* kills double-tap zoom + 300ms delay */
  -webkit-tap-highlight-color: transparent;
  user-select: none;
}
button:active:not(:disabled), .btn:active, [role="button"]:active { transform: translateY(1px); }

/* Keyboard focus is visible; mouse clicks don't leave outlines behind. */
:focus-visible { outline: 2px solid var(--accent, #d4a017); outline-offset: 1px; }
button:focus:not(:focus-visible), .btn:focus:not(:focus-visible) { outline: none; }

/* ── 4. Busy state (opt-in via window.withBusy or .neo-busy) ────────────────── */
.neo-busy { pointer-events: none !important; opacity: .55; position: relative; }
.neo-busy::after {
  content: ""; position: absolute; inset: 0; margin: auto; width: 14px; height: 14px;
  border: 2px solid rgba(0,0,0,.25); border-top-color: rgba(0,0,0,.7);
  border-radius: 50%; animation: neo-spin .7s linear infinite;
}
@keyframes neo-spin { to { transform: rotate(360deg); } }

/* ── 5. Toasts (replace blocking alert() popups) ────────────────────────────── */
#neo-toasts {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  z-index: 2147483000; display: flex; flex-direction: column; align-items: center;
  gap: 8px; pointer-events: none; width: max-content; max-width: min(92vw, 620px);
}
.neo-toast {
  pointer-events: auto; cursor: pointer;
  background: rgba(26,29,38,.95); color: #fff;
  border-radius: 10px; padding: 10px 16px 10px 14px;
  font: 500 13.5px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  box-shadow: 0 8px 28px rgba(0,0,0,.24), 0 2px 8px rgba(0,0,0,.16);
  border-left: 3px solid var(--text3, #9ca3af);
  max-width: 100%; overflow-wrap: break-word; white-space: pre-line;
  animation: neo-toast-in .22s cubic-bezier(.21,1.02,.55,1) both;
  transition: opacity .25s ease, transform .25s ease;
}
.neo-toast.ok   { border-left-color: var(--green, #16a34a); }
.neo-toast.err  { border-left-color: var(--red, #dc2626); }
.neo-toast.info { border-left-color: var(--accent, #d4a017); }
.neo-toast.hide { opacity: 0; transform: translateY(6px); }
@keyframes neo-toast-in { from { opacity: 0; transform: translateY(10px); } }

/* ── 6. Skeleton shimmer for async placeholders (opt-in: .neo-skel) ─────────── */
.neo-skel {
  position: relative; overflow: hidden; background: var(--surface2, #f0f1f5);
  border-radius: 6px; color: transparent !important; min-height: 1em;
}
.neo-skel::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.55), transparent);
  animation: neo-shimmer 1.4s ease-in-out infinite;
}
@keyframes neo-shimmer { from { transform: translateX(-100%); } to { transform: translateX(100%); } }

/* ── 7. Seamless page-to-page navigation (no white flash between screens) ─────
   Browsers that support cross-document view transitions get a quick crossfade;
   everyone else keeps the normal navigation. Zero JS, zero risk. */
@view-transition { navigation: auto; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: .16s; }

/* ── 8. Accessibility: honor reduced-motion for OUR animations only ─────────── */
@media (prefers-reduced-motion: reduce) {
  .neo-toast { animation: none; }
  .neo-skel::after { animation: none; }
  button:active:not(:disabled), .btn:active, [role="button"]:active { transform: none; }
  ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
}

/* ── 8. Feedback card (temporary broker feedback prompt, see neo-polish.js) ───
   Deliberately NOT a modal: no overlay, no trap, nothing behind it is blocked.
   Sits bottom-LEFT because bottom-right belongs to the Gemini FAB. */
#neo-fb {
  position: fixed; left: 20px; z-index: 2147482900;
  bottom: calc(20px + env(safe-area-inset-bottom, 0px));
  width: 322px; max-width: calc(100vw - 40px);
  background: var(--surface, #fff); color: var(--text, #1a1d26);
  border: 1px solid var(--border, #e2e4eb); border-radius: 14px;
  box-shadow: 0 14px 44px rgba(0,0,0,.15), 0 2px 8px rgba(0,0,0,.06);
  padding: 15px 16px 14px;
  font: 400 13.5px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, sans-serif;
  animation: neo-fb-in .3s cubic-bezier(.21,1.02,.55,1) both;
  transition: opacity .28s ease, transform .28s ease;
}
#neo-fb.hide { opacity: 0; transform: translateY(8px); }
@keyframes neo-fb-in { from { opacity: 0; transform: translateY(14px); } }
.neo-fb-t { font-size: 13.5px; font-weight: 700; padding-right: 20px; }
.neo-fb-s { font-size: 12.5px; color: var(--text2, #6b7280); margin-top: 2px; }
/* Close is always visible, never hover-only (self-evident UI). */
.neo-fb-x {
  position: absolute; top: 9px; right: 9px; width: 24px; height: 24px;
  border: 0; border-radius: 7px; background: transparent; cursor: pointer;
  color: var(--text3, #9ca3af); font-size: 15px; line-height: 1;
}
.neo-fb-x:hover { background: var(--surface2, #f0f1f5); color: var(--text2, #6b7280); }
/* The faces: real buttons with resting chrome, so they read as clickable. */
.neo-fb-faces { display: grid; grid-template-columns: repeat(4, 1fr); gap: 7px; margin-top: 12px; }
.neo-fb-face {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 8px 0 6px; cursor: pointer;
  background: var(--surface2, #f0f1f5);
  border: 1px solid var(--border, #e2e4eb); border-radius: 10px;
  font: 600 9.5px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  color: var(--text2, #6b7280); letter-spacing: .02em;
  transition: background .15s ease, border-color .15s ease, transform .12s ease;
}
.neo-fb-face i { font-style: normal; font-size: 20px; line-height: 1; }
.neo-fb-face:hover {
  background: var(--accent-light, rgba(212,160,23,.08));
  border-color: var(--accent, #d4a017); color: var(--text, #1a1d26);
  transform: translateY(-1px);
}
.neo-fb-face:active { transform: translateY(0); }
.neo-fb-face.on { background: var(--accent-light, rgba(212,160,23,.08)); border-color: var(--accent, #d4a017); }
.neo-fb-note {
  width: 100%; margin-top: 11px; padding: 8px 10px; resize: none;
  border: 1px solid var(--border, #e2e4eb); border-radius: 9px;
  background: var(--surface, #fff); color: var(--text, #1a1d26);
  font: 400 13px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
.neo-fb-note:focus { outline: 0; border-color: var(--accent, #d4a017); box-shadow: 0 0 0 3px var(--accent-light, rgba(212,160,23,.08)); }
.neo-fb-foot { display: flex; justify-content: flex-end; gap: 8px; margin-top: 10px; }
.neo-fb-b {
  padding: 7px 13px; border-radius: 8px; cursor: pointer;
  border: 1px solid var(--border, #e2e4eb); background: var(--surface, #fff);
  color: var(--text2, #6b7280);
  font: 600 12.5px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
.neo-fb-b:hover { background: var(--surface2, #f0f1f5); }
.neo-fb-b.p { background: var(--accent, #d4a017); border-color: var(--accent, #d4a017); color: #fff; }
.neo-fb-b.p:hover { background: var(--accent2, #b8860b); }
@media (max-width: 640px) { #neo-fb { left: 12px; right: 12px; width: auto; } }
@media (prefers-reduced-motion: reduce) {
  #neo-fb { animation: none; }
  .neo-fb-face:hover { transform: none; }
}

/* ── 9. Dark theme (owner-sanctioned 2026-08-03; LIGHT stays the default) ─────
   Opt-in per device via the header moon button (localStorage neo.theme). The
   whole fleet speaks one token vocabulary, so the theme is a token flip:
   :root[data-theme] outranks every page's own :root block on specificity.
   Deep ink (never pure black), gold slightly lifted so it keeps its glow,
   status hues brightened for contrast on dark grounds. */
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg:#0e1015; --surface:#161a22; --surface2:#1e232d; --border:#2b313d;
  --text:#e8eaf0; --text2:#a2a9b6; --text3:#727b8a;
  --accent:#deb345; --accent2:#ecc55c; --accent-light:rgba(222,179,69,.13);
  --green:#3ecf6e; --green-bg:rgba(62,207,110,.13);
  --red:#f47171; --red-bg:rgba(244,113,113,.13);
  --yellow:#e7bd44; --yellow-bg:rgba(231,189,68,.14);
  --blue:#639df6; --blue-bg:rgba(99,157,246,.14);
  --purple:#a78bfa; --teal:#2dd4bf;
  --shadow-sm:0 1px 2px rgba(0,0,0,.55);
  --shadow-md:0 4px 16px rgba(0,0,0,.5);
  --shadow-lg:0 14px 44px rgba(0,0,0,.6);
}
:root[data-theme="dark"] body { background: var(--bg); color: var(--text); }

/* Pages hardcode a handful of light literals — neutralize the common ones. */
:root[data-theme="dark"] tbody tr:nth-child(even) td,
:root[data-theme="dark"] tbody tr:nth-child(even) { background: rgba(255,255,255,.025) !important; }
:root[data-theme="dark"] ::placeholder { color: var(--text3); }
:root[data-theme="dark"] *::-webkit-scrollbar-thumb {
  background: rgba(148,163,184,.32); background-clip: content-box; }

/* The NOUR brand logo has a true dark variant (silver lettering, same golden
   sun) — neo-polish.js swaps /static/logo.png ↔ /static/logo-dark.png with the
   theme, so it never needs a chip. THIRD-PARTY marks (carriers, Applied) are
   drawn for light paper and are never recolored; those sit on a soft light
   chip — the difference between "dark theme" and "someone inverted my page". */
:root[data-theme="dark"] img[src*="/static/carriers/"],
:root[data-theme="dark"] img[src*="applied_logo"] {
  background:#f7f8fa; border-radius:9px; padding:3px 7px;
  box-shadow: 0 0 0 1px rgba(255,255,255,.07);
}
:root[data-theme="dark"] img[src*="ringcentral"] { background:#f7f8fa; border-radius:6px; padding:2px; }

/* The busy spinner was ink-on-light; flip its strokes. */
:root[data-theme="dark"] .neo-busy::after {
  border-color: rgba(255,255,255,.25); border-top-color: rgba(255,255,255,.8); }

/* Theme toggle (injected by neo-polish.js): lives in the sidebar next to the
   sign-out button when the page has one, else in the page header. */
#neo-theme-btn {
  border:1px solid var(--border,#e2e4eb); background:var(--surface,#fff);
  border-radius:999px; width:34px; height:34px; font-size:15px; cursor:pointer;
  display:inline-flex; align-items:center; justify-content:center; flex:0 0 auto;
  transition: border-color .12s, transform .12s; margin-left:10px;
}
#neo-theme-btn:hover { border-color: var(--accent,#d4a017); transform: translateY(-1px); }
#neo-theme-btn.side-icon-btn {
  border-radius:8px; margin-left:0; background:transparent; font-size:14.5px;
}
#neo-theme-btn.side-icon-btn:hover { transform:none; background:var(--surface2,#f0f1f5); }

/* ── Seasonal event layer (owner 2026-08-30): Fêtes (Dec 1 - Jan 2) and
   Halloween (Oct 24 - Nov 1). Never a re-skin: the palette and layout stay
   exactly as they are; this is a fine string of lights along the top plus a
   few quiet touches. Injected by neo-polish.js when the date arrives;
   ?season=christmas|halloween|off previews it; the × hides it for the
   season on this device. aria-hidden, pointer-events none (except × and the
   spider), z-index under every dialog. ── */
#neo-season { position: fixed; inset: 0; pointer-events: none; z-index: 850; overflow: hidden; }
#neo-season .season-wire { position: absolute; top: 0; left: 0; right: 0; height: 26px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='138' height='18' viewBox='0 0 138 18'%3E%3Cpath d='M0 2 Q 34.5 14 69 2 T 138 2' fill='none' stroke='%2300000024' stroke-width='1.4'/%3E%3C/svg%3E") repeat-x top left; }
:root[data-theme="dark"] #neo-season .season-wire {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='138' height='18' viewBox='0 0 138 18'%3E%3Cpath d='M0 2 Q 34.5 14 69 2 T 138 2' fill='none' stroke='%23ffffff2e' stroke-width='1.4'/%3E%3C/svg%3E"); }
#neo-season .season-light { position: absolute; width: 7px; height: 7px; border-radius: 50%;
  background: currentColor; box-shadow: 0 0 7px 1px currentColor; opacity: .55;
  animation: neo-twinkle 2.6s ease-in-out infinite; }
#neo-season .season-light.c0 { color: #e2ae39; }
#neo-season .season-light.c1 { color: #dd5f5f; }
#neo-season .season-light.c2 { color: #4aa96c; }
#neo-season .season-light.h0 { color: #f29a3a; }
#neo-season .season-light.h1 { color: #a96fd6; }
@keyframes neo-twinkle { 0%, 100% { opacity: .45; } 50% { opacity: 1; } }
#neo-season .season-x { position: absolute; top: 20px; right: 12px; pointer-events: auto;
  width: 22px; height: 22px; border-radius: 50%; border: 1px solid var(--border, #e2e4eb);
  background: var(--surface, #fff); color: var(--text3, #9ca3af); font-size: 14px; line-height: 1;
  cursor: pointer; opacity: 0; transition: opacity .2s; padding: 0; }
#neo-season:hover .season-x, #neo-season .season-x:focus-visible { opacity: .85; }
/* snow: a dozen slow flakes, pale in light, bright in dark */
#neo-season { --season-flake: #9fb2cc; }
:root[data-theme="dark"] #neo-season { --season-flake: rgba(235, 241, 252, .85); }
#neo-season .season-flake { position: absolute; top: -32px; animation: neo-fall linear infinite; }
#neo-season .season-flake b { display: block; font-style: normal; font-weight: 400;
  color: var(--season-flake); opacity: .5; animation: neo-sway ease-in-out infinite alternate; }
@keyframes neo-fall { to { transform: translateY(108vh); } }
@keyframes neo-sway { from { transform: translateX(-16px) rotate(-14deg); }
  to { transform: translateX(16px) rotate(14deg); } }
/* halloween: one bat gliding across the top about once a minute... */
#neo-season .season-bat { position: absolute; top: 30px; left: 0; width: 40px; color: rgba(63, 48, 90, .4);
  animation: neo-bat 62s linear infinite; }
:root[data-theme="dark"] #neo-season .season-bat { color: rgba(206, 195, 235, .38); }
@keyframes neo-bat {
  0%   { transform: translate(-9vw, 24px); }
  3%   { transform: translate(11vw, 2px); }
  6%   { transform: translate(31vw, 30px); }
  9%   { transform: translate(57vw, 6px); }
  12%  { transform: translate(83vw, 26px); }
  14%  { transform: translate(108vw, 0); }
  14.1%, 100% { transform: translate(120vw, 0); }
}
/* ...and a little spider that lowers itself once, then naps. Hover: it climbs. */
#neo-season .season-spider { position: absolute; top: 18px; right: 7vw; width: 22px;
  color: rgba(50, 44, 62, .55); transform: translateY(-120px);
  animation: neo-spider 6.5s cubic-bezier(.3,.8,.4,1) 1.2s forwards; transition: transform 1.4s ease; }
:root[data-theme="dark"] #neo-season .season-spider { color: rgba(215, 208, 232, .5); }
#neo-season .season-spider .thread { display: block; width: 1px; height: 84px; margin: 0 auto 1px;
  background: linear-gradient(180deg, transparent, currentColor); opacity: .5; }
#neo-season .season-spider svg { display: block; width: 22px; height: 19px; }
#neo-season .season-spider:hover { transform: translateY(-74px) !important; }
@keyframes neo-spider { 0% { transform: translateY(-120px); } 74% { transform: translateY(7px); }
  87% { transform: translateY(-5px); } 100% { transform: translateY(0); } }
@media (prefers-reduced-motion: reduce) {
  #neo-season .season-light, #neo-season .season-flake, #neo-season .season-flake b { animation: none; }
  #neo-season .season-flake, #neo-season .season-bat { display: none; }
  #neo-season .season-spider { animation: none; transform: translateY(0); }
}

/* ── Copy icon (Google Cloud idiom, owner 2026-09-08) ───────────────────────
   A quiet two-rectangle button next to a value; only a click on it copies.
   .inline sits after <code>/[data-copy] values and beside the values a
   page chooses (the client file). */
.neo-cp {
  display: inline-flex; align-items: center; justify-content: center;
  /* min-height: mobile.css gives every <button> 44px on phones; this icon stays 22px
     (2026-09-18: the client file's copy icons stood 44px tall on phones). */
  width: 22px; height: 22px; min-height: 0; padding: 0; margin: 0; border: 0; border-radius: 6px;
  background: transparent; color: var(--text3, #9ca3af); cursor: pointer;
  vertical-align: middle; line-height: 0; flex: 0 0 auto; font: inherit;
  transition: color .12s ease, background .12s ease, opacity .12s ease;
}
.neo-cp svg { width: 14px; height: 14px; display: block; }
.neo-cp.inline { margin-left: 4px; }
.neo-cp:hover, .neo-cp:focus-visible { color: var(--text, #1a1d26); background: var(--surface2, #f0f1f5); }
.neo-cp.done, .neo-cp.done:hover { color: var(--green, #16a34a); background: transparent; }
.btn .neo-cp-ico, .neo-cp-ico { width: 14px; height: 14px; vertical-align: -2px; }
@media (prefers-reduced-motion: reduce) { .neo-cp { transition: none; } }

/* The top bar (logo + NEO) stays in view while scrolling (owner 2026-09-25): every
   NEO page has its own .header straight under <body>. z-index 40 keeps it under
   the overlays (Ctrl+K 50, sidebar 60/61); --neo-hdr (set by neo-polish.js) lets
   page-level sticky strips and scroll-into-view land below it. */
body > .header { position: sticky; top: 0; z-index: 40; }
html { scroll-padding-top: calc(var(--neo-hdr, 0px) + 8px); }
@media print { body > .header { position: static; } }
