  *{box-sizing:border-box;margin:0;padding:0}
  body{background:var(--bg);color:var(--ink);font:14px/1.5 system-ui,-apple-system,"Segoe UI",sans-serif;padding:20px;-webkit-text-size-adjust:100%}
  a{color:var(--pri);text-decoration:none}
  .hidden{display:none!important}
  .card{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:16px}
  /* login */
  #login{max-width:380px;margin:10vh auto}
  #login h1{margin-bottom:6px;display:flex;align-items:center;gap:8px}
  #login input{display:block;width:100%;margin:10px 0;padding:12px;border-radius:10px;border:1px solid var(--line);background:var(--panel2);color:var(--ink)}
  button{cursor:pointer;border:0;border-radius:10px;padding:11px 16px;font-weight:600;font-size:14px;background:var(--pri);color:#fff}
  button.ghost{background:var(--panel2);color:var(--ink);border:1px solid var(--line)}
  .err{color:var(--bad);min-height:20px;margin:6px 0}
  /* topbar — two rows: the session (brand, account, theme, sign out) above the sections.
     The rows are separate boxes rather than one wrapped flex line, so where the line breaks never depends
     on how long the operator's email happens to be. One gap for every control in both rows: the spacing
     used to come from inline margin-left on some buttons and not others, so the gaps did not match. */
  #top{display:block;margin-bottom:16px}
  #topBar{display:flex;justify-content:space-between;align-items:center;gap:10px;flex-wrap:wrap}
  #topActions{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
  #topNav{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:10px;justify-content:flex-end}
  #top h1{font-size:18px;display:flex;align-items:center;gap:8px}
  #top .who{color:var(--muted);font-size:13px}
  .brand-mark{width:24px;height:24px;display:block;flex:0 0 auto}
  /* Every page shares one content width, centred. Settings had this inline and the other three did
     not, so they stretched to the full window while Settings sat in a column. Declared once here so the
     four cannot drift again. Below 1240px it does nothing, so nothing about the responsive layout
     changes. #envBanner is in the list because it is a card: left out, it would sit 80px wider than the
     cards beneath it. #top is in it for the same reason: the header holds controls that line up with the
     cards below — the brand on the left edge, the account, theme toggle, Sign out and the section tabs on
     the right edge — and on a wide window it was reaching past both. */
  #view-findleads,#view-pipeline,#view-businesses,#view-settings,#envLabel,#envBanner,#top{max-width:1240px;margin:0 auto}
  /* Where am I. Stated once, large, above everything: the three environments render the same pages with
     the same businesses in them, so nothing below this line says which one is real -- and mail, the
     database and the image bucket all follow from it. Colour carries the risk: green is a scratch
     environment, amber is one step from production, red is production. */
  #envLabel{font-size:30px;font-weight:800;line-height:1.15;letter-spacing:-.02em;margin-bottom:6px}
  #envLabel[data-env="development"]{color:var(--ok)}
  #envLabel[data-env="staging"]{color:var(--acc)}
  #envLabel[data-env="production"]{color:var(--bad)}
  /* metrics */
  #metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;margin-bottom:18px}
  .metric{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:14px}
  .metric b{font-size:26px;display:block}
  .metric span{color:var(--muted);font-size:12px}
  /* layout */
  /* Pipeline: the enquiries and pipeline cards stack, with the activity feed beside them. */
  #layout{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:16px;align-items:start}
  #layout #leadsColumn{grid-column:1;grid-row:1;min-width:0}
  #layout #activity{grid-column:2;grid-row:1}
    /* Desktop: Find New Leads and Live Activity on row 1, the leads table spanning both columns below. */
    /* Find Leads: the search card spans the top, then the staging table with the activity feed
       beside it. Explicit placement, so the mobile order can differ. */
    #findLayout{display:block}
    /* Spans both rows, so it sits to the right of Find New Leads AND the leads table. */
  /* Settings' two-column shell lives here rather than in an inline style so the mobile
     breakpoint below can actually override it (inline styles beat media queries). */
  /* The two forms that live on it now are peers, so equal columns: the old .9fr/1.4fr suited a
     deployment summary beside a long provider list. */
  #settingsGrid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px;align-items:start}
  /* Settings section tabs (Accounts / Server / Maintenance). A segmented control rather than
     underlined tabs. On a desktop it hugs its labels, because three tabs stretched across 1240px is
     mostly empty track; on a phone it goes full width with equal segments, so there is nothing to
     wrap and nothing to scroll sideways. */
  #settingsTabs{display:flex;gap:4px;width:fit-content;max-width:100%;padding:4px;margin-bottom:16px;background:var(--panel);border:1px solid var(--line);border-radius:12px}
  #settingsTabs .tab{flex:0 0 auto;min-width:132px;padding:9px 14px;border:1px solid transparent;border-radius:9px;background:transparent;color:var(--muted);font-weight:600;font-size:13px;white-space:nowrap;text-align:center;overflow:hidden;text-overflow:ellipsis}
  #settingsTabs .tab:hover{color:var(--ink)}
  /* Same accent treatment as the page tabs in #top, so "selected" reads identically in both strips. */
  #settingsTabs .tab[aria-selected="true"]{background:color-mix(in srgb, var(--acc) 22%, transparent);border-color:color-mix(in srgb, var(--acc) 40%, transparent);color:var(--acc)}
  /* Each panel is its own grid. A card hidden inside it (display:none, which is how the admin-only
     panels are gated) is not a grid item at all, so it leaves no gap behind it — a sibling margin or
     a flex gap would. */
  .settingsPanel{display:grid;gap:16px}
  /* Active configuration, inset at the top of the LLM Providers card. */
  .inset{background:var(--panel2);border:1px solid var(--line);border-radius:10px;padding:12px}
  /* One provider: identity on the left, its buttons on the right. */
  .provRow{display:flex;gap:12px;align-items:center;justify-content:space-between;padding:10px 12px;border:1px solid var(--line);border-radius:10px;background:var(--panel2)}
  .provMain{min-width:0}
  /* URLs and model names are long single tokens. anywhere() breaks them rather than letting them push
     the row wider, but unlike break-all it still prefers a space, so model names stop splitting
     mid-word ("de epseek-chat"). */
  .provMeta{overflow-wrap:anywhere}
  .provActions{display:flex;gap:6px;flex-shrink:0}
  .provActive{color:var(--ok);border-color:color-mix(in srgb, var(--ok) 40%, transparent)}
  /* Which page you are on. */
  #top [data-tab].active{border-color:var(--acc);color:var(--acc);background:color-mix(in srgb, var(--acc) 22%, transparent);font-weight:600}

  /* The captured-enquiries card and the pipeline card are different things on the same page, so
  they need to read as two blocks rather than one. */
  #inboxCard{margin-bottom:16px}
  /* A little inset for the search / filter / Refresh row, which otherwise sits flush against the
  card's inner edges. */
  #pipelineCard .toolbar{padding-inline:6px}
  @media(max-width:1000px){#layout,#settingsGrid{grid-template-columns:1fr}}
    /* Mobile: one column, and Live Activity drops BELOW the leads table rather than sitting between
       Find New Leads and the pipeline. Explicit rows keep this independent of source order. */
    @media(max-width:1000px){
      #layout{grid-template-columns:1fr}
      #layout #activity{grid-column:1;grid-row:2}
    }
  /* table */
  .toolbar{display:flex;gap:10px;margin-bottom:12px;flex-wrap:wrap}
    #stagedCounts{flex:1}

  /* One row per maintenance action: button, what it does, and its own result line. */
  .maintRow{padding:10px 0;border-top:1px solid var(--line)}
  .maintRow .mini{margin-top:4px}
  .toolbar input,.toolbar select{padding:9px 11px;border-radius:9px;border:1px solid var(--line);background:var(--panel2);color:var(--ink)}
  table{width:100%;border-collapse:collapse}
  th,td{text-align:left;padding:10px 8px;border-bottom:1px solid var(--line);vertical-align:top}
  th{color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.05em;position:sticky;top:0;background:var(--panel);z-index:2}
  #pipelineTable td,#stagedTable td{font-size:13px}
  #pipelineTable a{margin-right:2px}
  /* Fixed layout so the table always fits its container instead of forcing a horizontal
     scroll. The pipeline's columns plus the 320px activity sidebar meant the table needed
     roughly 1700px of viewport to lay out naturally - narrow desktop windows scrolled
     sideways too, not just phones. Long values now ellipsize (titles carry the full text). */
  /* Table cells stay table cells. A <td> given display:flex/block/grid leaves the table layout
     algorithm: it stops occupying its column and is laid out where the PREVIOUS column sits, so its
     content renders under the wrong heading while the DOM still looks perfectly correct. That is how
     the staging table's buttons ended up under Audit. Keep flex/grid containers as inner <div>s (see
     the cell-actions>div and cell-audit>div rules below).
     DashboardTableLayoutConventionTests fails the build if this is broken.
     The mobile card-mode block below is the one deliberate exception: there the table is abandoned on
     purpose, so display:block on a td is the point. */
  #pipelineTable,#stagedTable{table-layout:fixed}
  #pipelineTable th,#pipelineTable td,#stagedTable th,#stagedTable td{overflow:hidden;text-overflow:ellipsis}
  #pipelineTable td.cell-name{white-space:nowrap}
  #pipelineTable td.cell-name .mini{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  #pipelineTable td.cell-name .contact a{font-size:12px;color:var(--muted)}
  /* URLs are single tokens: without nowrap they cannot wrap and would be clipped by the
     cell's overflow with no ellipsis to show for it. Their titles carry the full value. */
  #pipelineTable td[data-label="Preview"]{white-space:nowrap}
  /* Pool rows carry three buttons. Laid out as a wrapped row with tighter padding they sit
     on one line instead of stacking into a three-line column that tripled the row height. */
  /* Two independent audit facts share this cell; stacked so neither hides the other and the
     column stays narrow. */
  #pipelineTable td.cell-audit>div,#stagedTable td.cell-audit>div{display:flex;flex-direction:column;gap:3px;align-items:flex-start}
  #pipelineTable td.cell-actions>div,#stagedTable td.cell-actions>div{display:flex;flex-wrap:wrap;gap:4px;align-items:center}
  #pipelineTable td.cell-actions button,#stagedTable td.cell-actions button{padding:6px 10px;font-size:12px;border-radius:8px}
  .row td a:visited{color:var(--pri)}
  .muted{color:var(--muted)}
  tr.row{cursor:pointer}
  tr.row:hover{background:var(--panel2)}
  .badge{display:inline-block;padding:3px 9px;border-radius:999px;font-size:11px;font-weight:600;background:var(--panel2);border:1px solid var(--line)}
  .badge.won{background:color-mix(in srgb, var(--ok) 18%, transparent);color:var(--ok);border-color:color-mix(in srgb, var(--ok) 40%, transparent)}
  .badge.engaged{background:color-mix(in srgb, var(--acc) 18%, transparent);color:var(--acc);border-color:color-mix(in srgb, var(--acc) 40%, transparent)}
  .badge.generated{background:color-mix(in srgb, var(--pri) 18%, transparent);color:var(--pri);border-color:color-mix(in srgb, var(--pri) 40%, transparent)}
  .stars{color:var(--acc)}
  .mini{color:var(--muted);font-size:12px}
  /* activity */
  #activity h3{margin-bottom:10px}
  #activity .act{padding:8px 0;border-bottom:1px solid var(--line);font-size:13px}
  #activity .act b{display:block}
  #activity .act span{color:var(--muted);font-size:12px}
  /* drawer */
  #drawer{position:fixed;inset:0;background:rgba(0,0,0,.55);display:none;align-items:center;justify-content:center;z-index:90}
  #drawer.open{display:flex}
  #drawer .panel{background:var(--bg);border:1px solid var(--line);border-radius:16px;width:min(960px,94vw);height:86vh;display:flex;flex-direction:column;padding:18px;overflow:auto}
  #drawer h2{margin-bottom:4px}
  #drawer .actions{display:flex;gap:8px;flex-wrap:wrap;margin:10px 0}
  /* `.ghost` is only defined for button.ghost, so an anchor with the same class fell back to
     the global link colour and read as a bare blue link next to a styled pill.
     nowrap stops flex from shrinking a pill until its own label wraps mid-text; the pills
     move to the next line instead. */
  #drawer .actions a{color:var(--ink);text-decoration:none;white-space:nowrap}
  iframe{width:100%;height:320px;border:1px solid var(--line);border-radius:10px;background:#fff}
  .tl{border-left:2px solid var(--line);padding-left:14px;margin-top:12px}
  .tl div{padding:6px 0}
  .tl .t{color:var(--muted);font-size:12px}
  #pipelineCard{padding:0;overflow-x:auto}
  #msg{position:fixed;bottom:16px;left:50%;transform:translateX(-50%);background:var(--ok);color:var(--on-ok);padding:10px 18px;border-radius:999px;font-weight:600;display:none;z-index:99;max-width:92vw;text-align:center}
  /* Stop the page behind the drawer from scrolling, which otherwise leaves the operator
     scrolled away from the modal they just opened. */
  body.drawer-open{overflow:hidden}
  /* Collapsible "Find New Leads". On a phone the search form plus the toolbar pushed the
     first prospect two screens down; here it starts collapsed and the header opens it.
     The default lives in CSS (not an inline style) so the breakpoint can override it. */
  #leadsToggle{display:none}
  /* ---- Narrow screens: phones, tablets and small desktop windows ------------------
     The breakpoint is 900px, not 640px: the pipeline has nine columns and cannot fit
     anything narrower as a table, and a centred 94vw panel is the wrong shape for a
     tablet. Below it the table becomes a stack of cards (no horizontal scrolling) and
     the drawer becomes a full-screen sheet. */
  @media(max-width:900px){
    body{padding:12px}
    #topBar{gap:8px;align-items:flex-start}

    #top h1{font-size:16px}
    #topActions,#topNav{gap:6px}
    /* Right-aligned on a wide screen, where it lines up under Sign out and against the cards' right edge.
       Stacked and full width on a phone it would just look ragged, with the actions above it starting at
       the left, so there it fills the row like everything else. */
    #topNav{margin-top:8px;justify-content:flex-start}
    #top button{padding:9px 12px;font-size:13px}
    #login{margin:6vh auto}
    /* Metrics: eight tiles in two columns ate half the first screen before any prospect
       was visible. Smaller type packs them into 3-4 columns. */
    #metrics{grid-template-columns:repeat(auto-fit,minmax(96px,1fr));gap:8px;margin-bottom:14px}
    .metric{padding:10px 11px}
    .metric b{font-size:19px}
    .metric span{font-size:11px;line-height:1.25}
    .toolbar{display:grid;grid-template-columns:1fr auto;gap:8px;align-items:center}
    .toolbar input{grid-column:1 / -1;width:100%;min-width:0}
    .toolbar select,.toolbar button{width:auto;min-width:0}
    /* The staging toolbar stacks: a select, a counts line and a long button label ("Audit not
       audited") do not belong on one two-column row with the label squeezing the buttons. Scoped
       to #stagedCard so the pipeline's filter toolbar keeps its own layout. */
    #stagedCard .toolbar{display:flex;flex-direction:column;align-items:stretch;gap:8px}
    #stagedCard .toolbar select,#stagedCard .toolbar button{width:100%}
    #stagedCard #stagedCounts{flex:0 0 auto;width:100%}
    input,select,textarea{font-size:16px}
    .card{padding:12px}
    #logOut{font-size:11px}
    /* Three equal-width tabs: 12px type and tighter padding keeps the longest label
       ("Maintenance") on one line down to a 320px viewport rather than ellipsising it. */
    #settingsTabs{width:100%;gap:3px;padding:3px}
    #settingsTabs .tab{flex:1 1 0;min-width:0;padding:8px 6px;font-size:12px}
    /* One provider per stacked block: side by side, the three buttons squeezed the model name until it
       broke mid-word. */
    .provRow{flex-direction:column;align-items:stretch;gap:8px}
    .provActions{flex-wrap:wrap}

    /* Find New Leads starts collapsed, so the pipeline is the first thing on screen.
       Its subtitle is dropped so the header stays on one line. */
    #leadsToggle{display:inline-block}
    #leadsCard h3 .mini{display:none}
    #leadsCard:not(.expanded) #leadsBody{display:none}
    /* Row links are the only tap targets inside a card; give them a little more height. */
    #pipelineTable td a{padding:3px 0;display:inline-block}

    /* Drawer -> full-screen sheet anchored to the viewport. */
    #drawer{align-items:stretch;justify-content:stretch}
    #drawer .panel{width:100%;height:100%;max-height:100%;border:0;border-radius:0;padding:12px;overflow-y:auto;-webkit-overflow-scrolling:touch}

    /* Pipeline table -> one card per prospect. Each cell keeps its column name via
       data-label, so nothing is hidden and there is nothing to scroll sideways.
       The desktop truncation rules are reset here: on a card, full text should wrap
       rather than ellipsize. */
    #pipelineCard,#stagedCard{overflow:visible;background:none;border:0;padding:0}
    #pipelineTable,#pipelineTable tbody,#stagedTable,#stagedTable tbody{display:block}
    #pipelineTable thead,#stagedTable thead{display:none}
    #pipelineTable tr.row,#stagedTable tr.row{display:block;background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:10px 12px;margin-bottom:10px}
    #pipelineTable td,#stagedTable td{display:block;border:0;padding:3px 0;font-size:13px;overflow:visible;text-overflow:clip;white-space:normal}
    /* Same specificity as the desktop nowrap rules for Website/Preview, and later in the
       sheet, so on a card those values wrap and stay readable instead of being clipped. */
    #pipelineTable td[data-label],#stagedTable td[data-label]{white-space:normal}
    #pipelineTable td[data-label]::before,#stagedTable td[data-label]::before{content:attr(data-label);display:inline-block;width:68px;color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.04em;vertical-align:top}
    #pipelineTable td.cell-name,#stagedTable td.cell-name{padding-bottom:8px;white-space:normal}
    #pipelineTable td.cell-name::before,#stagedTable td.cell-name::before{display:none}
    #pipelineTable td.cell-name .mini,#stagedTable td.cell-name .mini{white-space:normal;overflow:visible}
    #pipelineTable td.cell-actions>div{display:flex;flex-wrap:wrap;gap:6px;align-items:center}
    #pipelineTable td.cell-actions::before,#stagedTable td.cell-actions::before{display:none}
    #pipelineTable td.cell-actions,#stagedTable td.cell-actions{padding-top:10px}
    #pipelineTable .empty-row td,#stagedTable .empty-row td{padding:20px 4px;text-align:center}
  }
