/* FollowStack AI — design tokens */
@import url('https://fonts.googleapis.com/css2?family=Schibsted+Grotesk:ital,wght@0,400;0,500;0,600;0,700;0,800;1,400&family=Spline+Sans+Mono:wght@400;500;600&display=swap');

:root {
  --accent: #0E7A5F;
  --accent-hover: #0A6A52;
  --accent-soft: #E3F1EC;
  --accent-text: #0B6B53;

  --ink: #10201B;          /* sidebar background */
  --ink-2: #182B25;        /* sidebar hover */
  --ink-line: #24382F;
  --ink-text: #AFC4BB;
  --ink-text-dim: #6E8278;
  --ink-strong: #FFFFFF;

  --bg: #F4F6F4;
  --surface: #FFFFFF;
  --surface-2: #FAFBFA;
  --border: #E4E8E4;
  --border-strong: #D2D9D3;

  --text: #16211C;
  --text-2: #51605A;
  --text-3: #88958F;

  --warn: #B45309;
  --warn-soft: #FCEFD9;
  --danger: #B3372E;
  --danger-soft: #FBE9E7;
  --info: #2B5FA8;
  --info-soft: #E5EDF8;
  --good: #0E7A5F;
  --good-soft: #E3F1EC;
  --violet: #6D4FA3;
  --violet-soft: #EEE9F7;

  --ai: #6D4FA3;
  --ai-soft: #F4F0FB;

  --r-sm: 6px;
  --r-md: 10px;
  --r-lg: 14px;

  --shadow-sm: 0 1px 2px rgba(20, 32, 27, 0.06);
  --shadow-md: 0 2px 8px rgba(20, 32, 27, 0.08), 0 1px 2px rgba(20, 32, 27, 0.05);
  --shadow-lg: 0 12px 32px rgba(20, 32, 27, 0.14), 0 2px 8px rgba(20, 32, 27, 0.08);

  --font: 'Schibsted Grotesk', system-ui, sans-serif;
  --mono: 'Spline Sans Mono', ui-monospace, monospace;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; height: 100%; }
body {
  font-family: var(--font);
  background: var(--bg);
  color: var(--text);
  font-size: 14px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}
#root { height: 100vh; }

::selection { background: var(--accent-soft); }

button { font-family: var(--font); cursor: pointer; }
input, textarea, select { font-family: var(--font); }

/* scrollbars */
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb { background: #C9D2CB; border-radius: 8px; border: 3px solid transparent; background-clip: content-box; }
*::-webkit-scrollbar-track { background: transparent; }

/* shared utility classes */
.fs-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
}
.mono { font-family: var(--mono); }

/* unified inbox 3-column grid — context rail collapses on narrow viewports */
.fs-inbox-grid {
  display: grid;
  grid-template-columns: minmax(220px, 300px) minmax(0, 1fr) minmax(240px, 312px);
  height: 100%;
}
.fs-inbox-context { display: flex; flex-direction: column; }
@media (max-width: 1180px) {
  .fs-inbox-grid { grid-template-columns: minmax(200px, 256px) minmax(0, 1fr); }
  .fs-inbox-context { display: none !important; }
  .fs-inbox-thread { display: none !important; }
}

/* tables: hover via CSS (replaces per-row JS handlers) */
.fs-table tbody tr { transition: background 0.1s; }
.fs-table tbody tr:hover { background: var(--surface-2); }
/* Notifications-matrix per-cell channel labels only appear when the table
   stacks on phones (≤640px block below) — desktop has real column headers */
.fs-notif-clabel { display: none; }

  /* Live Call Assistant — transcript must never collapse */
  .fs-call-feed { min-height: 170px; }
  @media (max-height: 760px) {
    .fs-call-checklist .fs-chips { flex-wrap: nowrap !important; overflow-x: auto; padding-bottom: 4px; }
    .fs-call-checklist { padding-top: 8px !important; padding-bottom: 8px !important; }
  }

@media (max-width: 900px) {
  /* Calendar: agenda list replaces the week grid on phones + narrow tablets
     (the week grid needs ~680px, which iPad portrait can't give once the
     persistent sidebar takes ~218px). */
  .fs-cal-inner { display: none !important; }
  .fs-cal-agenda { display: flex !important; }
}

@keyframes fsFadeUp {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: no-preference) {
  .fs-fade { animation: fsFadeUp 0.3s ease; }
}

/* ============ responsive layer ============ */
/* app shell fills the dynamic viewport (iOS Safari safe) */
.fs-app { height: 100vh; height: 100dvh; }

