/* ============================================================
   SHOPNSIGN — "Trust + Torque" shared theme
   Single source of truth for color, type, and core components.
   Linked LAST in <head> on every page so it wins the cascade.
   Fonts (Space Grotesk / Inter / JetBrains Mono) are linked from
   each page <head> via Google Fonts.
   To retheme the whole app, edit the tokens in :root below.
   ============================================================ */

@import url('https://fonts.googleapis.com/css2?family=Source+Sans+3:wght@300;400;600;700&display=swap');

:root {
  /* Type roles */
  --display: 'Source Sans 3', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --body:    'Source Sans 3', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --sans:    'Source Sans 3', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono:    'JetBrains Mono', ui-monospace, 'SFMono-Regular', monospace;

  /* Brand blue (trust + selection) */
  --blue: #2563EB; --blue-dim: #2563EB; --blue-deep: #1D4ED8; --blue-soft: #60A5FA;
  --blue-bg: #EFF6FF;

  /* Ink (text + dark chrome) */
  --ink: #0F172A; --ink-soft: #1E293B;

  /* Warm accent (the one action that matters) */
  --accent: #F97316; --btn: #003B7B; --btn-deep: #00264D;

  /* Status */
  --green: #16A34A; --green-deep: #15803D; --green-bg: #EAF7EF;
  --red: #EF4444; --red-deep: #B91C1C; --red-bg: #FEF2F2;
  --amber: #F59E0B; --amber-deep: #C2410C; --amber-bg: #FEF1E7;
  --indigo: #4338CA; --indigo-bg: #EEF2FF;

  /* Neutrals */
  --surface: #FFFFFF;
  --paper: #F4F6FB; --paper-soft: #F1F5F9;
  --canvas: #F4F6FB; --bg: #F4F6FB;
  --line: #E2E8F0;
  --slate: #334155; --mist: #64748B; --muted: #64748B; --mist-soft: #94A3B8;
  --text: #0F172A;

  /* Shape */
  --radius-sm: 8px; --radius: 11px; --radius-lg: 14px; --radius-xl: 16px;
}

/* ---- Base ---- */
/* Smaller, consistent page titles (Dashboard, Workflow, New Estimate, etc.) */
.page-title, .page-title-big, .page-head h1, .page-topbar h1 { font-size: 20px !important; }
/* Reserve space for the vertical scrollbar at all times so the layout doesn't
   shift left when it appears (fixes the topbar bell/New Estimate jumping). */
