/* console_shell.css — the staff shell's GLOBAL layer, and deliberately nothing else.
 *
 * The staff console single-origin shell ADR keeps each surface's chrome copied rather
 * than extracted (the copied-chrome decision, analysis console support-parity rebuild
 * ADR, Decision 5, left standing by the shell ADR's Decision 6). So this file is NOT a
 * shared design system that surfaces inherit from — it holds only what genuinely belongs
 * to the document rather than to any surface:
 *
 *   1. The 52 design tokens BOTH surfaces already defined with IDENTICAL values. Measured,
 *      not assumed: the two :root blocks were compared property by property and zero of
 *      the 52 differed. Each surface's OWN extras (Support has 18, Analysis 3) stay on
 *      that surface's root in its own stylesheet, where they still cascade to everything
 *      it renders. Hoisting only the agreed set is what keeps this from quietly becoming
 *      the shared-shell extraction the copied-chrome decision's revisit trigger has not
 *      fired for.
 *   2. The reset, `body`, and the scrollbars — one document, so these can only be declared
 *      once.
 *   3. The boot splash and the login overlay. These are the SHELL's, not a surface's,
 *      because they are exactly what is on screen when NO surface is mounted.
 *   4. The two @keyframes both surfaces declared identically. See the warning below.
 *
 * ⚠ @keyframes IS A GLOBAL NAMESPACE AND SURFACE SCOPING CANNOT PROTECT IT. The scoped
 * surface stylesheet decision (shell ADR, Decision 13) makes every SELECTOR safe by
 * emitting it under `[data-surface="…"]`, and that genuinely retires the two measured
 * conflicts and every future one. It does nothing for animation names: an @keyframes
 * declared inside a scoped block still registers globally, so two surfaces declaring
 * `ff-bob` differently is a silent last-one-wins that no wrapper prevents. Today both
 * surfaces declare `boot-spin` and `ff-bob` with byte-identical bodies — harmless, and
 * exactly the state that drifts unnoticed. They are hoisted HERE so there is one copy;
 * surface-unique names (`ff-pulse`, `anchflash`) stay with their surface, where they
 * cannot collide with anything.
 */

:root {
  /* ============ Flexfilm Design System — the agreed subset ============
     Ported from the claude.ai/design "Flexfilm Console" export. Flex Blue on ink +
     warm-paper panes; Quantico for labels, Open Sans for body. */
  /* Flex Blue scale (sampled from the logo globe) */
  --flex-blue-50:#e6f4fb; --flex-blue-100:#c3e4f5; --flex-blue-200:#8dcdee;
  --flex-blue-300:#4fb4e4; --flex-blue-400:#1fa2dc; --flex-blue-500:#009fda;
  --flex-blue-600:#0082b3; --flex-blue-700:#006689; --flex-blue-800:#004a64;
  --flex-blue-900:#002f41;
  /* Cool slate neutrals */
  --ink-0:#ffffff; --ink-25:#f7f9fb; --ink-50:#f0f3f6; --ink-100:#e4e8ec;
  --ink-200:#cdd3d9; --ink-300:#a7b0b8; --ink-400:#7d8790; --ink-500:#5a646d;
  --ink-600:#3d454c; --ink-700:#242a2f; --ink-800:#14181b; --ink-900:#0a0c0e;
  /* Semantic accents */
  --success:#2aa462; --success-600:#238a52; --success-soft:#e8f6ee;
  --warning:#e0a100;
  --danger:#d72c2c;  --danger-soft:#fcebeb;
  --flex-blue:#009fda;
  /* Attention (amber) — "a customer is owed a reply" */
  --attn-bg:#fef5dd; --attn-fg:#8a6200; --attn-dot:#e0a100;
  /* Internal traffic (demo) — a yellow held DELIBERATELY apart from the amber attention
     family above. --attn-* means a reply is owed; this means the opposite, that nothing
     is owed because the traffic is ours. */
  --demo-bg:#ffdd57; --demo-fg:#4a3800; --demo-soft:#fff6cc; --demo-line:#f0d688;
  /* Shared height for the two single-bar column heads, so their divider lines meet
     across the column border. Measured in a browser, not derived. */
  --headbar-h:74px;
  /* Borders / shadows / motion */
  --border:var(--ink-100); --border-strong:var(--ink-200);
  --shadow-1:0 1px 2px rgba(10,12,14,.06);
  --shadow-2:0 2px 6px rgba(10,12,14,.08),0 1px 2px rgba(10,12,14,.04);
  --ease-out:cubic-bezier(.2,.8,.2,1);
  /* Fonts */
  --font-display:'Quantico','Eurostile',system-ui,sans-serif;
  --font-body:'Open Sans',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
  /* Back-compat aliases both surfaces ride on */
  --bg:var(--ink-25); --panel:var(--ink-0); --line:var(--border);
  --ink:var(--ink-900); --muted:var(--ink-400);
  --hover:var(--ink-50); --active:var(--ink-50); --sel:var(--flex-blue-50);
}

* { box-sizing: border-box; }

/* The `hidden` attribute must always win — class rules that set `display` would
   otherwise override the UA [hidden]{display:none}. JS toggles `.hidden` on these. */