/* iOS auto-zooms into any focused form field whose font-size is < 16px, which
   shrinks the visual viewport below the layout viewport and makes the whole page
   scroll sideways (the real cause of the "inbox/login is wider than the screen"
   reports — only reproduces in WebKit, never Chromium). Keep every form field at
   >=16px so iOS never zooms. !important because many fields set an inline
   font-size (e.g. the inbox reply <textarea> is inline 13.5px) and inline beats a
   plain rule — but inline-without-!important still loses to a rule with !important. */
input, textarea, select { font-size: 16px !important; }
/* Belt-and-suspenders: clip any stray horizontal overflow at the root
   (overflow:clip, not hidden, so it never becomes a scroll container that could
   trap the inbox). NB: on iOS WebKit this does NOT clip position:fixed children —
   the off-canvas sidebar is handled directly via visibility (see @media 760px). */
html, body { overflow-x: clip; }
/* WebKit won't break long unbreakable tokens (E.164 phone numbers like
   +12109424936, emails, bare URLs) on its own, so a call-summary / message bubble
   grows to the token's width and pans the thread sideways. Let everything inside
   the conversation log wrap. */
[role="log"] { overflow-wrap: anywhere; }

/* tables: scroll sideways instead of crushing */
.fs-card:has(> table) { overflow-x: auto !important; }
.fs-card > table { min-width: 620px; }
.fs-scroll-x { overflow-x: auto !important; }
.fs-cal-inner { min-width: 680px; }

/* sidebar drawer below 760px (phones). iPad portrait (768px+) keeps the
   persistent sidebar so the tablet isn't stuck with the cramped phone layout. */
.fs-burger { display: none; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: 10px; border: 1px solid var(--border); background: var(--surface); color: var(--text-2); flex-shrink: 0; }
.fs-nav-backdrop { position: fixed; inset: 0; background: rgba(16, 32, 27, 0.45); z-index: 140; }
@media (max-width: 760px) {
  /* Parked off-screen-left when closed. CRITICAL: also visibility:hidden +
     pointer-events:none so the fixed box leaves the scrollable area — on iOS
     WKWebView, html/body overflow-x:clip does NOT clip a position:fixed
     descendant, so a parked translateX(-105%) drawer otherwise makes the whole
     page pan sideways (scrollWidth still reports 440 — invisible to it). */
  aside.fs-sidebar { position: fixed; left: 0; top: 0; bottom: 0; z-index: 150; transform: translateX(-105%); visibility: hidden; pointer-events: none; transition: transform 0.22s ease, visibility 0.22s ease; box-shadow: var(--shadow-lg); }
  aside.fs-sidebar.open { transform: translateX(0); visibility: visible; pointer-events: auto; }
  .fs-burger { display: inline-flex; }
}

/* topbar search slims down */
@media (max-width: 1100px) {
  .fs-topbar-search { width: auto !important; flex: 0 0 auto; }
  .fs-search-hint { display: none !important; }
}

/* grid utilities — !important beats inline styles */
@media (max-width: 1100px) {
  .fs-grid-5 { grid-template-columns: repeat(3, 1fr) !important; }
  .fs-grid-4 { grid-template-columns: repeat(2, 1fr) !important; }
  .fs-tpl-grid { grid-template-columns: 1fr !important; }
}
@media (max-width: 900px) {
  .fs-cols, .fs-grid-3, .fs-auto-grid { grid-template-columns: 1fr !important; }
  /* Live Call Assistant — tabbed on mobile so the transcript is never buried */
  .fs-call-grid { grid-template-columns: 1fr !important; grid-template-rows: auto minmax(0, 1fr); }
  .fs-call-tabs { display: flex !important; }
  .fs-call-grid[data-mtab="transcript"] .fs-call-panel { display: none !important; }
  .fs-call-grid[data-mtab="transcript"] .fs-call-checklist { display: none !important; }
  .fs-call-grid[data-mtab="hints"] .fs-call-left > *:not(:first-child) { display: none !important; }
  .fs-call-grid[data-mtab="hints"] .fs-call-left { flex: none; }
  .fs-call-grid[data-mtab="checklist"] .fs-call-panel { display: none !important; }
  .fs-call-grid[data-mtab="checklist"] .fs-call-left > *:not(.fs-call-checklist):not(:first-child) { display: none !important; }
  .fs-call-grid[data-mtab="checklist"] .fs-call-checklist { border-top: none; }
  .fs-call-panel { border-left: none !important; border-top: 1px solid var(--border); }
  .fs-grid-2 { grid-template-columns: 1fr !important; }
  .fs-grid-5 { grid-template-columns: repeat(2, 1fr) !important; }
  .fs-stepper { flex-wrap: wrap; row-gap: 8px; }
}
@media (max-width: 760px) {
  .fs-login-split { flex-direction: column !important; }
}
/* Mobile pane-switcher contract (shared by inbox, automations, live call). On a
   phone, two side-by-side panes used to collapse into two cramped stacked scrollers
   (250px list over a scrolling thread, etc.). Instead, the host grid (.fs-mgrid)
   becomes ONE full-screen pane + a tab bar (.fs-mtabs) switches which pane shows,
   keyed off data-mtab="a"|"b" on the host with .fs-mpane-a / .fs-mpane-b on the panes.
   Generalised from the Live Call Assistant .fs-call-grid/.fs-call-tabs mechanism. */