html { overflow-y: scroll; scrollbar-gutter: stable; }
html, body {
  background: var(--paper) !important;
  color: var(--ink) !important;
  font-family: var(--body) !important;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4, h5, h6,
.page-title, .panel-title, .card-title, .modal-head h3,
.brand, .wordmark, .header-title__main {
  font-family: var(--display) !important;
  letter-spacing: -0.015em;
}
/* Register feel for figures + identifiers */
td.num, .num, .money, .total-amount, .opt-choice__price,
.metric .value, .stat-value, .wo, .order-num {
  font-family: var(--mono);
}

/* Light-context brand wordmark (e.g. customer-sign header): keep it dark,
   colour just the N with brand blue. The dark-sidebar version is restyled
   separately below. */
.brand span, .brand .n, .wordmark .n { color: var(--blue) !important; }

/* ---- Links ---- */
a { color: var(--blue); }

/* ---- Buttons ---- */
.btn-primary, .btn-submit, button.primary, .btn.btn-primary {
  background: var(--btn) !important;
  color: #fff !important;
  border: 0 !important;
  border-radius: var(--radius) !important;
  font-family: var(--display) !important;
  font-weight: 700 !important;
  box-shadow: none !important;
  transition: background .15s, transform .08s !important;
}
.btn-primary:hover:not(:disabled), .btn-submit:hover:not(:disabled),
button.primary:hover:not(:disabled) { background: var(--btn-deep) !important; }
.btn-primary:active:not(:disabled), .btn-submit:active:not(:disabled) { transform: translateY(1px) !important; }

/* Secondary / ghost buttons keep a quiet outline */
.btn-ghost, .btn-secondary, .panel-link-btn {
  background: #fff !important; color: var(--slate) !important;
  border: 1.5px solid var(--line) !important; border-radius: var(--radius) !important;
  font-family: var(--body) !important; font-weight: 600 !important;
}

/* ---- Form fields ---- */
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
textarea, select {
  border: 1.5px solid var(--line) !important;
  border-radius: var(--radius-sm) !important;
  font-family: var(--body) !important;
}
input:focus, textarea:focus, select:focus {
  outline: none !important;
  border-color: var(--blue) !important;
  box-shadow: 0 0 0 3px rgba(37,99,235,0.16) !important;
  background-color: #F4F8FF !important;
}

/* ---- Surfaces: cards & panels ---- */
.card, .panel, .modal-card, .stat, .channel, .link-card,
.estimate-card, .signed-card, .sig-item {
  background: var(--surface) !important;
  border: 1px solid var(--line) !important;
  border-radius: var(--radius-lg) !important;
}

/* ---- Tables ---- */
.panel-table th, .lines th, table.data th {
  font-family: var(--body) !important;
  font-weight: 600 !important; color: var(--mist) !important;
  text-transform: uppercase; letter-spacing: .04em; font-size: 11.5px;
  border-bottom: 1px solid var(--line) !important;
}
.panel-table td, .lines td { border-bottom: 1px solid var(--line) !important; color: var(--slate); }

/* ---- Status chips ---- */
.chip { display: inline-flex; align-items: center; font-family: var(--body); font-size: 12px; font-weight: 600; padding: 4px 11px; border-radius: 999px; }
.chip.sent, .chip.awaiting, .status-sent { background: var(--blue-bg) !important; color: #185FA5 !important; }
.chip.repair, .chip.in-progress, .status-progress { background: var(--amber-bg) !important; color: var(--amber-deep) !important; }
.chip.ready, .status-ready { background: var(--indigo-bg) !important; color: var(--indigo) !important; }
.chip.done, .chip.completed, .chip.signed, .status-done, .status-signed { background: var(--green-bg) !important; color: var(--green-deep) !important; }
.chip.draft, .status-draft { background: var(--paper-soft) !important; color: var(--slate) !important; }

/* ---- LIVE pill ---- */
.live-pill { background: var(--green-bg) !important; color: var(--green-deep) !important; }
.live-pill .dot { background: var(--green) !important; }

/* ============================================================
   Dark "blueprint" sidebar chrome (dashboard pages).
   Scoped under .sidebar so customer-facing pages are untouched.
   ============================================================ */
.sidebar {
  background-color: var(--ink) !important;
  background-image:
    linear-gradient(rgba(255,255,255,0.04) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,0.04) 1px, transparent 1px) !important;
  background-size: 26px 26px !important;
  border-right: 0 !important;
  color: #fff !important;
  /* Pinned: stick to the top, exactly one screen tall, so the nav stays in view
     while scrolling. The navy column behind it is painted by .app::before below,
     so there's no light gap even on pages taller than one screen. */
  height: 100vh !important;
  min-height: 100vh;
  position: sticky !important;
  top: 0 !important;
  align-self: start !important;
  z-index: 1;
}
/* Full-height navy rail behind the (pinned) sidebar so the left column is always
   navy down to the very bottom — no light gap. Width tracks the rail width at
   each breakpoint; hidden when the sidebar is hidden on phones. */
.app { position: relative; }
.app::before {
  content: ''; position: absolute; top: 0; bottom: 0; left: 0;
  width: 160px; background-color: var(--ink); z-index: 0; pointer-events: none;
}
@media (min-width: 769px) { .app::before { width: 144px; } }
@media (max-width: 720px) { .app::before { display: none; } }
/* Logo becomes a white chip so the blue mark reads on dark ink */
.sidebar .brand-logo, .sidebar .brand img, .sidebar .brand-stack img {
  background: transparent !important;
  border-radius: 11px !important;
  padding: 0 !important;
  width: 44px !important; height: 44px !important;
  object-fit: contain !important;
  box-sizing: border-box !important;
}
.sidebar .brand, .sidebar .wordmark { color: #fff !important; }
.sidebar .brand span, .sidebar .brand .n, .sidebar .wordmark .n { color: var(--blue-soft) !important; }
.sidebar .nav-section { color: #64748B !important; font-weight: 600 !important; }
.sidebar .nav-item {
  color: #CBD5E1 !important;
  font-family: var(--body) !important; font-weight: 500 !important;
  border-left: 3px solid transparent !important; border-radius: 9px !important;
}
.sidebar .nav-item svg { color: var(--mist, #64748B) !important; }
.sidebar .nav-item:hover svg { color: #fff !important; }
.sidebar .nav-item:hover { background: rgba(255,255,255,0.06) !important; color: #fff !important; }
.sidebar .nav-item.active {
  background: rgba(37,99,235,0.16) !important; color: #BFDBFE !important;
  border-left-color: var(--blue, #2563EB) !important; border-radius: 0 9px 9px 0 !important;
}
.sidebar .nav-item.active svg { color: #60A5FA !important; }
.sidebar .nav-badge, .sidebar .nav-item .pill { background: var(--accent) !important; color: #fff !important; }
.sidebar .sidebar-foot { border-top: 1px solid rgba(255,255,255,0.08) !important; }
.sidebar .avatar { background: var(--blue) !important; color: #fff !important; font-family: var(--display) !important; }
.sidebar .user-name { color: #fff !important; }
.sidebar .user-role { color: #94A3B8 !important; }
.sidebar .logout-btn { color: #94A3B8 !important; }
.sidebar .logout-btn:hover { color: #fff !important; background: rgba(255,255,255,0.06) !important; }

/* ---- Topbar ---- */
.topbar { background: var(--surface) !important; border-bottom: 1px solid var(--line) !important; }
.topbar .search input, .search-input-wrap input {
  border: 1.5px solid var(--line) !important; border-radius: var(--radius-sm) !important;
  background: var(--paper) !important; font-family: var(--body) !important;
}
.topbar .icon-btn { border: 1.5px solid var(--line) !important; border-radius: var(--radius-sm) !important; }
.icon-btn .dot { background: var(--accent) !important; }

@media (prefers-reduced-motion: reduce) {
  .btn-primary:active, .btn-submit:active { transform: none !important; }
}

/* ============================================================
   Narrower sidebar rail (desktop only). Each page collapses the
   sidebar on its own mobile breakpoint (<=768px), so this is
   scoped to >=769px to avoid fighting those rules.
   To change the rail width app-wide, edit the 144px below.
   ============================================================ */
@media (min-width: 769px) {
  .app { grid-template-columns: 144px 1fr !important; }
  .sidebar { padding-left: 9px !important; padding-right: 9px !important; }
  .sidebar .brand, .sidebar .wordmark { font-size: 18px !important; }
  .sidebar .brand-logo, .sidebar .brand img, .sidebar .brand-stack img { width: 40px !important; height: 40px !important; }
  .sidebar .nav-section { padding-left: 9px !important; padding-right: 9px !important; }
  .sidebar .nav-item { font-size: 12px !important; padding: 7px 9px !important; gap: 9px !important; }
}

/* Sidebar user name — show the full name (wrap instead of truncating) */
.user-name {
  white-space: normal !important;
  overflow: visible !important;
  text-overflow: clip !important;
  word-break: break-word;
  line-height: 1.25;
}

/* Members (staff) must not see revenue/financial figures */
.role-staff .owner-only { display: none !important; }
/* Hide the "Total" ($) column in the dashboard Workflow Status table for members */
.role-staff #workflowTable th:nth-child(3),
.role-staff #workflowTable td:nth-child(3) { display: none !important; }
/* With the two revenue panels hidden, keep the lone Workflow panel from stretching */
.role-staff .panels { grid-template-columns: minmax(0, 580px) !important; }

/* Hide owner-only nav links for members instantly (prevents flash on navigation) */
.role-staff a[href="/settings"],
.role-staff a[href="/revenue"],
.role-staff a[href="/invoices"] { display: none !important; }

/* Members have no dashboard — hide the Dashboard nav item (sidebar + mobile).
   (Scoped to nav links so Cancel/logo links to /shop are unaffected.) */
.role-staff .nav-item[href="/shop"],
.role-staff .footer-tabs a[href="/shop"] { display: none !important; }

/* Members have no account items (Settings/Invoices/Revenue are hidden), so the
   "Account" section header would sit alone above the language toggle — hide it. */
.role-staff .nav-section-account { display: none !important; }

/* ============================================================
   Lock the topbar height so it NEVER grows/reflows as the shop
   name, logo or content load in (fixes the bell "jumping" on load).
   Lives in theme.css so it applies regardless of the page's HTML
   version. The mobile block below overrides the height for phones.
   ============================================================ */
.topbar {
  height: 66px !important;
  box-sizing: border-box !important;
}
.topbar .topbar-shopname {
  white-space: nowrap !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  font-size: 17px !important;
}
.topbar .topbar-logo {
  width: 30px !important;
  height: 30px !important;
}

/* ============================================================
   Mobile topbar — relax the fixed desktop height/overflow (which
   can break rendering on phones) and give the shop name room.
   ============================================================ */
@media (max-width: 640px) {
  .topbar {
    height: 56px !important;
    min-height: 56px !important;
    overflow: visible !important;
    padding: 8px 14px !important;
    gap: 10px !important;
  }
  .topbar .topbar-search { display: none !important; }
  .topbar .topbar-shopname {
    max-width: 46vw !important;
    font-size: 15px !important;
  }
  .topbar .topbar-logo { width: 32px !important; height: 32px !important; }
  .topbar .top-actions { gap: 8px !important; }
  .topbar .top-actions .sns-bell,
  .topbar .top-actions .icon-btn { width: 34px !important; height: 34px !important; }
  .topbar .top-actions .btn-primary {
    height: 34px !important;
    padding: 0 12px !important;
    font-size: 12.5px !important;
  }
}

/* ============================================================
   Mobile: New Estimate / Inspection topbars carry a title + tabs
   (.np-context). On phones that doesn't fit in one row, so wrap it
   to a full-width second row and keep the tabs fully visible.
   ============================================================ */
@media (max-width: 640px) {
  .topbar:has(.np-context) {
    flex-wrap: wrap !important;
    height: auto !important;
    min-height: 56px !important;
    overflow: visible !important;
    padding-bottom: 8px !important;
  }
  .topbar:has(.np-context) .topbar-titles { order: 1; }
  .topbar:has(.np-context) .top-actions { order: 2; }
  .topbar:has(.np-context) .np-context {
    order: 3;
    width: 100%;
    margin-top: 4px;
    overflow-x: auto;
  }
  .topbar:has(.np-context) .np-title { font-size: 15px; }
}