[hidden] { display: none !important; }

body { margin:0; font:14px/1.55 var(--font-body); color:var(--ink-900); background:var(--ink-25);
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility; }
button { font: inherit; cursor: pointer; }
::-webkit-scrollbar { width:10px; height:10px; }
::-webkit-scrollbar-thumb { background:var(--ink-200); border-radius:99px; border:3px solid transparent; background-clip:content-box; }
::-webkit-scrollbar-thumb:hover { background:var(--ink-300); background-clip:content-box; }

/* ---- boot gate (prevents the login-overlay FOUC) ----
   The splash sits above BOTH the mounted surface and the login overlay (z-index:100) and
   shows only while <html> has `.booting`, so the wrong-surface paint→correct flip is
   hidden until /api/me decides. The shell drops `.booting` only after it has already set
   the correct state, so removing the splash reveals the final surface with no flash in
   either direction (signed-in → surface, signed-out → login). */
.boot-splash { position:fixed; inset:0; display:none; align-items:center; justify-content:center;
  background:var(--ink-25); z-index:100; }
html.booting .boot-splash { display:flex; }
.boot-spinner { width:26px; height:26px; border:3px solid var(--ink-100);
  border-top-color:var(--flex-blue-500); border-radius:50%; animation:boot-spin .7s linear infinite; }

/* ---- the two @keyframes both surfaces declared identically ----
   Hoisted so there is exactly ONE copy. See the file header: scoping a surface's rules
   does not scope its animation names, so two copies here would be a silent collision the
   moment either drifts. Surface-unique names stay in their surface stylesheet. */
@keyframes boot-spin { to { transform:rotate(360deg); } }
@keyframes ff-bob { 0%,100%{transform:translateY(0);} 50%{transform:translateY(-10px);} }

/* ---- login overlay (Polaris / Shopify-Inbox aesthetic) ----
   ONE overlay for the whole platform, which is the visible half of the one-origin,
   one-service, one-session decision (shell ADR, Decision 1): a staff member signs in
   once and every surface is already open to them. Previously each surface carried its
   own copy of this, and crossing between them could land on a second sign-in. */
.overlay { position: fixed; inset: 0; background: var(--ink-25); display: none;
  align-items: center; justify-content: center; z-index: 50; }
.overlay.on { display: flex; }
.card { background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
  padding: 28px 28px 24px; width: 340px; box-shadow: 0 16px 48px rgba(0,0,0,.18); }
.card .brand-mark { width: 40px; height: 40px; border-radius: 10px; background: var(--ink);
  color: #fff; font-weight: 700; font-size: 20px; display: flex; align-items: center;
  justify-content: center; margin-bottom: 16px; }
.card h2 { margin: 0 0 3px; font-size: 17px; font-weight: 650; color: var(--ink); }
.card p { margin: 0 0 18px; color: var(--muted); font-size: 13px; }
.card input { width: 100%; padding: 9px 12px; border: 1px solid var(--line);
  border-radius: 8px; font: inherit; color: var(--ink); background: #fff; margin-bottom: 10px; }
.card input:focus { outline: none; border-color: var(--ink); }
.card .err { color: #b91c1c; font-size: 12.5px; min-height: 17px; margin-bottom: 8px; }
.card #login-btn, .card #login-pass-btn { width: 100%; padding: 9px 16px; }
.card [hidden] { display: none !important; }
.card .ok-msg { color: #15803d; font-size: 13px; margin: 12px 0 0; }
.card .alt { margin: 14px 0 0; font-size: 12.5px; }
.card .alt a { color: var(--muted); text-decoration: underline; cursor: pointer; }
.card .alt a:hover { color: var(--ink); }
.card button.primary { background:var(--ink-900); color:#fff; border:1px solid var(--ink-900);
  border-radius:8px; padding:8px 16px; font-family:var(--font-display); font-weight:700;
  font-size:12px; letter-spacing:.06em; text-transform:uppercase; }
.card button.primary:hover { background:var(--ink-700); }
.card button:disabled { opacity: .45; cursor: default; }

/* The broken-deploy state. Lives on the shell rather than in any surface stylesheet for
   the obvious reason: it renders when a surface's own CSS is exactly what failed to load. */
.mount-error { max-width: 34rem; margin: 18vh auto; padding: 0 1.5rem; }
.mount-error h2 { font-family: var(--font-display); font-size: 19px; margin: 0 0 10px; }
.mount-error p { color: var(--muted); font-size: 13.5px; margin: 0 0 12px; line-height: 1.55; }
.mount-error .detail { font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px; color: var(--danger); word-break: break-word; }
.mount-error button.primary { background: var(--ink-900); color: #fff;
  border: 1px solid var(--ink-900); border-radius: 8px; padding: 8px 16px;
  font-family: var(--font-display); font-weight: 700; font-size: 12px;
  letter-spacing: .06em; text-transform: uppercase; }

/* The surface mount point — a plain block with NO sizing of its own, deliberately.
   Each surface's `.layout` already declares `height:100vh` and owns its own grid, so a
   height here would either duplicate that or fight it. The element exists to carry
   `data-surface`, which is what every scoped rule in a surface stylesheet hangs off. */
#surface-root:empty { display: none; }