.fs-mtabs { display: none; }
/* Panes must be allowed to shrink below their content's min-content, or a single long
   token (e.g. a long lead name in the inbox list) forces the whole grid wider than the
   screen. A grid/flex item defaults to min-width:auto (= min-content), so set it to 0. */
.fs-mpane-a, .fs-mpane-b { min-width: 0; }
@media (max-width: 900px) {
  .fs-mgrid { grid-template-columns: 1fr !important; grid-template-rows: auto minmax(0, 1fr) !important; }
  .fs-mtabs { display: flex !important; gap: 4px; padding: 8px 12px; border-bottom: 1px solid var(--border); background: var(--surface); grid-column: 1 / -1; }
  .fs-mgrid[data-mtab="a"] .fs-mpane-b { display: none !important; }
  .fs-mgrid[data-mtab="b"] .fs-mpane-a { display: none !important; }
  .fs-mpane-b { border-left: none !important; }
}
@media (max-width: 560px) {
  .fs-grid-5, .fs-grid-4 { grid-template-columns: 1fr 1fr !important; }
  .fs-grid-3 { grid-template-columns: 1fr !important; }
}
/* Inline 2-column content grids that lack a responsive class (chatbot settings +
   live-preview, website/forms + other "form | preview" layouts) stack on phones +
   narrow tablets so the second column doesn't run off-screen. Targets the specific
   content column patterns by their rendered inline value — deliberately NOT a blanket
   grid rule, so intentional inline grids (the dialer keypad `repeat(3,1fr)`, icon
   `auto 1fr` rows, `52px repeat(...)` table headers) are left untouched. */
@media (max-width: 900px) {
  .fs-stack,
  [style*="grid-template-columns: 1fr 1fr"],
  [style*="grid-template-columns: 1fr 320px"],
  [style*="grid-template-columns: 1fr 360px"],
  [style*="grid-template-columns: 1fr 1.2fr"],
  [style*="grid-template-columns: 1.2fr 1fr"],
  [style*="grid-template-columns: 1.3fr 1fr"],
  [style*="grid-template-columns: 1.5fr 1fr"],
  [style*="grid-template-columns: 1.6fr 1fr"],
  [style*="grid-template-columns: 1.7fr 1fr"] {
    grid-template-columns: 1fr !important;
  }
  /* Let collapsed grid columns shrink to the viewport instead of being held wide by
     a child's min-content (e.g. the chatbot live-preview mockup) — the classic grid
     overflow fix. min-width:0 is harmless for intentional grids (keypad etc.). */
  main [style*="grid-template-columns"] > * { min-width: 0; }
}
@keyframes fsPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}
@keyframes fsBlink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0; }
}

/* ============ Dynamic Island / notch safe-area + phone polish ============ */
/* The topbar drops below the Dynamic Island / notch and respects side insets
   (landscape). The white header background fills the inset strip so the status
   bar reads cleanly over it. */
.fs-topbar {
  padding-top: env(safe-area-inset-top) !important;
  min-height: calc(58px + env(safe-area-inset-top));
  padding-left: max(16px, env(safe-area-inset-left)) !important;
  padding-right: max(16px, env(safe-area-inset-right)) !important;
}
.fs-topbar > h1 { min-width: 0; }

/* Main scroll area honors side insets in landscape (notch on the side). */
.fs-main-pad {
  padding: 20px;
  padding-left: max(20px, env(safe-area-inset-left));
  padding-right: max(20px, env(safe-area-inset-right));
}

/* Sidebar drawer (phones) clears the island + left inset; footer clears the
   home indicator. */
@media (max-width: 760px) {
  aside.fs-sidebar {
    padding-top: env(safe-area-inset-top);
    padding-left: env(safe-area-inset-left);
    padding-bottom: env(safe-area-inset-bottom);
    width: calc(218px + env(safe-area-inset-left));
  }
}

/* Fixed overlays ride above the home indicator. */
.fs-incoming-toast { width: min(330px, calc(100vw - 24px)) !important; right: 12px !important; bottom: max(12px, env(safe-area-inset-bottom)) !important; }
.fs-tour-card { bottom: max(18px, calc(env(safe-area-inset-bottom) + 8px)) !important; }

/* ---- topbar fits any phone without clipping ---- */
@media (max-width: 680px) {
  .fs-topbar { gap: 9px !important; }
  .fs-hide-phone { display: none !important; }   /* global search + help button */
  .fs-topbar-label { display: none; }            /* "New" collapses to its icon */
  .fs-new-btn { padding-left: 10px !important; padding-right: 10px !important; }
}

/* ---- popover menus become full-width sheets under the topbar (never clipped) ---- */
@media (max-width: 560px) {
  .fs-pop {
    position: fixed !important;
    top: calc(env(safe-area-inset-top) + 62px) !important;
    left: 10px !important;
    right: 10px !important;
    width: auto !important;
    max-height: calc(100dvh - env(safe-area-inset-top) - 86px) !important;
    overflow-y: auto;
  }
  .fs-cmd-wrap { padding-top: calc(env(safe-area-inset-top) + 64px) !important; align-items: stretch !important; }
  .fs-cmd { width: 100% !important; max-height: 72dvh !important; }
  .fs-main-pad { padding-top: 14px; padding-bottom: 16px; padding-left: max(13px, env(safe-area-inset-left)); padding-right: max(13px, env(safe-area-inset-right)); }
}

/* Smallest phones (iPhone SE / mini): tighten the topbar title and gaps. */
@media (max-width: 380px) {
  .fs-topbar { gap: 7px !important; }
  .fs-topbar > h1 { font-size: 15px !important; }
}

/* ============ accessibility + design-system layer ============ */
/* Type + spacing scale tokens (adopt incrementally; collapses the 0.5px sprawl). */
:root {
  --fs-xs: 11px; --fs-sm: 12.5px; --fs-md: 14px; --fs-lg: 16px; --fs-xl: 18px; --fs-2xl: 21px; --fs-3xl: 26px;
  --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px; --space-5: 24px; --space-6: 32px;
  --r-pill: 999px;
  /* darken secondary text so small labels/timestamps meet WCAG AA on --bg + --surface */
  --text-3: #63726A;
}

/* Visible keyboard focus everywhere (the app removed native outlines without a
   replacement). Pointer users don't see it; keyboard users do. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}
*:focus:not(:focus-visible) { outline: none; }
/* many inputs set inline `outline:none` which beats the rule above — force a
   visible focus ring on form fields with !important so keyboard users see it */
input:focus-visible, textarea:focus-visible, select:focus-visible, [contenteditable]:focus-visible {
  outline: 2px solid var(--accent) !important;
  outline-offset: 1px;
}

/* clickable cards/rows get a real hover + focus affordance */
.fs-card-btn { transition: box-shadow 0.12s, border-color 0.12s, background 0.12s; }
.fs-card-btn:hover { box-shadow: var(--shadow-md); border-color: var(--border-strong); }

/* respect reduced-motion: stop infinite pulses + damp transitions */
@media (prefers-reduced-motion: reduce) {
  .fs-fade, [style*="fsPulse"], [style*="fsBlink"] { animation: none !important; }
  * { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }
}

/* toast stack (shared FS_TOAST) — viewport-anchored so it never clips inside a pane */
.fs-toast-wrap { position: fixed; left: 50%; transform: translateX(-50%); bottom: max(20px, env(safe-area-inset-bottom)); z-index: 240; display: flex; flex-direction: column; gap: 10px; align-items: center; width: min(440px, calc(100vw - 24px)); pointer-events: none; }
.fs-toast { pointer-events: auto; width: 100%; background: var(--ink); color: var(--ink-strong); border: 1px solid rgba(255,255,255,0.08); border-radius: 15px; box-shadow: 0 14px 40px rgba(0,0,0,0.36); padding: 12px 14px; display: flex; align-items: center; gap: 12px; font-size: 13px; position: relative; overflow: hidden; }
/* accent spine — colour-codes the notification and gives it presence */
.fs-toast::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--accent); }
.fs-toast.tone-success::before { background: #2fbe6a; }
.fs-toast.tone-info::before { background: #3b9dff; }
.fs-toast.tone-warn::before { background: #f5a623; }
.fs-toast.tone-danger::before { background: #ff453a; }
.fs-toast.tone-call::before { background: #2fbe6a; }
.fs-toast-ico { flex-shrink: 0; width: 36px; height: 36px; border-radius: 11px; display: flex; align-items: center; justify-content: center; background: rgba(255,255,255,0.11); color: #fff; }
.fs-toast.tone-success .fs-toast-ico { background: rgba(47,190,106,0.22); color: #7fe3b0; }
.fs-toast.tone-info .fs-toast-ico { background: rgba(59,157,255,0.22); color: #9cc9ff; }
.fs-toast.tone-warn .fs-toast-ico { background: rgba(245,166,35,0.22); color: #ffd28a; }
.fs-toast.tone-danger .fs-toast-ico { background: rgba(255,69,58,0.22); color: #ff9d95; }
.fs-toast.tone-call .fs-toast-ico { background: rgba(47,190,106,0.22); color: #7fe3b0; }
.fs-toast-title { font-weight: 800; font-size: 13px; line-height: 1.25; }
.fs-toast-msg { font-size: 12.5px; color: rgba(255,255,255,0.78); line-height: 1.35; }
.fs-toast button { background: rgba(255,255,255,0.12); border: none; color: #7fe3c0; font-weight: 800; font-size: 12px; cursor: pointer; white-space: nowrap; padding: 6px 12px; border-radius: 9px; }
.fs-toast button.fs-toast-x { background: none; color: var(--ink-text-dim); padding: 4px 2px; font-weight: 600; }

/* role=switch toggle */
.fs-switch { width: 38px; height: 22px; border-radius: 999px; border: none; padding: 0; position: relative; cursor: pointer; flex-shrink: 0; transition: background 0.15s; background: var(--border-strong); }
.fs-switch[aria-checked="true"] { background: var(--accent); }
.fs-switch > span { position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%; background: #fff; transition: left 0.15s; box-shadow: 0 1px 2px rgba(0,0,0,0.2); }
.fs-switch[aria-checked="true"] > span { left: 18px; }

/* responsive leftovers: pipeline columns + table scroll on phones */
@media (max-width: 700px) {
  .fs-pipe-col { width: 84vw !important; }
  .fs-pipe-row { scroll-snap-type: x mandatory; }
  .fs-pipe-col { scroll-snap-align: start; }
}
.fs-tbl-wrap { overflow-x: auto; }
.fs-tbl-wrap > table { min-width: 560px; }

/* ===== mobile: reflow wide tables into stacked cards (no sideways scroll) ===== */
@media (max-width: 640px) {
  /* kill the desktop min-width + the horizontal-scroll container */
  .fs-table { min-width: 0 !important; width: 100% !important; }
  .fs-card > table { min-width: 0 !important; }
  .fs-card:has(> table.fs-table) { overflow-x: hidden !important; }
  .fs-table thead, .fs-table colgroup { display: none !important; }
  .fs-table, .fs-table tbody, .fs-table tr, .fs-table td { display: block !important; width: 100% !important; box-sizing: border-box; }
  .fs-table tr { padding: 11px 14px !important; border-bottom: 1px solid var(--border) !important; }
  .fs-table tr:hover { background: transparent !important; }
  .fs-table td { padding: 2px 0 !important; border: none !important; text-align: left !important; white-space: normal !important; max-width: 100% !important; }
  .fs-table td:first-child { font-weight: 700; font-size: 14px; margin-bottom: 2px; }
  /* a few last-cell action columns shouldn't force a tall empty row */
  .fs-table td:empty { display: none !important; }

  /* Settings → Notifications matrix: when the table stacks, label each toggle
     with its channel (the column headers are hidden here) */
  .fs-table.fs-notif-matrix td { display: flex !important; align-items: center; justify-content: space-between; gap: 10px; }
  .fs-table.fs-notif-matrix td:first-child { display: block !important; }
  .fs-notif-matrix .fs-notif-clabel { display: inline; font-size: 12.5px; font-weight: 600; color: var(--text-2); }

  /* filter / chip rows: let them scroll horizontally instead of clipping */
  .fs-chip-row, .fs-filters { overflow-x: auto; flex-wrap: nowrap !important; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
  .fs-chip-row::-webkit-scrollbar, .fs-filters::-webkit-scrollbar { display: none; }

  /* page hint + banners: compact so they don't eat the first screen */
  .fs-pagehint { padding: 7px 13px !important; font-size: 12px !important; }
  .fs-pagehint .fs-hint-try { display: none !important; }
  .fs-pushbanner { padding: 8px 13px !important; font-size: 12.5px !important; }
  .fs-pushbanner-txt { overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
}

/* Tap targets: the push-banner dismiss (X) button is rendered without a class —
   give it a 36px minimum hit area (glyph stays small, banner height unchanged). */
.fs-pushbanner button:last-child {
  min-width: 36px;
  min-height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
}
