/* ===========================================================
   SMFlow design system (Phase B)
   Dense, light, professional analytics tool — not a landing page.
   Class names are kept stable from the previous theme on purpose:
   every existing page's markup keeps working unchanged. Only the
   tokens and component styles change here.
   =========================================================== */
:root {
    --bg:            #EDEFF3;
    --surface:       #FFFFFF;
    --surface-alt:   #F5F6F8;
    --border:        #E2E5EA;
    --text:          #111827;
    --text-dim:      #6B7280;
    --text-faint:    #9CA3AF;

    /* Switched from Smith Media red to a RedTrack-style blue per explicit
       request — this is a global accent-color change (buttons, links,
       focus rings, active nav state, badges everywhere in the app), not
       scoped to one page. Revert to #C9161D / #A91218 / #FDECEC to go
       back to the original brand red. */
    --brand:         #2563EB;
    --brand-hover:   #1D4ED8;
    --brand-tint:    #EAF1FE;

    --positive:      #159A62;
    --positive-tint: #EAF7F1;
    --negative:      #D92D3A;
    --negative-tint: #FDECEC;
    --warning:       #F59E0B;
    --warning-tint:  #FEF6E7;

    /* Legacy token names some pages still reference — mapped onto the
       new palette so nothing silently loses its color. */
    --amber:         var(--warning);
    --surface-raised: var(--surface-alt);

    /* ---- Phase 1 design tokens (scales — use these, not raw values) ---- */
    --text-strong:   #0B1220;
    --text-2:        #374151;
    --on-brand:      #FFFFFF;
    --surface-hover: #ECEEF2;
    --border-strong: #CDD2DA;

    /* Secondary accents (violet / teal) + tonal "container" tints, Material-3 style */
    --accent-2:        #7C3AED;
    --accent-2-tint:   #F1EAFE;
    --teal:            #0E9AA7;
    --teal-tint:       #E3F6F8;
    --brand-container: #DCE7FF;
    --on-brand-container: #0B3A9E;

    /* Dark chrome (topbar) */
    --topbar:        #1A1D24;
    --topbar-text:   #B8BCC4;
    --topbar-strong: #E4E6EA;

    /* Chart / series palette: blue, violet, teal, amber, rose, green */
    --chart-1: #2563EB; --chart-2: #7C3AED; --chart-3: #0E9AA7;
    --chart-4: #F59E0B; --chart-5: #E11D74; --chart-6: #159A62;

    /* Elevation */
    --shadow-1: 0 1px 2px rgba(16,24,40,.05), 0 1px 3px rgba(16,24,40,.06);
    --shadow-2: 0 4px 8px rgba(16,24,40,.05), 0 8px 24px rgba(16,24,40,.08);
    --shadow-3: 0 12px 24px rgba(16,24,40,.10), 0 32px 64px rgba(16,24,40,.14);
    --ring:     0 0 0 3px rgba(37,99,235,.28);

    /* Type scale (replaces the 10 / 10.5 / 11 / 11.5 / 12 / 12.5 … ladder) */
    --fs-2xs: 11px; --fs-xs: 12px; --fs-sm: 13px; --fs-md: 14px;
    --fs-lg: 16px;  --fs-xl: 18px; --fs-2xl: 22px; --fs-3xl: 28px;

    /* Motion */
    --ease: cubic-bezier(.2, 0, 0, 1);
    --dur:  150ms;

    --radius-sm: 6px;
    --radius-md: 10px;
    --radius-lg: 14px;
    --radius-pill: 999px;
    /* Tighter "enterprise/technical" radius for the Campaign editor's
       Funnel component set specifically (RedTrack correction pass) —
       every color used there reuses the tokens above (all already
       within a few hex points of the requested spec values); only the
       radius needed a genuinely new, smaller token. Not used anywhere
       else in the app. */
    --radius-xs: 3px;
    --control-h: 36px;
    --font-ui:   'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
    --font-mono: 'SFMono-Regular', Consolas, 'Liberation Mono', monospace;
}

* { box-sizing: border-box; }
html, body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: var(--font-ui);
    font-size: var(--fs-sm);
    -webkit-font-smoothing: antialiased;
}
a { color: var(--brand); text-decoration: none; }
a:hover { color: var(--brand-hover); text-decoration: underline; }
code { font-family: var(--font-mono); font-size: var(--fs-xs); background: var(--surface-alt); padding: 1px 5px; border-radius: 4px; }

/* ---------- App shell ---------- */
.app-shell {
    display: grid;
    grid-template-columns: 224px 1fr;
    min-height: 100vh;
}

/* Left navigation — same shell as SMHealth / SMPost: 224px white panel,
   uppercase group labels, 13px semibold links with 16px icons, rounded
   hover, soft-blue active pill. Sticks while the page scrolls. */
.sidebar {
    position: sticky; top: 0; align-self: start;
    height: 100vh; overflow-y: auto;
    background: var(--surface);
    border-right: 1px solid var(--border);
    padding: 0 0 18px;
    scrollbar-width: thin;
}
.sidebar__brand {
    display: flex; align-items: center; height: 50px; padding: 0 20px; margin-bottom: 14px;
    border-bottom: 1px solid var(--border);
    font-size: 17px; font-weight: 600; letter-spacing: -0.4px; color: var(--text-strong);
    text-decoration: none !important;
}
.sidebar__brand span { color: var(--brand); }
.sidebar__logo { width: 26px; height: 26px; border-radius: 22%; flex: none; display: block; margin-right: 9px; }
.nav-group__label {
    font-size: var(--fs-2xs); font-weight: 600; color: var(--text-dim);
    letter-spacing: .6px; text-transform: uppercase;
    padding: 0 20px; margin: 0 0 6px;
}
.sidebar-nav { display: flex; flex-direction: column; gap: 2px; padding: 0 12px; margin-bottom: 18px; }
.nav-link {
    display: flex; align-items: center; gap: 10px; width: 100%;
    padding: 8px 12px; border-radius: var(--radius-md);
    font-size: var(--fs-sm); font-weight: 500; letter-spacing: -.1px; line-height: 1.3;
    color: var(--text-dim); text-decoration: none !important;
}
.nav-link svg { width: 16px; height: 16px; flex-shrink: 0; }
.nav-link span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-link:hover { background: var(--surface-alt); color: var(--text-strong); }
.nav-link.active { color: var(--brand); background: rgba(37, 99, 235, .08); }

/* Phones / small tablets: the sidebar becomes an off-canvas drawer opened by the
   topbar's menu button (app.js toggles .is-nav-open on .app-shell). */
@media (max-width: 900px) {
    .app-shell { grid-template-columns: 1fr; }
    .sidebar {
        position: fixed; z-index: 200; top: 0; left: 0; bottom: 0; width: 272px; max-width: 86vw; height: 100vh; height: 100dvh;
        overflow-y: auto; overscroll-behavior: contain; border-right: 1px solid var(--border);
        transform: translateX(-104%); visibility: hidden;
        transition: transform .22s var(--ease), visibility 0s linear .22s;
    }
    .app-shell.is-nav-open .sidebar { transform: none; visibility: visible; transition: transform .22s var(--ease); box-shadow: var(--shadow-3); }
    .nav-backdrop { position: fixed; inset: 0; z-index: 190; background: rgba(15, 19, 27, .45); backdrop-filter: blur(2px); }
}
.main { display: flex; flex-direction: column; min-width: 0; }

/* Dark charcoal top header — the one deliberately dark surface in an
   otherwise light app, per the brand direction. */
.topbar {
    height: 50px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 20px;
    background: var(--topbar);
    color: var(--topbar-strong);
    flex-shrink: 0;
}
.topbar__daterange {
    font-size: var(--fs-xs);
    color: var(--topbar-strong);
    background: #262A33;
    border: 1px solid #363B47;
    border-radius: var(--radius-sm);
    padding: 5px 10px;
    height: var(--control-h);
}
.topbar__status {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: var(--fs-2xs);
    color: var(--topbar-text);
    margin-left: 14px;
}
.topbar__status .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--positive); display: inline-block; }
.topbar__status .dot.warn { background: var(--warning); }
.topbar__status .dot.bad { background: var(--negative); }
.topbar__tools { color: var(--topbar-text); margin-left: 10px; font-size: var(--fs-xs); }
.topbar__tools a { color: var(--topbar-text); }
.topbar__tools a:hover { color: #fff; }
.topbar__user { color: var(--topbar-text); font-size: var(--fs-xs); }
.topbar__user a { color: var(--topbar-text); margin-left: 12px; }
.topbar__user a:hover { color: #fff; }
.topbar__left { display: flex; align-items: center; }

.content { padding: 16px 18px; flex: 1; }

/* ---------- KPI cards ---------- */
.kpi-grid {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 10px;
    margin-bottom: 18px;
}
@media (max-width: 1100px) { .kpi-grid { grid-template-columns: repeat(3, 1fr); } }

.kpi-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 12px 14px;
}
.kpi-card__label {
    font-size: var(--fs-2xs);
    font-weight: 500;
    color: var(--text-faint);
    letter-spacing: 0.04em;
    margin-bottom: 6px;
}
.kpi-card__value {
    font-family: var(--font-mono);
    font-size: var(--fs-xl);
    font-weight: 500;
    color: var(--text);
    line-height: 1.1;
}
.kpi-card__delta { font-family: var(--font-mono); font-size: var(--fs-2xs); margin-top: 5px; }
.kpi-card__delta.up { color: var(--positive); }
.kpi-card__delta.down { color: var(--negative); }
.kpi-card__delta.flat { color: var(--text-faint); }

/* ---------- Panels ---------- */
.panel {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    margin-bottom: 16px;
}
.panel__header {
    padding: 11px 14px;
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.panel__title { font-size: var(--fs-xs); font-weight: 500; color: var(--text); }
.panel__body { padding: 0; }

/* ---------- Tables ---------- */
table.data-table { width: 100%; border-collapse: collapse; font-size: var(--fs-xs); }
table.data-table th {
    text-align: left;
    font-size: var(--fs-2xs);
    font-weight: 500;
    color: var(--text-faint);
    letter-spacing: 0.03em;
    padding: 6px 10px;
    border-bottom: 1px solid var(--border);
    background: var(--surface-alt);
    position: sticky; top: 0;
}
table.data-table td {
    padding: 6px 10px;
    border-bottom: 1px solid var(--border);
    font-family: var(--font-mono);
    color: var(--text);
    white-space: nowrap;
}
table.data-table td.text { font-family: var(--font-ui); }
table.data-table tr:last-child td { border-bottom: none; }
table.data-table tr:hover td { background: var(--surface-alt); }
/* Editable rows inside a .data-table (e.g. Traffic Channels' parameter
   mapping, Offer Sources' postback field mapping) previously only set
   inline height/width, so their inputs/selects fell back to the plain
   browser-native look — unrounded and visually inconsistent with every
   other field in the app. One shared rule here matches the standard
   .field input look instead of restyling each one individually. */
table.data-table td input[type="text"],
table.data-table td select {
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--text); font-size: var(--fs-xs); font-family: var(--font-ui);
    padding: 0 8px;
}
table.data-table td input[type="text"]:focus,
table.data-table td select:focus {
    outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-tint);
}
.num-positive { color: var(--positive); font-weight: 500; }
.num-negative { color: var(--negative); font-weight: 500; }

/* ============================================================
   GLOBAL CELL VERTICAL ALIGNMENT — single source of truth for every
   shared table component (.data-table, .logs-clicks-table/.landers-table,
   .report-table, .campaigns-grid/.resizable-table). The browser default
   for td/th is `vertical-align: baseline`, which computes each cell's
   position from its own content's text baseline — that computation
   differs depending on what's actually inside the cell (plain text vs
   a <span class="badge">, an <a class="entity-name-link"> block, a
   nested <div> for a comparison delta, etc.), which is exactly what
   produced the "some values sit higher/lower" inconsistency: it was
   never a per-page padding/margin problem, it was every cell silently
   using a different effective baseline. Overriding to `middle` here
   makes every cell's content box center vertically in the row instead,
   regardless of what element is inside it — one rule, not per-column
   fixes. Deliberately does NOT touch row height, padding, or
   line-height, so the compact density is unaffected; anything that
   still visually anchors to a corner (e.g. wrapped 2-line metric
   headers, which intentionally bottom-align to sit closest to the data
   below) does so via its own more specific selector layered on top
   further down this file. */
:is(.data-table, .logs-clicks-table, .landers-table, .report-table, .campaigns-grid, .resizable-table) th,
:is(.data-table, .logs-clicks-table, .landers-table, .report-table, .campaigns-grid, .resizable-table) td {
    vertical-align: middle;
}
/* .entity-name-cell / .campaigns-grid__name-cell are already plain <td>
   elements, so they're covered by the rule above — the hover-actions
   container inside them is position:absolute and ignores the parent's
   vertical-align entirely, so it never re-introduces misalignment.
   .badge is inline-block and appears inside table cells across every
   page (Status columns, etc.) — without this it aligns to its own
   text baseline like any other inline-block, which is the same class
   of bug as the cell-level one above, just one level deeper. */
.badge { vertical-align: middle; }

/* ---------- Resizable grid table (Campaigns list) ---------- */
/* table-layout:fixed + an explicit <colgroup> is what makes column
   widths independently controllable — with the default auto layout,
   the browser sizes every column from its content across ALL rows at
   once, which is what made a content-heavy column (Actions) squeeze
   the numeric ones unpredictably. Fixed layout + <col> widths is also
   what real spreadsheet-style tools (the reference included) rely on
   for actually resizable columns. */
.resizable-table { table-layout: fixed; }
.resizable-table th, .resizable-table td {
    border-right: 1px solid var(--border);
    overflow: hidden; text-overflow: ellipsis;
}
.resizable-table th:last-child, .resizable-table td:last-child { border-right: none; }
.resizable-table th { position: relative; }
.col-resize-handle {
    position: absolute; top: 0; right: -4px; width: 8px; height: 100%;
    cursor: col-resize; z-index: 3; user-select: none;
}
.col-resize-handle:hover, .col-resize-handle.is-resizing { background: var(--brand-tint); }
.resizable-table td .icon-btn-row, .resizable-table td .row-actions { flex-wrap: wrap; }
/* Headers may wrap onto ~2 lines instead of truncating — with a
   user-resizable column, forcing single-line headers would either
   truncate short-but-wider-than-column text or force every column
   wider than its data needs just to fit its own label. Values stay
   nowrap (set per td.num/td.text elsewhere); only header text wraps. */
.resizable-table th { white-space: normal; line-height: 1.15; }

/* Sticky columns pinned by assets/js/table-engine.js's applySticky() —
   left offset is set inline per-cell by JS (computed from live column
   widths), this just supplies the opaque background so scrolled-past
   content doesn't show through, and a box-shadow on the last pinned
   column to visually separate it from the scrolling columns. */
.sm-sticky-col { background: var(--surface); }
tr.totals-row .sm-sticky-col, thead .sm-sticky-col { background: var(--surface-alt); }


/* ---------------- Campaigns page: bare reporting workspace ----------------
   Deliberately NOT wrapped in .panel — this page reads as one continuous
   reporting surface (title, filters, toolbar, table) rather than a stack
   of bordered dashboard cards, matching the reference layout. */
.workspace-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.workspace-header__title { font-size: var(--fs-2xl); font-weight: 600; color: var(--text); margin: 0; }

.workspace-filterbar { display: flex; flex-wrap: wrap; gap: 14px; align-items: flex-end; margin-bottom: 4px; }
.wf-field { display: flex; flex-direction: column; gap: 3px; }
.wf-field label { font-size: var(--fs-2xs); font-weight: 500; color: var(--text-faint); letter-spacing: 0.03em; text-transform: uppercase; }
.wf-field select, .wf-field input {
    height: 30px; padding: 0 8px; font-size: var(--fs-xs); border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--text);
}
.wf-static { height: 30px; display: flex; align-items: center; font-size: var(--fs-xs); color: var(--text-dim); }

/* Flat icon+text toolbar actions — no button borders/chrome, just a
   hover background, so the toolbar reads as a strip of actions rather
   than a row of separate buttons. Disabled state is a plain opacity
   drop, same convention as everywhere else disabled controls appear. */
.workspace-toolbar {
    display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px;
    padding: 6px 0; border-bottom: 1px solid var(--border); margin-bottom: 0;
}
.workspace-toolbar__group { display: flex; align-items: center; gap: 2px; flex-wrap: wrap; }
.wt-action {
    display: inline-flex; align-items: center; gap: 5px;
    background: none; border: none; color: var(--text-dim); font-size: var(--fs-xs); font-weight: 500;
    padding: 5px 8px; border-radius: 4px; cursor: pointer; text-decoration: none; white-space: nowrap;
}
.wt-action svg { width: 13px; height: 13px; }
.wt-action:hover { background: var(--surface-alt); color: var(--text); text-decoration: none; }
.wt-action:disabled { opacity: 0.4; cursor: not-allowed; }
.wt-action:disabled:hover { background: none; color: var(--text-dim); }
.wt-action.is-disabled { opacity: 0.4; cursor: default; }
.wt-action.is-active { color: var(--brand); background: var(--brand-tint); }
.columns-panel label.is-active { color: var(--brand); font-weight: 500; }

.workspace-table-wrap { border-top: 1px solid var(--border); }


/* ============================================================
   ENTITY-NAME-CELL HOVER ACTIONS — ONE shared component, used by
   Campaigns (.campaigns-grid__name-cell) and every other entity table
   (.entity-name-cell — Traffic Channels/Offers/Offer Sources/Landers/
   CAPI/Ad Accounts). Every property below (container, icon size,
   button size, spacing, colors, transition, touch fallback) is defined
   exactly once and shared via :is(); nothing here is duplicated per
   page. Only the trigger differs, intentionally: Campaigns reveals its
   actions on hovering/focusing anywhere in the row (tr:hover), while
   every other table added afterward is scoped tighter — hovering the
   name cell itself only, never a metric cell like Clicks/Revenue/Cost.
   Both triggers point at the exact same .row-hover-actions container,
   so the two look and behave identically wherever they appear.

   Actions live INSIDE the name cell rather than a dedicated trailing
   column — nothing reserves extra table width for them, they stay
   reachable regardless of horizontal scroll on tables that pin their
   name column, and they never affect row height or column width: the
   container is position:absolute (out of flow) and invisible
   (opacity:0) until triggered, while the name link's own padding-right
   reserves their visual space so nothing shifts on hover. */
:is(.campaigns-grid__name-cell, .entity-name-cell) { position: relative; white-space: nowrap; overflow: hidden; }
:is(.campaigns-grid__name-link, .entity-name-link) { font-weight: 500; color: var(--text); text-decoration: none; display: block; overflow: hidden; text-overflow: ellipsis; }
.campaigns-grid__name-link { padding-right: 92px; }
:is(.campaigns-grid__name-link, .entity-name-link):hover { color: var(--brand); text-decoration: underline; }
:is(.campaigns-grid__name-cell, .entity-name-cell) .row-hover-actions {
    position: absolute; top: 50%; right: 4px; transform: translateY(-50%);
    display: flex; align-items: center; gap: 2px; background: var(--surface);
    opacity: 0; pointer-events: none; transition: opacity .1s ease;
}
.campaigns-grid tr:hover .row-hover-actions,
.campaigns-grid tr:focus-within .row-hover-actions,
.entity-name-cell:hover .row-hover-actions,
.entity-name-cell:focus-within .row-hover-actions { opacity: 1; pointer-events: auto; }
:is(.campaigns-grid__name-cell, .entity-name-cell) .row-hover-actions .icon-btn,
:is(.campaigns-grid__name-cell, .entity-name-cell) .row-hover-actions .copy-url--icon-only { width: 22px; height: 22px; }
:is(.campaigns-grid__name-cell, .entity-name-cell) .row-hover-actions .icon-btn svg { width: 12px; height: 12px; }
@media (hover: none) {
    /* No hover on touch — keep actions faintly visible and always
       tappable instead of requiring a hover that can't happen. Same
       fallback for both Campaigns and every other entity table. */
    :is(.campaigns-grid__name-cell, .entity-name-cell) .row-hover-actions { opacity: 0.7; pointer-events: auto; background: none; }
}

/* Caps how wide the primary entity/name column is allowed to grow on
   every auto-table-layout reporting table (Traffic Channels/Offers/
   Offer Sources/Landers/CAPI/Ad Accounts — Campaigns is exempt, its
   .campaigns-grid__name-cell gets an explicit pixel width from its own
   JS-resizable <colgroup> instead). Without this cap, narrowing the
   numeric columns (see the column-width system below) just hands the
   freed-up space straight to this column instead, since it's the only
   one left without a width constraint — exactly the "Name column eats
   70% of the table" regression this fixes. min-width keeps short names
   from collapsing too far; overflow/ellipsis on .entity-name-link
   already handles anything longer than max-width, with the full name
   available via the browser's native title tooltip on the link. */
.entity-name-cell { min-width: 160px !important; max-width: 260px !important; }

/* Campaigns now uses the shared .landers-table grid (sticky checkbox / ID /
   name columns, density classes, totals row) — see the list-table section. */

/* Extremely light, Profit-signed row tint (Section 12 of this pass) —
   reuses the exact same tint tokens badges/hero cards already use
   elsewhere, so "subtle" here means the same thing it means everywhere
   else in the app, not a new, stronger color. */
tr.row-positive td { background: var(--positive-tint); }
tr.row-negative td { background: var(--negative-tint); }
tr.row-positive:hover td, tr.row-negative:hover td { filter: brightness(0.98); }

/* Shared "newly created/duplicated entity pinned to the top" highlight
   (see report_apply_pinned_row() and each entity page's ?pinned_id
   handling) — a brief fade from the same brand tint used elsewhere
   (.wt-action.is-active, focus rings), never a permanent badge/style.
   Applies to the row's own background; sticky/hover-action cells keep
   their opaque background the same way row-positive/row-negative do. */
tr.row-pinned-new td { animation: sm-pinned-fade 2.4s ease-out forwards; }
@keyframes sm-pinned-fade {
    0%   { background-color: var(--brand-tint); }
    100% { background-color: transparent; }
}

.empty-state {
    padding: 40px 24px;
    text-align: center;
    color: var(--text-dim);
}
.empty-state__title { font-size: var(--fs-sm); font-weight: 500; color: var(--text); margin-bottom: 5px; }
.empty-state__body { font-size: var(--fs-xs); color: var(--text-faint); max-width: 420px; margin: 0 auto; }

/* ---------- System health ---------- */
.health-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.health-item {
    background: var(--surface-alt);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 9px 11px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: var(--fs-xs);
}
.health-dot { width: 6px; height: 6px; border-radius: 50%; display: inline-block; margin-right: 6px; }
.health-dot.ok { background: var(--positive); }
.health-dot.warn { background: var(--warning); }
.health-dot.bad { background: var(--negative); }

/* ---------- Login ---------- */
.login-wrap { min-height: 100vh; display: flex; align-items: center; justify-content: center; background: var(--bg); }
.login-card { width: 340px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 26px; box-shadow: 0 1px 3px rgba(20,24,32,0.06); }
.login-card__brand { font-weight: 600; font-size: var(--fs-lg); margin-bottom: 18px; }
.login-card__brand span { color: var(--brand); }

/* ---------- Public legal pages (privacy / terms / data deletion) ---------- */
body.legal { background: var(--bg); color: var(--text); overflow: auto; height: auto; }
.legal__inner { max-width: 760px; margin: 0 auto; padding: 0 16px; }
.legal__bar { background: var(--surface); border-bottom: 1px solid var(--border); }
.legal__bar-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; min-height: 54px; }
.legal__brand { margin: 0; }
.legal__nav { display: flex; gap: 16px; flex-wrap: wrap; font-size: var(--fs-sm); }
.legal__nav a { color: var(--text-dim); text-decoration: none; padding: 4px 0; }
.legal__nav a:hover, .legal__nav a.is-current { color: var(--brand); }
.legal__doc { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md); width: calc(100% - 32px); max-width: 760px; box-sizing: border-box; margin-top: 24px; padding: 28px 32px; font-size: var(--fs-md); line-height: 1.65; }
.legal__doc h1 { font-size: 24px; font-weight: 700; margin: 0 0 4px; }
.legal__doc h2 { font-size: var(--fs-lg); font-weight: 600; margin: 26px 0 8px; }
.legal__doc h3 { font-size: var(--fs-md); font-weight: 600; margin: 16px 0 6px; }
.legal__doc p, .legal__doc ul, .legal__doc ol { margin: 0 0 10px; }
.legal__doc ul, .legal__doc ol { padding-left: 22px; }
.legal__doc li { margin-bottom: 4px; }
.legal__doc a, .legal__footer a { color: var(--brand); }
.legal__doc code { font-family: var(--font-mono); font-size: var(--fs-xs); background: var(--surface-alt); border: 1px solid var(--border); border-radius: var(--radius-xs); padding: 0 4px; }
.legal__updated { color: var(--text-faint); font-size: var(--fs-xs); }
.legal__footer { color: var(--text-dim); font-size: var(--fs-xs); line-height: 1.6; padding-top: 18px; padding-bottom: 32px; }
@media (max-width: 600px) { .legal__doc { padding: 20px 16px; } }

/* Legal pages' logo links home (the landing page itself uses landing.css). */
.landing__logo { text-decoration: none; color: var(--text); }

/* ---------- Form controls ---------- */
/* Outlined/floating label: the label sits ON the input's top border
   rather than above it, matching the reference screenshots. .field
   already wraps <label> + the control everywhere in the app, so this
   is a pure CSS change — no markup changes needed on any page. */
.field { margin-bottom: 15px; position: relative; }
.field label {
    position: absolute;
    top: -7px; left: 9px;
    max-width: calc(100% - 18px);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    background: var(--surface);
    padding: 0 5px;
    font-size: var(--fs-2xs);
    font-weight: 500;
    color: var(--text-faint);
    line-height: 1;
    z-index: 1;
    pointer-events: none;
}
.field input, .field select, .field textarea {
    width: 100%;
    height: var(--control-h);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 0 10px;
    color: var(--text);
    font-size: var(--fs-xs);
    font-family: var(--font-ui);
}
.field textarea { height: auto; padding: 12px 10px 8px; font-family: var(--font-mono); font-size: var(--fs-xs); resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-tint); }
.field__hint { font-size: var(--fs-2xs); color: var(--text-faint); margin-top: 4px; line-height: 1.4; }

/* Segmented control — a row of mutually-exclusive buttons sharing one
   bordered group, e.g. Lander Type. Wrap real radios so it degrades
   to something usable without JS; style hides the radio itself. */
/* .segmented has no border of its own to "sit on" the way a bordered
   input/select does, so its floating .field label (position:absolute,
   top:-7px) has nothing to visually clear — margin-top here reserves
   the same vertical rhythm a real input's top border would. */
.field .segmented { margin-top: 8px; }
.segmented { display: inline-flex; border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; background: var(--bg); }
.segmented input[type="radio"] { position: absolute; opacity: 0; width: 0; height: 0; }
.segmented label {
    /* .field label (above) sets pointer-events:none for the floating
       field-name label — but that's a descendant selector, so it also
       silently matches these option labels (nested inside .field via
       .segmented) and made every segmented control site-wide unclickable
       by mouse. Restore it explicitly. */
    pointer-events: auto;
    position: static; background: none; padding: 0 16px; height: var(--control-h);
    display: flex; align-items: center; font-size: var(--fs-2xs); font-weight: 500; letter-spacing: 0.02em;
    color: var(--text-faint); cursor: pointer; border-right: 1px solid var(--border);
}
.segmented label:last-child { border-right: none; }
.segmented input[type="radio"]:checked + label { background: var(--surface); color: var(--text); box-shadow: inset 0 0 0 1px var(--border); }
.segmented input[type="radio"]:focus-visible + label { outline: 2px solid var(--brand); outline-offset: -2px; }

/* Plain themed radio (e.g. Offer Sources' Postback Protection choices)
   — for a short vertical/inline list of options where the .segmented
   tab-group look doesn't fit, just a normal radio dot recolored to
   match the theme instead of the raw OS-native control. */
.radio-option {
    display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
    font-size: var(--fs-xs); color: var(--text); font-weight: 400;
}
.radio-option input[type="radio"] {
    appearance: none; -webkit-appearance: none; margin: 0; flex-shrink: 0;
    width: 15px; height: 15px; border: 1.5px solid var(--border); border-radius: 50%;
    background: var(--surface); position: relative; cursor: pointer;
}
.radio-option input[type="radio"]:checked { border-color: var(--brand); }
.radio-option input[type="radio"]:checked::after {
    content: ''; position: absolute; top: 50%; left: 50%; width: 7px; height: 7px;
    border-radius: 50%; background: var(--brand); transform: translate(-50%, -50%);
}
.radio-option input[type="radio"]:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: var(--control-h);
    background: var(--brand);
    color: #fff;
    border: none;
    border-radius: var(--radius-sm);
    padding: 0 14px;
    font-size: var(--fs-xs);
    font-weight: 500;
    cursor: pointer;
    width: 100%;
    white-space: nowrap;
}
.btn:hover { background: var(--brand-hover); }
.btn-inline { width: auto; }
/* Icon buttons (.btn/.btn-secondary with an icon_svg() child) previously
   left the <svg> with no explicit size — with only a viewBox and no
   width/height, a flex item with no natural size and an intrinsic
   ratio sizes itself off the flex line's cross size. Once the text
   wrapped even slightly, the icon inflated to fill that taller line,
   which pushed the text to wrap even more, spiraling into ~50px icons
   and 3-line button labels (Traffic Channels/Offers/Offer Sources).
   .wt-action already avoided this by fixing its icon to 13px; buttons
   need the same explicit size. */
.btn svg, .btn-secondary svg { width: 14px; height: 14px; flex-shrink: 0; }
.form-error {
    background: var(--negative-tint);
    border: 1px solid #F6C6CA;
    color: var(--negative);
    border-radius: var(--radius-sm);
    padding: 8px 11px;
    font-size: var(--fs-xs);
    margin-bottom: 13px;
}
.form-success {
    background: var(--positive-tint);
    border: 1px solid #B7E4CF;
    color: var(--positive);
    border-radius: var(--radius-sm);
    padding: 8px 11px;
    font-size: var(--fs-xs);
    margin-bottom: 13px;
}
.form-info {
    background: #EAF2FE;
    border: 1px solid #C7DCFB;
    color: #1E4C8C;
    border-radius: var(--radius-sm);
    padding: 10px 12px;
    font-size: var(--fs-xs);
    line-height: 1.55;
    margin-bottom: 13px;
}
.form-info ul { margin: 4px 0 0 18px; padding: 0; }

/* ---------- Generic CRUD forms ---------- */
.form-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 13px; padding: 14px; }
.form-grid .field.full { grid-column: 1 / -1; }
.form-actions { padding: 11px 14px; border-top: 1px solid var(--border); display: flex; gap: 9px; }
.form-grid > .form-actions--full { grid-column: 1 / -1; padding: 11px 0 0; }

/* ---------- Alerts page ---------- */
.alerts-meta { font-size: var(--fs-2xs); color: var(--text-faint); }
.alerts-empty { padding: 16px 14px; font-size: var(--fs-xs); color: var(--text-dim); }
.alert-row { padding: 11px 14px; border-bottom: 1px solid var(--border); border-left: 3px solid var(--border); }
.alert-row:last-child { border-bottom: none; }
.alert-row--critical { border-left-color: var(--negative); }
.alert-row--warning { border-left-color: var(--warning); }
.alert-row__head { display: flex; align-items: center; gap: 8px; }
.alert-row__title { font-size: var(--fs-sm); font-weight: 500; color: var(--text); flex: 1; min-width: 0; }
.alert-row__link { font-size: var(--fs-xs); white-space: nowrap; }
.alert-row__body { margin-top: 6px; font-size: var(--fs-xs); color: var(--text-dim); white-space: pre-line; line-height: 1.5; }
.alert-row__meta { margin-top: 6px; font-size: var(--fs-2xs); color: var(--text-faint); }
.alerts-inline-form { display: flex; align-items: center; gap: 10px; }
.alerts-inline-form select {
    height: 28px; padding: 0 8px; font-size: var(--fs-xs); font-family: var(--font-ui);
    border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); color: var(--text);
}
.alerts-check { display: inline-flex; align-items: center; gap: 4px; font-size: var(--fs-xs); color: var(--text-dim); }
.alerts-add-form { border-top: 1px solid var(--border); }
.alerts-table-wrap { overflow-x: auto; }
.alerts-checks { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px 20px; padding: 14px 14px 4px; }
.alerts-check-row { display: flex; align-items: flex-start; gap: 8px; font-size: var(--fs-xs); color: var(--text); cursor: pointer; }
.alerts-check-row input { margin-top: 3px; }
@media (max-width: 720px) { .alerts-checks { grid-template-columns: 1fr; } }

.btn-secondary {
    display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: var(--control-h);
    background: var(--surface); color: var(--text-dim); border: 1px solid var(--border);
    border-radius: var(--radius-sm); padding: 0 14px; font-size: var(--fs-xs); cursor: pointer; text-decoration: none;
    white-space: nowrap;
}
.btn-secondary:hover { color: var(--text); border-color: var(--text-faint); text-decoration: none; background: var(--surface-alt); }

.row-actions a, .row-actions button { margin-right: 10px; font-size: var(--fs-xs); }

.badge {
    display: inline-block;
    font-size: var(--fs-2xs);
    font-weight: 500;
    padding: 2px 8px;
    border-radius: var(--radius-md);
}
.badge.active { background: var(--positive-tint); color: var(--positive); }
.badge.paused { background: var(--warning-tint); color: #92620A; }
.badge.archived { background: var(--surface-alt); color: var(--text-faint); border: 1px solid var(--border); }
.badge.error { background: var(--negative-tint); color: var(--negative); }
.badge.pending { background: var(--surface-alt); color: var(--text-dim); border: 1px solid var(--border); }

.copy-url {
    font-family: var(--font-mono);
    font-size: var(--fs-2xs);
    background: var(--surface-alt);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 6px 9px;
    color: var(--text-dim);
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.copy-url[data-url] { cursor: pointer; }
.copy-url[data-url]:hover { border-color: var(--text-faint); background: var(--surface); }
.copy-url__icon {
    flex-shrink: 0; width: 14px; height: 14px; color: var(--text-faint);
    display: inline-flex; align-items: center; justify-content: center;
}
.copy-url__icon svg { width: 100%; height: 100%; }
.copy-url[data-url]:hover .copy-url__icon { color: var(--brand); }
.copy-url--copied .copy-url__icon { color: var(--positive); }
.copy-url__feedback {
    display: none; font-family: var(--font-ui); font-weight: 500; font-size: var(--fs-2xs); color: var(--positive);
}
.copy-url--copied .copy-url__feedback { display: inline; }
.copy-url--copied .copy-url__text { display: none; }
.copy-url button { background: none; border: none; color: var(--brand); cursor: pointer; font-size: var(--fs-2xs); font-family: var(--font-ui); font-weight: 500; }

/* ---------------- Full-page Campaign editor (replaces the old centered modal) ----------------
   No backdrop, no fixed max-width "dialog" box — this occupies the same
   .content area the Campaigns list itself uses, so switching between
   ?action=new/edit and the plain list is just two mutually-exclusive
   blocks of markup in the same page, not a modal over a page. */
.editor-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.editor-header__title { font-size: var(--fs-xl); font-weight: 600; color: var(--text); }
.editor-header__actions { display: flex; gap: 8px; }

.editor-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin-bottom: 0; }
.editor-tab {
    display: inline-block; padding: 8px 4px; margin-right: 18px;
    font-size: var(--fs-xs); font-weight: 500; color: var(--text-faint);
    border-bottom: 2px solid transparent; margin-bottom: -1px; text-decoration: none;
}
.editor-tab:hover { color: var(--text); text-decoration: none; }
.editor-tab.active { color: var(--brand); border-bottom-color: var(--brand); }

.editor-body { background: var(--bg); padding: 14px 2px 20px; }
.editor-columns { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 14px; align-items: start; }
.editor-col-left, .editor-col-right { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
@media (max-width: 1100px) {
    .editor-columns { grid-template-columns: 1fr; }
}
.editor-footer { display: flex; justify-content: flex-end; gap: 8px; padding-top: 14px; margin-top: 4px; border-top: 1px solid var(--border); }

/* Tracking Code is a secondary/generated identifier, not a primary
   field — de-emphasized so it doesn't visually compete with Campaign
   Name, per the redesign's explicit ask. */
.editor-field--secondary label { font-weight: 400; }
.editor-field--secondary input { font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--text-dim); }

/* Tighter card/field density, scoped to the editor specifically — the
   shared .modal-section/.form-grid classes keep their normal spacing
   everywhere else (Traffic Channels, Offers, Landers, ...); only this
   page's cards get the denser treatment the correction pass asked for. */
.editor-body .modal-section { padding: 11px 13px; margin-bottom: 10px; }
.editor-body .modal-section__title { font-size: var(--fs-xs); margin-bottom: 9px; }
.editor-body .form-grid { gap: 9px; padding: 0; }
.editor-body .field { margin-bottom: 0; }
.editor-body .field input, .editor-body .field select { height: 30px; }
.editor-body .modal-subsection-title { padding-top: 9px; margin-top: 9px; margin-bottom: 7px; }

/* Campaign Tracking URL / No-Redirect script fields read as long text
   blocks by default (.copy-url wraps) — inside the editor specifically,
   make them behave like a single-line read-only technical field
   (truncated with an ellipsis, not wrapped) since the full value is
   always available via the copy action anyway. Scoped to .editor-body
   so .copy-url's normal wrapping behavior elsewhere (e.g. the Campaigns
   list) is untouched. */
.editor-body .copy-url { max-width: 100%; border-radius: var(--radius-xs); }
.editor-body .copy-url__text {
    overflow: hidden; white-space: nowrap; text-overflow: ellipsis; min-width: 0;
}

/* Boxed-tab treatment shared by both tab groups in the editor:
   #tm-tabs (Tracking Links & Parameters -> tracking_method) and
   .funnel-mode-tabs (Funnel #1 -> flow_type). Deliberately distinct
   controls over different fields (see the markup's own comments) but
   the same discrete-box-with-blue-underline visual, so the editor
   doesn't invent two different tab languages for the same concept. */
.tm-tabs, .funnel-mode-tabs { display: inline-flex; }
.tm-tabs__tab, .funnel-mode-tabs__tab {
    box-sizing: border-box; appearance: none; cursor: pointer;
    font-family: var(--font-ui); font-weight: 500; text-transform: uppercase; letter-spacing: .3px;
    background: var(--surface-alt); color: var(--text-faint);
    border: 1px solid var(--border); border-right-width: 0;
    border-bottom-width: 3px; border-bottom-color: transparent;
}
.tm-tabs__tab:first-child, .funnel-mode-tabs__tab:first-child { border-radius: var(--radius-xs) 0 0 var(--radius-xs); }
.tm-tabs__tab:last-child, .funnel-mode-tabs__tab:last-child { border-right-width: 1px; border-radius: 0 var(--radius-xs) var(--radius-xs) 0; }
.tm-tabs__tab:hover:not(.active), .funnel-mode-tabs__tab:hover:not(.active) { color: var(--text-dim); }
.tm-tabs__tab.active, .funnel-mode-tabs__tab.active { background: var(--surface); color: var(--text); border-bottom-color: var(--brand); }
.tm-tabs__tab { height: 29px; padding: 0 11px; font-size: var(--fs-2xs); margin-bottom: 10px; }
.funnel-mode-tabs__tab { height: 28px; padding: 0 9px; font-size: var(--fs-2xs); }

/* Small visual "Funnel #1" header inside the Funnels card — this is a
   presentational label only; SMFlow has exactly one implicit funnel
   per campaign (its own campaign_routes), not a bundled offer+lander
   unit like the reference's Funnels feature. */
/* One border per Funnel — the primary grouping unit now that a campaign
   can have several — is kept; everything nested INSIDE it (route rows,
   the Filters builder) intentionally does NOT repeat its own border/card
   background, so multiple Funnels don't turn into boxes-within-boxes.
   Funnel blocks stack with a visible gap instead of touching. */
#funnel-blocks { display: flex; flex-direction: column; gap: 14px; }
.funnel-block { border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); padding: 12px; }
.funnel-block__header { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; flex-wrap: wrap; }
.funnel-block__badge {
    display: inline-flex; align-items: center; background: var(--surface-alt); border: 1px solid var(--border);
    border-radius: var(--radius-xs); padding: 3px 9px; font-size: var(--fs-2xs); font-weight: 600; color: var(--text-dim);
    flex-shrink: 0;
}
/* Small "Funnel label" box, styled like the reference — an internal-only
   organizational name, never sent to the routing engine. */
.funnel-label-input {
    flex: 1 1 180px; min-width: 140px; height: 30px; padding: 0 10px;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--text); font-size: var(--fs-xs); font-family: var(--font-ui);
}
.funnel-label-input:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-tint); }
.funnel-label-input::placeholder { color: var(--text-faint); }
.funnel-block__weight { flex-shrink: 0; width: 76px; margin-bottom: 0; }
.funnel-block__weight input { height: 30px; text-align: center; }

/* Small info tooltip icon next to the "Funnels" section title, replacing
   the previous always-visible explanatory paragraph — same content,
   shown on hover/focus via the native title attribute so it doesn't
   consume vertical space in the card by default. */
.editor-body .modal-section__title { display: flex; align-items: center; gap: 6px; }
.modal-section__title-actions { display: inline-flex; align-items: center; gap: 8px; }
.info-tip { display: inline-flex; color: var(--text-faint); cursor: help; }
.info-tip svg { width: 13px; height: 13px; }
.info-tip:hover, .info-tip:focus-visible { color: var(--text-dim); outline: none; }

/* Icon-only variant of .copy-url — e.g. the Campaigns list's compact
   "copy tracking link" action, where there's no room for the text/label.
   The icon itself still flips to --positive on a successful copy
   (via the existing .copy-url--copied rule above), which is feedback
   enough without a text label. */
.copy-url--icon-only { width: 26px; height: 26px; padding: 0; justify-content: center; gap: 0; }
.copy-url--icon-only .copy-url__text, .copy-url--icon-only .copy-url__feedback { display: none; }

/* ---------- Compact icon-only row actions (Copy Link / Edit / Duplicate / Reports, etc.) ---------- */
.icon-btn-row { display: inline-flex; align-items: center; gap: 4px; }
.icon-btn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 26px; height: 26px; flex-shrink: 0;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--text-faint);
    cursor: pointer; text-decoration: none; padding: 0;
}
.icon-btn svg { width: 14px; height: 14px; }
.icon-btn:hover { color: var(--brand); border-color: var(--text-faint); background: var(--surface-alt); text-decoration: none; }
.icon-btn.is-disabled { opacity: 0.4; cursor: not-allowed; pointer-events: none; }

.btn-secondary__icon { display: inline-flex; width: 12px; height: 12px; }
.btn-secondary__icon svg { width: 100%; height: 100%; }

/* ---------- Funnel-style route rows (Campaigns modal, Routing tab) ----------
   Deliberately NOT its own bordered/background card anymore — it already
   lives inside a bordered .funnel-block, and a Filters builder can open
   beneath it, so giving the row its own box too was exactly the
   "box inside a box inside a box" nesting this was asked to flatten.
   A bottom divider (removed on the last row) is enough separation. */
.funnel-route-card { padding: 7px 0; border-bottom: 1px solid var(--border); }
.funnel-route-card:last-child { border-bottom: none; }
.funnel-route-card__main { display: flex; align-items: center; gap: 6px; height: 30px; }
.funnel-route-card__index {
    flex-shrink: 0; width: 16px; height: 16px; border-radius: 50%;
    background: var(--surface-alt); color: var(--text-faint);
    font-size: 9.5px; font-weight: 500; display: inline-flex; align-items: center; justify-content: center;
}
/* Explicit control widths per control, not a blanket width:100% on the
   row — a route row is number + selector + weight + settings + remove,
   and the selector must not visually swallow the whole Funnel card. */
.funnel-route-card__select { flex: 1 1 auto; min-width: 0; max-width: 62%; }
.funnel-route-card__select select {
    width: 100%; height: 30px; padding: 0 8px;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--text); font-size: var(--fs-xs); font-family: var(--font-ui);
}
.funnel-route-card__select select:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-tint); }
.funnel-route-card__weight { flex-shrink: 0; width: 62px; }
.funnel-route-card__weight input {
    height: 30px; width: 100%; padding: 0 6px; text-align: center; font-size: var(--fs-xs);
    border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); color: var(--text); font-family: var(--font-ui);
}
.funnel-route-card__weight input:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-tint); }

/* Ghost icon buttons for the route row's settings/remove actions —
   borderless until hover, so they read as row-level utility actions
   rather than bordered buttons competing with the select/weight fields. */
.icon-btn--ghost { width: 24px; height: 24px; border-color: transparent; background: none; }
.icon-btn--ghost:hover { background: var(--surface-alt); border-color: var(--border); }
.icon-btn--ghost svg { width: 13px; height: 13px; }

/* "+ Add" route action — the one place green is used in the Funnel
   card, reserved for this add-action so it doesn't compete visually
   with the neutral Filters control. Reuses --positive, the same green
   already used for Active/positive-metric states elsewhere. Solid
   (not the earlier pale tint) so it has enough contrast to read as an
   intentional action, not a disconnected pastel rectangle. */
.btn-add {
    display: inline-flex; align-items: center; gap: 4px;
    height: 26px; padding: 0 10px; font-size: var(--fs-2xs); font-weight: 500;
    background: var(--positive); color: #fff; border: 1px solid var(--positive);
    border-radius: var(--radius-xs); text-decoration: none; cursor: pointer;
}
.btn-add:hover { filter: brightness(0.93); color: #fff; text-decoration: none; }
.btn-add .btn-secondary__icon svg { width: 100%; height: 100%; }

/* ---------- Custom select appearance (replaces native browser chrome) ----------
   The previous pass's regression: this SVG data-URI has no explicit
   width/height on the <svg> element, and no background-size was set
   here, so on browsers that fall back to a replaced-element's default
   intrinsic size (300x150) for an unsized SVG, "background-size: auto"
   rendered the chevron at that huge scale instead of its viewBox size.
   Fixed by pinning background-size explicitly — the chevron is always
   9x5px on screen regardless of how the browser sizes the source image. */
.editor-body select {
    appearance: none; -webkit-appearance: none; -moz-appearance: none;
    background-color: var(--surface);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%2398A2B3' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 9px center;
    background-size: 9px 5px;
    padding-right: 26px;
    border: 1px solid var(--border);
    border-radius: var(--radius-xs);
    font-size: var(--fs-2xs);
    color: var(--text);
}
.editor-body select:hover { border-color: var(--text-faint); }
.editor-body select:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 2px var(--brand-tint); }
.editor-body select:disabled { background-color: var(--surface-alt); color: var(--text-faint); cursor: not-allowed; }

/* ---------- Route card Filters (dynamic routing-rule builder) ---------- */
.funnel-filters { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); }
.funnel-filters-pill-wrap { position: relative; }
/* Now matches .btn-add's green (same "+Add" tone used elsewhere in the
   Funnel card) rather than a neutral gray pill — Filters is common
   enough to configure that it earns the same visual weight as Add. */
.filters-btn {
    display: inline-flex; align-items: center; gap: 6px;
    background: var(--positive); color: #fff; border: 1px solid var(--positive); border-radius: var(--radius-sm);
    height: 28px; padding: 0 11px; font-size: var(--fs-2xs); font-weight: 600; text-transform: uppercase; letter-spacing: .3px;
    cursor: pointer;
}
.filters-btn svg { width: 12px; height: 12px; }
.filters-btn:hover { filter: brightness(0.93); }
.filters-btn__count {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 16px; height: 16px; padding: 0 4px; border-radius: var(--radius-pill);
    background: rgba(255,255,255,0.28); color: #fff; font-size: var(--fs-2xs); font-weight: 600;
}
.filters-btn__chevron { font-size: 8px; line-height: 1; color: #fff; }

/* The whole collapsible configuration area (preset + add filter +
   configured rows) — collapsed by default regardless of how many
   filters already exist, per the spec's own acceptance test. A tinted
   background (not a bordered card) is enough separation here — it
   already sits inside a route row inside a bordered Funnel block, so a
   third nested border would be exactly the "box inside a box inside a
   box" this was asked to flatten. */
.filters-panel {
    margin-top: 8px; padding: 10px; background: var(--surface-alt);
    border-radius: var(--radius-sm);
}
.filters-panel__row { display: flex; gap: 10px; flex-wrap: wrap; }
.filters-panel__preset { flex: 1; min-width: 180px; }
.filters-panel__or { font-size: var(--fs-2xs); color: var(--text-faint); margin: 8px 0 6px; }

.filters-menu {
    position: absolute; top: calc(100% + 4px); left: 0; z-index: 20; width: 240px; max-width: 90vw;
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm);
    box-shadow: 0 4px 14px rgba(20,24,32,0.12); padding: 4px;
    max-height: 260px; overflow-y: auto;
}
.filters-menu__group { padding: 2px 0; }
.filters-menu__group-title {
    font-size: 9.5px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em;
    color: var(--text-faint); padding: 5px 10px 3px;
}
.filters-menu a {
    display: block; padding: 7px 10px; font-size: var(--fs-xs); color: var(--text); text-decoration: none; border-radius: var(--radius-xs);
}
.filters-menu a:hover { background: var(--surface-alt); text-decoration: none; }

.filters-table { width: 100%; margin-top: 8px; font-size: var(--fs-xs); border-collapse: separate; border-spacing: 0; background: var(--surface-alt); border-radius: var(--radius-sm); }
.filters-table th {
    text-align: left; font-size: var(--fs-2xs); font-weight: 500; color: var(--text-faint);
    padding: 6px 8px; border-bottom: 1px solid var(--border);
}
.filters-table td { padding: 6px 8px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.filters-table tr:last-child td { border-bottom: none; }
/* Every field inside the Filters builder (mode/value selects, the value
   textbox, the sub-number picker, the Add Filter search box, the preset
   select) shares this same rounded/bordered/opacity-aware look — this
   is the one place that styling is defined, rather than each control
   relying on the browser's native (square-cornered) appearance, which
   is what made them look visually inconsistent with the rest of
   SMFlow's fields. */
.filters-table select, .filters-table input[type="text"],
.filters-add-input, .filters-panel select,
.chip-input__field {
    height: 28px; width: 100%; padding: 0 9px;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--text); font-size: var(--fs-xs); font-family: var(--font-ui);
}
.filters-table select:focus, .filters-table input[type="text"]:focus,
.filters-add-input:focus, .filters-panel select:focus {
    outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-tint);
}
.filters-panel select:disabled { opacity: 0.6; cursor: not-allowed; background: var(--surface-alt); }
/* Subs row — one compact label+textbox pair per sub1..sub20, scrollable
   once it exceeds a few rows rather than blowing out the whole card. */
.sub-multi-list {
    display: flex; flex-direction: column; gap: 4px;
    max-height: 220px; overflow-y: auto; padding-right: 2px;
}
.sub-multi-row { display: flex; align-items: center; gap: 6px; }
.sub-multi-row label { flex: 0 0 34px; font-size: var(--fs-2xs); font-weight: 500; color: var(--text-faint); }
.sub-multi-row input { flex: 1; }
.filters-panel__preset select { height: 30px; }

/* Removable-chip multi-value input (Country/Device/OS/Browser) — see
   funnelInitChipInput() in campaigns.php. The real submitted value
   stays the hidden .f-value sibling; this is purely presentational.
   .f-value-wrap is the positioning context for the dropdown below (see
   .chip-search-menu) so the two read as one control, not a box with a
   separate popup floating under it. */
.f-value-wrap { position: relative; }
.chip-input {
    display: flex; flex-wrap: wrap; gap: 4px; align-items: center;
    min-height: 28px; padding: 3px 5px; border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface);
}
.chip-input:focus-within { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-tint); }
/* When its dropdown is open, square off the bottom of the box and hide
   its bottom border (same color as the box's own background, so it
   disappears against the menu sitting flush beneath it) — the two
   pieces read as one control that's simply grown taller, not a box
   with a second, separate floating card under it. */
.chip-input.chip-input--menu-open {
    border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-tint);
    border-bottom-left-radius: 0; border-bottom-right-radius: 0; border-bottom-color: var(--surface);
}
.chip-input__chips { display: flex; flex-wrap: wrap; gap: 4px; }
.chip-input__chip {
    display: inline-flex; align-items: center; gap: 4px;
    background: var(--brand-tint); color: var(--brand); border-radius: var(--radius-pill);
    padding: 2px 4px 2px 8px; font-size: var(--fs-2xs); font-weight: 500; white-space: nowrap;
}
.chip-input__chip button {
    background: none; border: none; color: inherit; cursor: pointer; padding: 0 2px; font-size: var(--fs-xs); line-height: 1;
    opacity: 0.7;
}
.chip-input__chip button:hover { opacity: 1; }
.chip-input__field {
    flex: 1; min-width: 70px; border: none; height: 21px; padding: 0 2px; font-size: var(--fs-xs);
    background: transparent; color: var(--text);
}
.chip-input__field:focus { outline: none; }

/* Searchable chip-value dropdown (Country/Device/OS/Browser) — spans
   the exact width of .chip-input and sits flush against its bottom
   edge (negative margin overlaps the 1px border, same border color, no
   top corners) so opening it looks like the input box itself grew
   downward into a list, not like a second, separate floating card. */
.chip-search-menu {
    position: absolute; top: 100%; left: 0; right: 0; z-index: 30;
    margin-top: -1px;
    max-height: 220px; overflow-y: auto;
    background: var(--surface); border: 1px solid var(--brand); border-top-color: var(--surface);
    border-radius: 0 0 var(--radius-sm) var(--radius-sm);
    box-shadow: 0 6px 14px rgba(20,24,32,0.12); padding: 4px;
}
.chip-search-menu a {
    display: block; padding: 6px 9px; font-size: var(--fs-xs); color: var(--text); text-decoration: none; border-radius: var(--radius-xs);
}
.chip-search-menu a:hover { background: var(--surface-alt); text-decoration: none; }
.chip-search-menu__empty { padding: 6px 9px; font-size: var(--fs-xs); color: var(--text-faint); }

/* Narrow screens: a 4-column grid table stops being usable, so each
   filter row becomes a labeled stack instead (Filter by / Type / Value
   / remove) — same data-label technique used nowhere else in this file
   yet, added here rather than a generic utility since this is currently
   the only place a table row needs to become a card on mobile. */
@media (max-width: 560px) {
    .filters-table, .filters-table thead, .filters-table tbody, .filters-table tr, .filters-table td { display: block; width: 100%; }
    .filters-table thead { display: none; }
    .filters-table tr { padding: 8px; border-bottom: 2px solid var(--border); }
    .filters-table td { border-bottom: none; padding: 4px 0; }
    .filters-table td[data-label]:not([data-label=""])::before {
        content: attr(data-label); display: block; font-size: 9.5px; font-weight: 600; text-transform: uppercase;
        letter-spacing: .04em; color: var(--text-faint); margin-bottom: 2px;
    }
}

/* ---------- Tabs (reused by tool pages, modal forms, log viewer) ---------- */
.tabbar { display: flex; gap: 2px; margin-bottom: 14px; border-bottom: 1px solid var(--border); }
.tab-link {
    display: inline-block;
    border-left: none;
    padding: 8px 14px;
    font-size: var(--fs-xs);
    font-weight: 500;
    color: var(--text-dim);
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
}
.tab-link:hover { color: var(--text); text-decoration: none; }
.tab-link.active { color: var(--brand); font-weight: 500; border-bottom-color: var(--brand); }

/* ---------- Tooltip ---------- */
.tt { position: relative; display: inline-flex; align-items: center; cursor: help; color: var(--text-faint); }
.tt .tt-bubble {
    display: none;
    position: absolute; bottom: 130%; left: 50%; transform: translateX(-50%);
    background: var(--topbar); color: #fff; font-size: var(--fs-2xs); font-weight: 400;
    padding: 6px 9px; border-radius: var(--radius-sm); white-space: normal; width: 220px; z-index: 40;
    line-height: 1.4;
}
.tt:hover .tt-bubble { display: block; }

/* ---------- Reusable modal / drawer system ----------
   Same overlay markup and classes for every entity's create/edit form.
   Backdrop + panel; sticky header and footer, scrollable body. No page
   using this needs its own bespoke modal CSS. */
.modal-backdrop {
    position: fixed; inset: 0; background: rgba(20,24,32,0.42);
    display: flex; align-items: flex-start; justify-content: center;
    padding: 40px 20px; z-index: 100; overflow-y: auto;
}
.modal {
    background: var(--surface);
    border-radius: var(--radius-md);
    width: 100%; max-width: 1180px;
    box-shadow: 0 4px 18px rgba(20,24,32,0.14);
    display: flex; flex-direction: column;
    max-height: calc(100vh - 60px);
}
.modal--narrow { max-width: 760px; }
.modal--wide { max-width: 1400px; }
.modal__header {
    position: sticky; top: 0; background: var(--surface);
    padding: 14px 20px; border-bottom: 1px solid var(--border);
    display: flex; align-items: center; justify-content: space-between;
    border-radius: var(--radius-md) var(--radius-md) 0 0;
}
.modal__title { font-size: var(--fs-md); font-weight: 500; }
.modal__header-actions { display: flex; gap: 8px; align-items: center; }
.modal__close { background: none; border: none; color: var(--text-faint); font-size: var(--fs-xl); cursor: pointer; padding: 4px 8px; line-height: 1; }
.modal__close:hover { color: var(--text); }
.modal__tabs { display: flex; gap: 2px; padding: 0 20px; border-bottom: 1px solid var(--border); background: var(--surface); }
.modal__body { overflow-y: auto; flex: 1; }
.modal__section-label { font-size: var(--fs-2xs); font-weight: 500; color: var(--text-dim); padding: 14px 14px 0; }

/* Opt-in "long scroll of cards" body variant (e.g. Campaigns' Edit
   modal) — a light backdrop with each section as its own bordered
   card, rather than the plain white .modal__body every other modal on
   the site still uses. Scoped entirely to these two new classes so it
   never touches the shared .modal__body/.modal__section-label rules
   other pages' modals rely on. */
.modal__body--sectioned { background: var(--bg); padding: 14px; }
.modal-section {
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md);
    padding: 13px 15px; margin-bottom: 12px;
}
.modal-section:last-child { margin-bottom: 0; }
.modal-section__title {
    font-size: var(--fs-xs); font-weight: 500; color: var(--text);
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    margin-bottom: 11px;
}
.modal-section__title-note { font-weight: 400; color: var(--text-faint); font-size: var(--fs-2xs); }
.modal-section > .form-grid { padding: 0; } /* form-grid's own padding would double up with the card's */
.modal-subsection-title {
    font-size: var(--fs-2xs); font-weight: 500; color: var(--text-dim);
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    padding-top: 11px; margin-top: 11px; margin-bottom: 8px; border-top: 1px dashed var(--border);
}
.modal-subsection-title:first-child { padding-top: 0; margin-top: 0; border-top: none; }
.modal__footer {
    position: sticky; bottom: 0; background: var(--surface);
    padding: 12px 20px; border-top: 1px solid var(--border);
    display: flex; gap: 9px; justify-content: flex-end;
    border-radius: 0 0 var(--radius-md) var(--radius-md);
}
.modal__footer .btn, .modal__footer .btn-secondary { width: auto; }

/* ---------- Columns Settings modal (shared across every entity page) ---------- */
.cs-search {
    height: 30px; padding: 0 10px; font-size: var(--fs-xs); border: 1px solid var(--border);
    border-radius: var(--radius-sm); background: var(--surface); color: var(--text);
}
.cs-cat {
    font-size: var(--fs-2xs); font-weight: 600; text-transform: uppercase; letter-spacing: .04em;
    color: var(--text-faint); padding: 8px 10px 4px; background: var(--surface-alt);
    position: sticky; top: 0;
}
.cs-row {
    display: flex; align-items: center; gap: 8px; padding: 6px 10px;
    border-bottom: 1px solid var(--border); font-size: var(--fs-xs);
}
.cs-row:hover { background: var(--surface-alt); }
.cs-row__text { flex: 1; min-width: 0; }
.cs-row__label { font-weight: 500; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cs-row__desc { font-size: var(--fs-2xs); color: var(--text-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cs-row--draggable { cursor: grab; }
.cs-row--draggable.is-dragging { opacity: 0.4; background: var(--brand-tint); }
.cs-drag-handle { color: var(--text-faint); cursor: grab; line-height: 1; letter-spacing: -2px; }
.cs-row button.wt-action { padding: 3px 8px; flex-shrink: 0; }

/* Macro chips (URL macro pickers on Offers/Landers) */
.macro-chip {
    display: inline-block; font-family: var(--font-mono); font-size: var(--fs-2xs); font-weight: 500;
    background: var(--surface-alt); border: 1px solid var(--border); color: var(--text-dim);
    border-radius: var(--radius-pill); padding: 3px 9px; margin: 2px 3px 2px 0; cursor: pointer;
}
.macro-chip:hover { border-color: var(--brand); color: var(--brand); text-decoration: none; background: var(--brand-tint); }

.saving-indicator { font-size: var(--fs-2xs); color: var(--text-faint); margin-left: 8px; }

/* ---------------- Dashboard hero KPI cards ---------------- */
.hero-kpi-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-bottom: 16px; }
.hero-kpi { border-radius: var(--radius-md); overflow: hidden; border: 1px solid var(--border); background: var(--surface); }
.hero-kpi__head { display: flex; align-items: center; gap: 10px; padding: 14px 16px; }
.hero-kpi__icon { width: 30px; height: 30px; border-radius: var(--radius-md); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.hero-kpi__icon svg { width: 17px; height: 17px; }
.hero-kpi__title { font-size: var(--fs-md); font-weight: 600; color: var(--text); }
.hero-kpi__body { background: var(--surface); padding: 14px 16px 16px; display: grid; grid-template-columns: 1fr 1fr; gap: 14px 10px; }
.hero-kpi__period { font-size: var(--fs-2xs); color: var(--text-faint); margin-bottom: 3px; }
.hero-kpi__value { font-size: var(--fs-xl); font-weight: 600; color: var(--text); }
.hero-kpi__value--sub { font-size: var(--fs-md); font-weight: 500; color: var(--text-dim); }
.hero-kpi--blue .hero-kpi__head { background: #EAF0FE; }
.hero-kpi--blue .hero-kpi__icon { background: #3D6FE0; color: #fff; }
.hero-kpi--green .hero-kpi__head { background: #EAF7EE; }
.hero-kpi--green .hero-kpi__icon { background: #2E9E52; color: #fff; }
.hero-kpi--orange .hero-kpi__head { background: #FDF1E4; }
.hero-kpi--orange .hero-kpi__icon { background: #E08A2E; color: #fff; }

/* ---------------- Best performing panels ---------------- */
.best-performing-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-bottom: 16px; align-items: start; }
.best-perf-label { font-size: var(--fs-xs); font-weight: 500; color: var(--text-dim); margin: 10px 0 6px; }
.best-perf-label:first-child { margin-top: 0; }
.best-perf-empty { font-size: var(--fs-xs); color: var(--text-faint); padding-bottom: 8px; }
.best-perf-table { width: 100%; border-collapse: collapse; margin-bottom: 4px; }
.best-perf-table td { padding: 4px 0; font-size: var(--fs-xs); border-bottom: 1px solid var(--border); }
.best-perf-table tr:last-child td { border-bottom: none; }
.best-perf-table__name { color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 1px; width: 60%; }
.best-perf-table td:not(.best-perf-table__name) { text-align: right; color: var(--text-dim); }

@media (max-width: 1100px) {
    .hero-kpi-grid, .best-performing-grid { grid-template-columns: 1fr; }
}

/* ---------------- Toolbar dropdown panels (Columns / Density / Status) ---------------- */
.columns-panel {
    display: none;
    position: absolute; top: calc(100% + 4px); right: 0;
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm);
    box-shadow: 0 6px 18px rgba(20,24,32,0.12);
    padding: 8px; min-width: 180px; z-index: 30;
    max-height: 320px; overflow-y: auto;
}
.columns-panel.open { display: block; }
.columns-panel label { display: flex; align-items: center; gap: 7px; padding: 4px 6px; font-size: var(--fs-xs); font-weight: 400; color: var(--text); cursor: pointer; }
.columns-panel label:hover { background: var(--surface-alt); border-radius: 4px; }

.text-faint { color: var(--text-faint); }

/* ============================================================
   Logs -> Clicks — dense, wide, horizontally-scrollable forensic
   table. Reuses existing tokens/components (.workspace-filterbar,
   .wf-field, .wt-action, .columns-panel) rather than inventing a
   parallel set, per the shared "reuse existing SMFlow components"
   convention every other dense-table page already follows.
   ============================================================ */
.logs-clicks-filterbar { margin-bottom: 10px; }
.columns-panel--wide { min-width: 240px; max-height: 420px; columns: 1; }
.columns-panel__group {
    font-size: var(--fs-2xs); font-weight: 600; text-transform: uppercase; letter-spacing: .04em;
    color: var(--text-faint); padding: 8px 6px 3px; border-top: 1px solid var(--border);
}
.columns-panel__group:first-child { border-top: none; padding-top: 4px; }

.logs-clicks-wrap {
    overflow: auto; max-height: calc(100vh - 260px);
    border: 1px solid var(--border); border-radius: var(--radius-xs);
    background: var(--surface); margin-top: 10px;
}
/* width: max-content ALONE (no min-width: 100%) is deliberate — a
   min-width:100% here would force the table to stretch to fill its
   container whenever content is naturally narrower than the viewport,
   and CSS auto table layout treats a cell's width/max-width as a
   distribution HINT rather than a hard cap once the table is stretched
   wider than the sum of its columns' natural widths: the browser hands
   that forced extra space back to the columns, which is exactly what
   was inflating the numeric columns (e.g. CPC/Clicks/Cost) well past
   their sm-col-* caps. Content-only sizing means a narrow table just
   stays narrow (leaving blank space in the wrap, which is fine — see
   the "don't stretch to fill the viewport" requirement) and a wide one
   still triggers .logs-clicks-wrap's own overflow:auto scroll. */
.logs-clicks-table, .landers-table { border-collapse: collapse; width: max-content; font-family: var(--font-ui); }
/* Offers' plain CRUD table reuses .logs-clicks-wrap purely for its
   overflow-x scroll container so it behaves like Landers/Traffic
   Channels/Offer Sources on narrow screens. Scoped to a direct .data-table
   child of this wrap (not the bare .data-table selector) so every other
   page still using .data-table elsewhere keeps its current width:100%
   layout untouched — only the table(s) actually placed in this wrapper
   gain content-driven sizing, same reasoning as above, which is what
   lets the wrap's overflow:auto actually engage instead of the table
   just squishing its columns down to fit. */
.logs-clicks-wrap > table.data-table { width: max-content; }
.logs-clicks-table th, .logs-clicks-table td, .landers-table th, .landers-table td {
    font-size: var(--fs-2xs); line-height: 1.3; padding: 0 8px; height: 27px;
    border-right: 1px solid var(--border); border-bottom: 1px solid var(--border);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    max-width: 240px;
}
.logs-clicks-table th, .landers-table th {
    position: sticky; top: 0; z-index: 2;
    background: var(--surface-alt); color: var(--text-dim); font-weight: 500; text-align: left;
    height: 30px;
}
.logs-clicks-table th.is-sortable, .landers-table th.is-sortable { cursor: pointer; }
.logs-clicks-table th.is-sortable:hover, .landers-table th.is-sortable:hover { color: var(--text); }
.logs-clicks-table tbody tr:hover td, .landers-table tbody tr:hover td { background: var(--surface-alt); }
.logs-clicks-table td.mono, .landers-table td.mono { font-family: var(--font-mono); }
.logs-clicks-table td.num, .landers-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.logs-clicks-table .click-id-link { color: var(--brand); text-decoration: none; font-family: var(--font-mono); }
.logs-clicks-table .click-id-link:hover { text-decoration: underline; }
.logs-clicks-table [data-col].col-hidden, .landers-table [data-col].col-hidden { display: none; }

/* ============================================================
   UNIFIED COLUMN-WIDTH SYSTEM — single source of truth for every
   entity/reporting table (Landers, Traffic Channels, Offer Sources,
   Offers, CAPI, Reports). Changing a width here updates every table
   that uses it; no page hand-rolls its own numeric column widths.
   (Campaigns' own resizable .campaigns-grid table is exempt by
   design — its per-user drag-resized <colgroup> widths are already a
   MORE capable system than a fixed width, and table-layout:fixed
   ignores td-level width/min-width/max-width on later rows anyway, so
   these rules are harmless no-ops there.)

   Two ways to opt in:
     1. Automatic — give the <th>/<td> a data-col="clicks" / "revenue" /
        etc. attribute using one of SMFlow's existing canonical metric
        key names (every reporting table already emits these). No class
        needed; matched below by attribute value.
     2. Explicit — apply .sm-col-num / .sm-col-pct / .sm-col-money /
        .sm-col-status / .sm-col-context / .sm-col-entity / .sm-col-id /
        .sm-col-tiny directly when a column's key doesn't match the
        canonical vocabulary (e.g. a bespoke Logs page column).

   The root problem this fixes: with auto table layout, a column sizes
   to its WIDEST cell including the header — so a one-line header like
   "Total Revenue" was forcing a ~100px-wide column even though every
   value in it is short ("$12.40"). The th rules below let the header
   wrap onto ~2 lines instead, so the column can actually shrink to fit
   its (short) data.

   These are override utility rules layered on top of several different
   base table components (.logs-clicks-table, .data-table, .report-table)
   that each already declare their own max-width/padding at equal or
   higher CSS specificity — `!important` here is deliberate, the same
   way a utility-class layer always needs to beat component base
   styles, not an accident of fighting inline styles. */
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) [data-col="clicks"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) [data-col$="_clicks"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) [data-col="lp_views"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) [data-col="conversions"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) [data-col="unique_clicks"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) [data-col="unique_conversions"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) [data-col^="event_"],
.sm-col-num {
    width: 74px !important; min-width: 60px !important; max-width: 90px !important; text-align: right !important; white-space: nowrap !important;
}
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) [data-col="cr"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) [data-col="roi"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) [data-col="lp_click_ctr"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) [data-col="roas"],
.sm-col-pct {
    width: 76px !important; min-width: 64px !important; max-width: 90px !important; text-align: right !important; white-space: nowrap !important;
}
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) [data-col="cpa"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) [data-col="cpc"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) [data-col="epc"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) [data-col="revenue"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) [data-col="cost"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) [data-col="profit"],
.sm-col-money {
    width: 92px !important; min-width: 76px !important; max-width: 112px !important; text-align: right !important; white-space: nowrap !important;
}
.sm-col-id { width: 44px !important; min-width: 40px !important; max-width: 65px !important; text-align: right !important; }
.sm-col-tiny { width: 28px !important; min-width: 28px !important; max-width: 40px !important; }
.sm-col-status { width: 88px !important; min-width: 75px !important; max-width: 100px !important; }
.sm-col-context { width: 130px !important; min-width: 100px !important; max-width: 150px !important; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sm-col-entity { width: auto !important; min-width: 180px !important; max-width: 300px !important; }

/* Header text may wrap onto ~2 lines for the narrow columns above
   instead of forcing the column wide enough for one line of text —
   see the block comment above for why this is the actual fix. */
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) th[data-col="clicks"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) th[data-col$="_clicks"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) th[data-col="lp_views"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) th[data-col="conversions"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) th[data-col="unique_clicks"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) th[data-col="unique_conversions"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) th[data-col^="event_"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) th[data-col="cr"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) th[data-col="roi"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) th[data-col="lp_click_ctr"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) th[data-col="roas"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) th[data-col="cpa"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) th[data-col="cpc"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) th[data-col="epc"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) th[data-col="revenue"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) th[data-col="cost"],
:is(.logs-clicks-table, .landers-table, .report-table, .data-table) th[data-col="profit"],
th.sm-col-num, th.sm-col-pct, th.sm-col-money, th.sm-col-status, th.sm-col-context {
    white-space: normal !important; line-height: 1.15; vertical-align: bottom; word-break: normal;
}

/* ---------- Landers report table specifics ---------- */
.landers-table th:nth-child(-n+3) { position: sticky; z-index: 3; }
.landers-table th:nth-child(1) { left: 0; width: 26px; }
.landers-table th:nth-child(2) { left: 26px; width: 34px; }
.landers-table th:nth-child(3) { left: 60px; box-shadow: 1px 0 0 var(--border); }
.landers-table td:nth-child(-n+3) { position: sticky; background: var(--surface); z-index: 1; }
.landers-table td:nth-child(1) { left: 0; }
.landers-table td:nth-child(2) { left: 26px; color: var(--text-faint); }
.landers-table td:nth-child(3) { left: 60px; box-shadow: 1px 0 0 var(--border); max-width: 220px; }
.landers-table tr.row-positive td:nth-child(-n+3),
.landers-table tr.row-negative td:nth-child(-n+3),
.landers-table tr.row-warning td:nth-child(-n+3),
.landers-table tr.row-negative-strong td:nth-child(-n+3) { background: var(--surface); }
.landers-table tr.row-warning td { background: var(--warning-tint); }
.landers-table tr.row-warning:hover td { filter: brightness(0.98); }
/* Stronger red tier for heavily-losing rows (Traffic Channels' ROI<=-50%
   distinction) — same negative tint, just less diluted, never a new hue. */
.landers-table tr.row-negative-strong td { background: var(--negative-tint); background: color-mix(in srgb, var(--negative-tint) 65%, var(--negative) 8%); }
.landers-table tr.row-negative-strong:hover td { filter: brightness(0.98); }
.landers-table tr.totals-row td, .landers-table tr.totals-row th {
    position: sticky; top: 30px; z-index: 2;
    background: var(--surface-alt); font-weight: 600; color: var(--text);
}
.landers-table tr.totals-row td:nth-child(-n+3) { z-index: 3; background: var(--surface-alt); }

/* Density variants — same convention as Campaigns' applyDensity(), just
   scoped to .landers-table instead of a page-specific table id. */
.landers-table.density-normal th, .landers-table.density-normal td { height: 32px; font-size: var(--fs-2xs); }
.landers-table.density-comfortable th, .landers-table.density-comfortable td { height: 38px; font-size: var(--fs-xs); }

.pagination-bar {
    display: flex; align-items: center; gap: 10px; justify-content: center;
    padding: 10px 0; margin-top: 4px;
}
.pagination-bar__label { font-size: var(--fs-xs); color: var(--text-dim); }
.pagination-bar select { height: 28px; font-size: var(--fs-2xs); border: 1px solid var(--border); border-radius: var(--radius-xs); background: var(--surface); }

/* ---------- Click Details drawer ---------- */
.click-drawer { display: none; position: fixed; inset: 0; z-index: 100; }
.click-drawer.open { display: block; }
.click-drawer__backdrop { position: absolute; inset: 0; background: rgba(20,24,32,0.35); }
.click-drawer__panel {
    position: absolute; top: 0; right: 0; bottom: 0; width: 480px; max-width: 100%;
    background: var(--surface); box-shadow: -8px 0 24px rgba(20,24,32,0.16);
    display: flex; flex-direction: column;
}
.click-drawer__header {
    display: flex; align-items: center; justify-content: space-between;
    padding: 12px 14px; border-bottom: 1px solid var(--border); flex-shrink: 0;
}
.click-drawer__title { font-size: var(--fs-sm); font-weight: 600; color: var(--text); font-family: var(--font-mono); }
.click-drawer__body { overflow-y: auto; padding: 4px 0; }
.click-drawer__section { padding: 10px 14px; border-bottom: 1px solid var(--border); }
.click-drawer__section-title {
    font-size: var(--fs-2xs); font-weight: 600; text-transform: uppercase; letter-spacing: .04em;
    color: var(--text-faint); margin-bottom: 6px;
}
.click-drawer__row { display: flex; gap: 10px; padding: 3px 0; font-size: var(--fs-2xs); }
.click-drawer__row-label { flex: 0 0 150px; color: var(--text-faint); }
.click-drawer__row-value { flex: 1; min-width: 0; color: var(--text); word-break: break-all; font-family: var(--font-mono); }
.click-drawer__subcard { border: 1px solid var(--border); border-radius: var(--radius-xs); padding: 6px 8px; margin-bottom: 6px; background: var(--surface-alt); }
.click-drawer__subcard:last-child { margin-bottom: 0; }

/* ============================================================
   CONSISTENCY LAYER — one look for every page.
   Every table, filter bar, toolbar, pagination control and page
   header shares the rules below, so no page drifts into its own style.
   ============================================================ */

/* Plain list tables (Settings, Domains, Ad Accounts, Alerts, Tools…) use
   the same header/cell look as the big grids: dim 10.5px/600 header on
   the alt surface, 12px UI-font cells with tabular numbers. */
table.data-table { font-size: var(--fs-xs); }
table.data-table th { color: var(--text-dim); letter-spacing: 0; }
table.data-table td { font-family: var(--font-ui); font-variant-numeric: tabular-nums; }
table.data-table td.mono { font-family: var(--font-mono); font-size: var(--fs-2xs); }
/* Any plain table scrolls inside its own box instead of widening the page. */
.table-scroll, .alerts-table-wrap { overflow-x: auto; }

/* Grid density applies to every grid (Reports and Logs too, not just
   the entity pages). No class = Compact. */
.logs-clicks-table.density-normal th, .logs-clicks-table.density-normal td { height: 32px; font-size: var(--fs-2xs); }
.logs-clicks-table.density-comfortable th, .logs-clicks-table.density-comfortable td { height: 38px; font-size: var(--fs-xs); }
/* Sortable header rendered as a link (Reports) looks like the others. */
.logs-clicks-table th a { color: inherit; text-decoration: none; display: block; overflow: hidden; text-overflow: ellipsis; }
.logs-clicks-table th a:hover { color: var(--text); text-decoration: none; }
/* Totals row on grids that aren't .landers-table (Reports). */
.logs-clicks-table tr.totals-row td {
    position: sticky; top: 30px; z-index: 2;
    background: var(--surface-alt); font-weight: 600; color: var(--text);
}
.logs-clicks-table tr.totals-row td:first-child { z-index: 3; }

/* Filter bars: every control and button is the same 30px. */
.workspace-filterbar .btn,
.workspace-filterbar .btn-secondary { height: 30px; padding: 0 14px; font-size: var(--fs-xs); }
.wf-field--dates { flex-direction: row; align-items: flex-end; gap: 6px; }
.wf-field--dates input { width: 130px; }
.wf-field .wf-check {
    height: 30px; display: inline-flex; align-items: center; gap: 6px;
    font-size: var(--fs-xs); font-weight: 500; color: var(--text-dim); text-transform: none; letter-spacing: 0; cursor: pointer;
}
.wf-field .wf-check input { height: auto; }
.wf-field input[type="text"] { min-width: 150px; }
.wf-actions { flex-direction: row; gap: 6px; }

/* Rows-per-page and other small toolbar selects: one size everywhere. */
.pagination-bar select,
.workspace-toolbar select {
    height: 28px; padding: 0 26px 0 8px; font-size: var(--fs-xs); color: var(--text);
    border: 1px solid var(--border); border-radius: var(--radius-sm); background-color: var(--surface);
}
.workspace-toolbar input[type="text"] {
    height: 28px; padding: 0 8px; font-size: var(--fs-xs); color: var(--text);
    border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface);
}
.workspace-toolbar input[type="text"]:focus,
.pagination-bar select:focus, .workspace-toolbar select:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-tint); }
.workspace-toolbar .btn { height: 28px; padding: 0 12px; font-size: var(--fs-xs); }

/* Page header: every page starts with the same title row; the primary
   action sits top-right. Panels below it keep their own section titles. */
.workspace-header .btn { width: auto; }
.workspace-header__actions { display: flex; align-items: center; gap: 8px; }
.workspace-header + .panel, .workspace-header + form + .panel { margin-top: 0; }

/* Saved-view chips (Reports). */
.saved-views { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 8px 0 2px; }
.saved-views__label { font-size: var(--fs-2xs); font-weight: 500; color: var(--text-faint); text-transform: uppercase; letter-spacing: 0.03em; margin-right: 2px; }
.saved-view-chip {
    display: inline-flex; align-items: center; gap: 4px; height: 24px; padding: 0 4px 0 9px;
    font-size: var(--fs-xs); background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-pill);
}
.saved-view-chip a { color: var(--text); text-decoration: none; }
.saved-view-chip a:hover { color: var(--brand); }
.saved-view-chip button {
    display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px;
    border: none; border-radius: 50%; background: none; color: var(--text-faint); cursor: pointer; font-size: var(--fs-sm); line-height: 1;
}
.saved-view-chip button:hover { background: var(--negative-tint); color: var(--negative); }

/* Row actions in plain tables use the same icon buttons as the grids. */
td .icon-btn-row form { display: inline; margin: 0; }

/* Top bar never overlaps itself on narrow windows. */
.topbar { gap: 14px; min-width: 0; }
.topbar__left { flex-shrink: 0; white-space: nowrap; }
.topbar__user { display: flex; align-items: center; flex: 0 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; }
.topbar__user > span:first-child { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.topbar__tools { white-space: nowrap; }
@media (max-width: 900px) {
    .topbar__tools { display: none; }
}
.topbar__title { font-size: var(--fs-xs); font-weight: 500; }

/* Page-level tabs (Logs, Tools): same brand underline as the active nav item. */
.page-tabs { display: flex; flex-wrap: wrap; gap: 2px; margin-bottom: 16px; border-bottom: 1px solid var(--border); }
.page-tab {
    display: inline-block; padding: 8px 14px; margin-bottom: -1px; font-size: var(--fs-xs); font-weight: 500;
    color: var(--text-dim); text-decoration: none; border-bottom: 2px solid transparent;
}
.page-tab:hover { color: var(--text); text-decoration: none; }
.page-tab.is-active { color: var(--brand); font-weight: 500; border-bottom-color: var(--brand); }
.page-breadcrumb { font-size: var(--fs-2xs); color: var(--text-faint); margin-bottom: 6px; }
.page-breadcrumb span { margin: 0 4px; }

/* Toolbar actions are the same height whether they're <a> or <button>. */
.wt-action { height: 26px; line-height: 1; box-sizing: border-box; }
/* Row icon buttons: same 22px size in plain tables as in the grids' hover actions. */
td .icon-btn-row .icon-btn { width: 22px; height: 22px; }
td .icon-btn-row .icon-btn svg { width: 12px; height: 12px; }

/* ============================================================
   FORM CONTROLS — one theme for every dropdown, checkbox and input,
   everywhere (pages, filter bars, toolbars, tables and pop-ups).
   ============================================================ */

/* Dropdowns: the app's own chevron, border, radius and focus ring instead
   of the browser's native control. (Previously only .editor-body had it.)
   The :not() pair lifts specificity above per-context rules such as
   `.wf-field select { padding: 0 8px; background: … }`, so the chevron and
   its right padding survive in every context; heights stay per context. */
select:not([multiple]):not([size]) {
    appearance: none; -webkit-appearance: none; -moz-appearance: none;
    background-color: var(--surface);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%2398A2B3' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
    background-size: 9px 5px;
    padding-right: 28px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text);
    font-family: var(--font-ui);
    cursor: pointer;
    text-overflow: ellipsis;
}
select:not([multiple]):not([size]):hover { border-color: var(--text-faint); }
select:not([multiple]):not([size]):focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-tint); }
select:not([multiple]):not([size]):disabled { background-color: var(--surface-alt); color: var(--text-faint); cursor: not-allowed; }
select option { color: var(--text); background: var(--surface); }

/* Text-type inputs outside .field / filter bars get the same base look. */
:where(input[type="text"], input[type="number"], input[type="date"], input[type="email"],
input[type="password"], input[type="url"], input[type="search"], textarea) {
    font-family: var(--font-ui); color: var(--text);
    border: 1px solid var(--border); border-radius: var(--radius-sm); background-color: var(--surface);
}
:where(input[type="text"], input[type="number"], input[type="date"], input[type="email"],
input[type="password"], input[type="url"], input[type="search"], textarea):focus {
    outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-tint);
}
:where(input[type="number"]) { padding-left: 8px; padding-right: 4px; }

/* Checkboxes: brand-colored, one size. */
:where(input[type="checkbox"]) { accent-color: var(--brand); width: 15px; height: 15px; margin: 0; cursor: pointer; vertical-align: middle; }

/* A checkbox inside a .field (e.g. "Cost sync" / "CAPI", "Set as default",
   "Active") must not inherit the text-input box or the floating label. */
.field label:has(> input[type="checkbox"]),
.field label.check {
    position: static; display: inline-flex; align-items: center; gap: 7px;
    max-width: none; overflow: visible; background: none; padding: 0;
    font-size: var(--fs-xs); font-weight: 500; color: var(--text); line-height: 1.3;
    pointer-events: auto; cursor: pointer; white-space: nowrap;
}
.field label > input[type="checkbox"] { width: 15px; height: 15px; padding: 0; flex-shrink: 0; }
.field.check-group { display: flex; align-items: center; gap: 18px; min-height: var(--control-h); }

/* Pop-up helpers used by the sectioned modals. */
.modal-section__intro { font-size: var(--fs-2xs); color: var(--text-dim); line-height: 1.5; margin: -4px 0 12px; }
.modal-section .table-scroll { margin: 0 -2px; }
.macro-chips { margin-top: 6px; }
.field-with-actions { display: flex; align-items: center; gap: 6px; }
.field-with-actions select, .field-with-actions input { flex: 1; min-width: 0; }
.field-static { display: flex; align-items: center; gap: 8px; height: var(--control-h); }
.field-static__value { font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--text-dim); }
.field-inline-actions { display: flex; align-items: center; gap: 10px; }
.btn-secondary--sm { height: 28px; padding: 0 10px; font-size: var(--fs-xs); }
.btn-secondary--sm svg { width: 13px; height: 13px; }

/* Editable rows in a table inside a pop-up (Traffic Channel / Offer Source
   parameter mapping): consistent 30px controls that fill their cell. */
table.data-table--form td { padding: 6px 8px; }
table.data-table--form td input[type="text"], table.data-table--form td select { width: 100%; min-width: 120px; height: 30px; font-size: var(--fs-xs); }

/* Import from RedTrack */
.import-key-row { display: flex; align-items: center; gap: 12px; padding: 12px 14px; }
.import-table select.import-action { height: 28px; font-size: var(--fs-xs); min-width: 170px; }
.import-table td.import-notes { white-space: normal; min-width: 220px; max-width: 360px; font-size: var(--fs-2xs); color: var(--text-dim); }
.import-tab-count { display: inline-block; min-width: 18px; padding: 0 5px; margin-left: 4px; border-radius: var(--radius-pill); background: var(--brand-tint); color: var(--brand); font-size: var(--fs-2xs); font-weight: 500; text-align: center; }

/* ============================================================
   LIST TABLES — RedTrack-style look for every grid (Campaigns, Offers,
   Offer Sources, Landers, Traffic Channels, Reports, Logs).
   ============================================================ */

/* 2. Bigger, calmer rows: 13px text in 26px rows, faint grid lines. */
.logs-clicks-table th, .logs-clicks-table td,
.landers-table th, .landers-table td {
    font-size: var(--fs-sm); height: 26px; padding: 0 7px;
    border-right: 1px solid rgba(0, 0, 0, .06); border-bottom: 1px solid rgba(0, 0, 0, .05);
}
.logs-clicks-table th, .landers-table th {
    background: var(--surface-hover); color: var(--text); font-size: var(--fs-xs); font-weight: 500;
    height: 36px; padding: 5px 7px; vertical-align: top;
}
.logs-clicks-table th.is-sortable:hover, .landers-table th.is-sortable:hover { color: var(--brand); }
.logs-clicks-wrap { border-color: var(--border); }

/* Density: Compact (default) 26px · Normal 32px · Comfortable 38px rows.
   The header keeps its size in every density, like RedTrack's. */
.logs-clicks-table.density-normal td, .landers-table.density-normal td { height: 32px; font-size: var(--fs-sm); }
.logs-clicks-table.density-comfortable td, .landers-table.density-comfortable td { height: 38px; font-size: 13.5px; }
.logs-clicks-table.density-normal th, .landers-table.density-normal th,
.logs-clicks-table.density-comfortable th, .landers-table.density-comfortable th { height: 36px; font-size: var(--fs-xs); }

/* 3. Totals inside the column header, under the label (moved there by app.js). */
.th-label { display: block; overflow: hidden; text-overflow: ellipsis; }
.th-total { display: block; margin-top: 3px; font-size: var(--fs-xs); font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.th-total.num-positive { color: var(--positive); }
.th-total.num-negative { color: var(--negative); }
.th-total div { font-weight: 400; font-size: var(--fs-2xs); color: var(--text-faint); }
table.has-header-totals th { height: 50px; }

/* 4. Profit tint by ROI, RedTrack's four levels — the pinned columns
   (checkbox / ID / name) are tinted too, so a row reads as one band. */
.logs-clicks-table tbody tr.row-positive-strong td, .landers-table tbody tr.row-positive-strong td,
.landers-table tbody tr.row-positive-strong td:nth-child(-n+3) { background: #C8E6C9; }
.logs-clicks-table tbody tr.row-positive td, .landers-table tbody tr.row-positive td,
.landers-table tbody tr.row-positive td:nth-child(-n+3) { background: #E8F5E9; }
.logs-clicks-table tbody tr.row-negative td, .landers-table tbody tr.row-negative td,
.landers-table tbody tr.row-negative td:nth-child(-n+3) { background: #FFEBEE; }
.logs-clicks-table tbody tr.row-negative-strong td, .landers-table tbody tr.row-negative-strong td,
.landers-table tbody tr.row-negative-strong td:nth-child(-n+3) { background: #FFCDD2; }
.logs-clicks-table tbody tr.row-warning td, .landers-table tbody tr.row-warning td,
.landers-table tbody tr.row-warning td:nth-child(-n+3) { background: #FFF8E1; }
.logs-clicks-table tbody tr[class*="row-"]:hover td { filter: brightness(.97); }

/* 5. The clicked row stays highlighted (yellow), pinned columns included. */
.logs-clicks-table tbody tr.is-current td, .landers-table tbody tr.is-current td,
.landers-table tbody tr.is-current td:nth-child(-n+3) { background: #FFF59D; filter: none; }
.logs-clicks-table tbody tr { cursor: default; }

/* Names use the full column width; the hover actions float over the end
   of the name on their own background, so no space is reserved for them. */
.logs-clicks-table .entity-name-link, .landers-table .entity-name-link { padding-right: 6px !important; }
.logs-clicks-table .row-hover-actions, .landers-table .row-hover-actions { background: inherit; padding-left: 6px; box-shadow: -8px 0 8px -4px rgba(0,0,0,.08); }
.logs-clicks-table tbody tr:not([class*="row-"]):not(.is-current) .row-hover-actions { background: var(--surface-alt); }

/* Numeric headers (and the total under them) align with their numbers. */
.logs-clicks-table th.num, .landers-table th.num { text-align: right; }

/* ================= Typography: RedTrack weights =================
   RedTrack sets almost everything at 400; only the header totals are
   bold and tabs/links are medium. Inter reads heavier than Open Sans at
   the same weight, so tables stay at 400 and names at 500. */
body { font-weight: 400; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
:is(.logs-clicks-table, .landers-table, table.data-table) :is(th, td) { font-weight: 400; }
:is(.logs-clicks-table, .landers-table, table.data-table) :is(.num-positive, .num-negative) { font-weight: 400; }
:is(.logs-clicks-table, .landers-table) tr.totals-row td { font-weight: 600; }
.th-total { font-weight: 700; }
:is(.campaigns-grid__name-link, .entity-name-link) { font-weight: 500; }
.num-positive, .num-negative { font-weight: 500; }
.workspace-header__title { font-weight: 600; }
.wf-field label, .saved-views__label { font-weight: 500; }
button, .btn, .btn-secondary, .wt-action { font-weight: 500; }

/* ================= Reports: grouping, chips, drill-down ================= */
/* Grouping (RedTrack): outlined button → full-width panel under the filter
   bar with the level boxes on top and dimension chips below. */
#rpt-filter-form { position: relative; }
.rpt-grouping__btn {
    height: 36px; padding: 0 16px; display: inline-flex; align-items: center; gap: 8px;
    border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface);
    font: inherit; font-size: var(--fs-sm); font-weight: 500; color: var(--text); cursor: pointer;
    transition: border-color .15s, box-shadow .15s;
}
.rpt-grouping__btn svg { color: var(--brand); }
.rpt-grouping__btn:hover { border-color: var(--text-faint); }
.rpt-grouping__count {
    min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--radius-md);
    background: var(--brand-tint); color: var(--brand); font-size: var(--fs-2xs); line-height: 18px; text-align: center;
}
.rpt-grouping__panel.open { display: flex; flex-direction: column; gap: 12px; }
.rpt-grouping__panel { left: 0; right: 0; top: calc(100% + 6px); padding: 18px 16px 12px; z-index: 40; }
.rpt-grouping__levels { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 10px; }
.workspace-filterbar .rpt-grouping__levels .wf-field select { width: 100%; min-width: 0; }
.workspace-filterbar .rpt-grouping__panel .wf-field > label:first-child { background: var(--surface); }
.rpt-grouping__chips, .rpt-grouping__dims { display: flex; flex-wrap: wrap; gap: 6px; }
.rpt-grouping__dims { padding-top: 10px; border-top: 1px solid var(--border); }
.rpt-grouping__dims[hidden] { display: none; }
.rpt-chip {
    height: 28px; padding: 0 10px; display: inline-flex; align-items: center; gap: 4px;
    border: 1px solid transparent; border-radius: var(--radius-sm); background: var(--surface-alt);
    font: inherit; font-size: var(--fs-xs); font-weight: 500; color: var(--text); cursor: pointer;
}
.rpt-chip:hover { background: var(--brand-tint); color: var(--brand); }
.rpt-chip.is-open { border-color: var(--brand); color: var(--brand); background: var(--surface); }
.rpt-chip.is-open svg { transform: rotate(180deg); }
.rpt-chip--dim.is-used { opacity: .4; cursor: default; background: var(--surface-alt); color: var(--text-dim); }
.rpt-grouping__foot { display: flex; align-items: center; justify-content: space-between; font-size: var(--fs-xs); color: var(--text-faint); }
.rpt-grouping__clear { border: 0; background: none; font: inherit; font-size: var(--fs-xs); font-weight: 500; color: var(--brand); cursor: pointer; }
@media (max-width: 900px) { .rpt-grouping__levels { grid-template-columns: 1fr 1fr; } }

.rpt-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 2px 0 10px; }
.rpt-chip { display: inline-flex; align-items: center; gap: 4px; height: 24px; padding: 0 10px; border-radius: var(--radius-pill); background: var(--surface-hover); color: var(--text-dim); font-size: var(--fs-xs); }
.rpt-chip strong { font-weight: 500; color: var(--text); }
.rpt-chip a { color: var(--text-faint); text-decoration: none; font-size: var(--fs-md); line-height: 1; margin-left: 2px; }
.rpt-chip a:hover { color: var(--negative); }
.rpt-chips__clear { font-size: var(--fs-xs); color: var(--brand); text-decoration: none; margin-left: 4px; }
.rpt-chips__clear:hover { text-decoration: underline; }

#report-table td.rpt-label-cell { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rpt-label { vertical-align: middle; }
.rpt-toggle, .rpt-toggle-spacer { display: inline-block; width: 16px; height: 16px; margin-right: 4px; vertical-align: middle; }
.rpt-toggle { padding: 0; border: 0; background: none; cursor: pointer; color: var(--text-faint); border-radius: 3px; position: relative; }
.rpt-toggle::before { content: ''; position: absolute; left: 5px; top: 4px; width: 5px; height: 5px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(-45deg); transition: transform .12s; }
.rpt-toggle:hover { background: var(--surface-alt); color: var(--text); }
tr.is-expanded > td .rpt-toggle::before { transform: rotate(45deg); top: 3px; }
tr.is-loading > td .rpt-toggle { opacity: .4; cursor: progress; }
#report-table tr[data-level="1"] > td { background-color: var(--surface-alt); }
#report-table tr[data-level="2"] > td { background-color: var(--surface-alt); }
#report-table tr[data-level="3"] > td, #report-table tr[data-level="4"] > td { background-color: var(--surface-hover); }
#report-table tr.rpt-more td { color: var(--text-faint); font-style: italic; }
.rpt-delta { font-size: var(--fs-2xs); font-weight: 400; margin-left: 3px; }

/* ---------- Dashboard: Metrics chart + best-performing column heads ---------- */
:root { --mc-cost: var(--chart-1); --mc-revenue: var(--chart-6); --mc-profit: var(--chart-2); --mc-roi: var(--chart-4); }
.best-perf-table__head td { font-size: var(--fs-2xs); color: var(--text-faint) !important; padding-top: 8px; }
.best-perf-table + .best-perf-table { margin-top: 6px; }
/* RedTrack layout: chart on top, its filters in one row under it, then the 4 metric tiles. */
.mc-body { display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; padding: 14px 16px; }
.mc-chart-wrap { position: relative; min-width: 0; }
.mc-chart { width: 100%; height: auto; display: block; }
.mc-grid { stroke: var(--border); stroke-width: 1; }
.mc-guide { stroke: var(--text-faint); stroke-dasharray: 3 3; }
.mc-axis { font-size: var(--fs-2xs); fill: var(--text-faint); font-family: inherit; }
.mc-legend { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-bottom: 6px; }
.mc-legend__item { border: 0; background: none; padding: 2px 0; font: inherit; font-size: var(--fs-xs); color: var(--text-dim); cursor: pointer; display: inline-flex; align-items: center; }
.mc-legend__item.is-off { opacity: .4; text-decoration: line-through; }
.mc-tile__dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; flex-shrink: 0; }
.mc-tip { position: absolute; top: 28px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm); box-shadow: 0 4px 14px rgba(16, 24, 40, .12); padding: 8px 10px; font-size: var(--fs-xs); pointer-events: none; white-space: nowrap; z-index: 2; }
.mc-tip div { display: flex; align-items: center; gap: 2px; line-height: 1.7; }
.mc-tip__day { font-weight: 600; }
/* The filters are a .workspace-filterbar (outlined fields) sitting inside a
   white panel, so the notched labels are backed by the panel colour. */
.mc-side { border-top: 1px solid var(--border); padding-top: 18px; margin-bottom: 0; }
.mc-side.workspace-filterbar .wf-field > label:first-child { background: var(--surface); }
.mc-tiles { flex-basis: 100%; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; margin-top: 4px; }
/* RedTrack's metric tiles: outlined in the series colour, value centred. */
.mc-tile { border: 1.5px solid var(--border); border-radius: var(--radius-md); padding: 10px 12px 12px; position: relative; text-align: center; }
.mc-tile:nth-child(1) { border-color: var(--mc-cost); }
.mc-tile:nth-child(2) { border-color: var(--mc-revenue); }
.mc-tile:nth-child(3) { border-color: var(--mc-profit); }
.mc-tile:nth-child(4) { border-color: var(--mc-roi); }
.mc-tile .mc-tile__dot { position: absolute; top: 12px; left: 12px; }
.mc-tile__label { font-size: var(--fs-xs); color: var(--text-dim); }
.mc-tile__value { font-size: var(--fs-xl); font-weight: 600; color: var(--text); margin-top: 4px; }
@media (max-width: 700px) { .mc-tiles { grid-template-columns: 1fr 1fr; } }

/* ---------- Date Range picker (RedTrack-style): one grouped control
   [‹ | 📅 Today · Sep 27, 2026 ⌄ | ›] opening a popover with presets
   left + two linked month calendars right. ---------- */
.drp {
    position: relative; display: inline-flex; align-items: stretch; height: 30px;
    border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface);
    transition: border-color .15s, box-shadow .15s;
}
.drp:hover { border-color: var(--text-faint); }
.drp.is-open { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-tint); }
.drp select { display: none; }
.drp-step {
    display: inline-flex; align-items: center; justify-content: center; width: 28px; padding: 0;
    border: 0; background: none; color: var(--text-dim); cursor: pointer;
    transition: background .15s, color .15s;
}
.drp-step:first-child { border-right: 1px solid var(--border); border-radius: 6px 0 0 6px; }
.drp-step:not(:first-child) { border-left: 1px solid var(--border); border-radius: 0 6px 6px 0; }
.drp-step:hover:not(:disabled) { background: var(--surface-alt); color: var(--text); }
.drp-step:disabled { color: var(--text-faint); opacity: .45; cursor: default; }
.drp-trigger {
    display: inline-flex; align-items: center; gap: 7px; padding: 0 10px;
    border: 0; background: none; color: var(--text);
    font-size: var(--fs-xs); font-family: inherit; cursor: pointer; white-space: nowrap;
    transition: background .15s;
}
.drp-trigger:hover, .drp-trigger.is-active { background: var(--surface-alt); }
.drp-trigger svg { flex-shrink: 0; color: var(--text-faint); }
.drp-trigger__label { font-weight: 500; max-width: 190px; overflow: hidden; text-overflow: ellipsis; }
.drp-trigger__range { color: var(--text-dim); max-width: 210px; overflow: hidden; text-overflow: ellipsis; }
.drp-trigger__range:empty { display: none; }
.drp-trigger__caret { margin-left: -1px; transition: transform .15s; }
.drp-trigger.is-active .drp-trigger__caret { transform: rotate(180deg); }
@media (max-width: 640px) { .drp-trigger__range { display: none; } }
.drp-panel { display: none; top: calc(100% + 6px); left: 0; right: auto; padding: 10px; }
.drp-panel.open { display: flex; gap: 10px; min-width: 0; }
.drp-presets { display: flex; flex-direction: column; gap: 1px; min-width: 128px; border-right: 1px solid var(--border); padding-right: 10px; }
.drp-preset {
    text-align: left; border: 0; background: none; padding: 6px 8px; border-radius: var(--radius-sm);
    font-size: var(--fs-xs); color: var(--text); cursor: pointer; white-space: nowrap; font-family: inherit;
}
.drp-preset:hover { background: var(--surface-alt); }
.drp-preset.is-active { background: var(--brand-tint); color: var(--brand); font-weight: 500; }
.drp-cals { display: flex; gap: 14px; }
.drp-cal { width: 196px; }
.drp-cal__head {
    display: flex; align-items: center; justify-content: space-between; gap: 4px;
    font-size: var(--fs-xs); font-weight: 500; color: var(--text); margin-bottom: 6px; padding: 0 2px;
}
.drp-nav {
    border: 0; background: none; color: var(--text-faint); cursor: pointer; font-size: var(--fs-md);
    line-height: 1; padding: 2px 4px; border-radius: 4px;
}
.drp-nav:hover { background: var(--surface-alt); color: var(--text); }
.drp-cal__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 1px; }
.drp-cal__dow { font-size: var(--fs-2xs); color: var(--text-faint); text-align: center; padding-bottom: 3px; }
.drp-day {
    height: 26px; border: 0; background: none; border-radius: 4px; font-size: var(--fs-xs); color: var(--text);
    cursor: pointer; font-family: inherit;
}
.drp-day:hover { background: var(--surface-alt); }
.drp-day.is-today { font-weight: 600; color: var(--brand); }
.drp-day.is-in-range { background: var(--brand-tint); border-radius: 0; }
.drp-day.is-edge { background: var(--brand); color: #fff; font-weight: 500; }
@media (max-width: 640px) {
    .drp-panel.open { flex-direction: column; }
    .drp-presets { flex-direction: row; flex-wrap: wrap; border-right: 0; border-bottom: 1px solid var(--border); padding-right: 0; padding-bottom: 8px; }
    .drp-cals { flex-direction: column; }
}

/* ---------- Campaigns: tags, Edit tags popover, Compare toggle ---------- */
.camp-tag { display: inline-block; padding: 1px 7px; margin: 0 4px 0 0; border-radius: var(--radius-md); background: var(--surface-alt); border: 1px solid var(--border); font-size: var(--fs-2xs); color: var(--text-dim); line-height: 16px; white-space: nowrap; }
.camp-tags-panel { min-width: 260px; padding: 12px; }
.camp-tags-panel input[type=text] { width: 100%; margin: 6px 0 4px; }
.camp-tags-panel__title { font-size: var(--fs-xs); font-weight: 500; color: var(--text); }
.camp-tags-panel__actions { display: flex; justify-content: flex-end; gap: 6px; margin-top: 10px; }
.camp-compare { display: inline-flex !important; align-items: center; gap: 6px; height: 30px; font-size: var(--fs-xs); text-transform: none !important; letter-spacing: 0 !important; color: var(--text-dim); cursor: pointer; white-space: nowrap; }
.camp-tag-editor { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; min-height: 32px; padding: 3px 6px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); }
.camp-tag-editor input { flex: 1; min-width: 140px; border: 0 !important; box-shadow: none !important; padding: 2px 4px !important; height: 24px; background: transparent; }
.camp-tag-editor__chips { display: contents; }
.camp-tag__x { border: 0; background: none; padding: 0 0 0 4px; margin: 0; cursor: pointer; color: var(--text-faint); font-size: var(--fs-sm); line-height: 1; }
.camp-tag__x:hover { color: var(--negative); }
.camp-tag-used { display: flex; flex-wrap: wrap; gap: 4px; }
.camp-tag--pick { cursor: pointer; font: inherit; font-size: var(--fs-2xs); }
.camp-tag--pick:hover { border-color: var(--text-faint); }
.camp-tag--pick.is-on { background: var(--brand-tint); border-color: var(--brand); color: var(--brand); }

/* ---------- Traffic channel editor: linked Meta ad accounts ---------- */
.tc-accounts { display: flex; flex-direction: column; gap: 6px; }
.tc-account { display: flex; align-items: center; gap: 10px; font-size: var(--fs-xs); flex-wrap: wrap; }
.tc-account__name { font-weight: 500; color: var(--text); }
.tc-account { padding: 8px 10px; border: 1px solid var(--border); border-radius: var(--radius-sm); }
.tc-account__actions { margin-left: auto; display: inline-flex; gap: 4px; }
.tc-manual { margin-top: 12px; font-size: var(--fs-xs); }
.tc-manual summary { cursor: pointer; color: var(--text-dim); }
.meta-connect-btn { background: #1877F2; border-color: #1877F2; }
.meta-connect-btn:hover { background: #166FE5; border-color: #166FE5; }

/* ---------- Offer editor ---------- */
.offer-macros { margin-top: 8px; font-size: var(--fs-xs); }
.offer-macros summary { cursor: pointer; color: var(--brand); font-weight: 500; }
.offer-macros .macro-chips { margin-top: 8px; max-height: 190px; overflow-y: auto; }
.offer-money { display: flex; gap: 6px; }
.offer-money input[type=number] { flex: 1; min-width: 0; }

/* ---------- CAPI pixel: Custom Conversion Matching rows ---------- */
.capi-match-row { display: grid; grid-template-columns: minmax(0, 1fr) 16px minmax(0, 1fr) 140px 90px 30px; gap: 6px; align-items: center; margin-bottom: 6px; }
.capi-match-row__arrow { color: var(--text-faint); text-align: center; }
@media (max-width: 700px) { .capi-match-row { grid-template-columns: 1fr 1fr; } .capi-match-row__arrow { display: none; } }

/* ---------- Tables fill the screen width (RedTrack-style) ----------
   Fixed-layout tables are max(width, sum of column widths) wide: at
   width:100% they stretch their columns to fill the page when there's
   room, and still grow + scroll sideways when there are more columns
   than fit. Overrides .logs-clicks-table's width:max-content above. */
.resizable-table { width: 100%; }

/* Checkbox cells: compact and never ellipsized. Columns keep their
   declared width now (tables stretch the data columns instead), so the
   13px box + default margins + cell padding no longer overflows its 28px. */
.resizable-table th:has(> input[type=checkbox]),
.resizable-table td:has(> input[type=checkbox]) { padding-left: 4px; padding-right: 4px; text-align: center; text-overflow: clip; }
.resizable-table th > input[type=checkbox],
.resizable-table td > input[type=checkbox] { margin: 0; vertical-align: middle; }

/* ================= Filter bars: RedTrack outlined fields =================
   Every filter is one uniform outlined box (36px, ~190px wide) with its
   label sitting in the top border — RedTrack's Material "notched" field —
   instead of a small caps label above boxes of assorted sizes. Pure CSS on
   the existing .wf-field markup (label + control), so every page's filter
   bar picks it up; app.js adds the × clear buttons and puts the date
   range into the date field's label. */
.workspace-filterbar { gap: 14px 10px; align-items: center; padding-top: 7px; margin-bottom: 8px; }
.workspace-filterbar .wf-field { position: relative; gap: 0; }
/* Apply + Reset pairs (Reports, Logs › CAPI) are a nested .wf-field — keep them apart. */
.workspace-filterbar .wf-field.wf-actions { flex-direction: row; align-items: center; gap: 10px; }
.workspace-filterbar .wf-field > label:first-child {
    position: absolute; top: -7px; left: 8px; z-index: 3; max-width: calc(100% - 16px);
    padding: 0 4px; font-size: var(--fs-2xs); line-height: 13px; font-weight: 400;
    text-transform: none; letter-spacing: 0; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    /* page colour above the border line, field colour below it */
    background: linear-gradient(to bottom, var(--bg) 50%, var(--surface) 50%); pointer-events: none;
}
.workspace-filterbar .wf-field > label[hidden] { display: none; }
.workspace-filterbar .wf-field select,
.workspace-filterbar .wf-field input:not([type=checkbox]):not([type=radio]):not([type=hidden]),
.workspace-filterbar .wf-static {
    height: 36px; min-width: 190px; padding: 0 12px; font-size: var(--fs-sm);
    border: 1px solid var(--border); border-radius: var(--radius-sm); background-color: var(--surface); color: var(--text);
    transition: border-color .15s, box-shadow .15s;
}
.workspace-filterbar .wf-field select:hover,
.workspace-filterbar .wf-field input:not([type=checkbox]):hover { border-color: var(--text-faint); }
.workspace-filterbar .wf-field select:focus,
.workspace-filterbar .wf-field input:not([type=checkbox]):focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-tint); }
/* Fixed width: a select otherwise grows to its longest option (campaign names). */
.workspace-filterbar .wf-field select { padding-right: 30px; width: 210px; text-overflow: ellipsis; }
.workspace-filterbar .wf-static { display: flex; align-items: center; color: var(--text); }
/* !important: several pages set height:30px inline on their Apply button. */
.workspace-filterbar .btn, .workspace-filterbar .btn-secondary { height: 36px !important; padding: 0 22px; font-size: var(--fs-sm); display: inline-flex; align-items: center; }
.workspace-filterbar input::placeholder { color: var(--text-faint); }

/* Date range picker as a filter field: same box, preset inside, dates in the label. */
.workspace-filterbar .drp { height: 36px; min-width: 190px; border-radius: var(--radius-sm); }
.workspace-filterbar .drp-trigger { flex: 1; font-size: var(--fs-sm); justify-content: flex-start; }
.workspace-filterbar .drp-trigger__caret { margin-left: auto; }
.workspace-filterbar .drp-step { width: 26px; }
.workspace-filterbar .drp.has-label-range .drp-trigger__range { display: none; }

/* Compare: RedTrack's swap icon between the two date fields; the compare
   field stays greyed out until it's switched on. */
.wf-compare-toggle {
    width: 30px; height: 30px; margin: 0 -2px; padding: 0; flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid var(--border); border-radius: 50%; background: var(--surface); color: var(--text-dim); cursor: pointer;
    transition: background .15s, color .15s, border-color .15s;
}
.wf-compare-toggle:hover { border-color: var(--text-faint); color: var(--text); }
.wf-compare-toggle.is-active { background: var(--brand); border-color: var(--brand); color: #fff; }
.wf-field--compare.is-off .wf-static { color: var(--text-faint); cursor: pointer; }
.wf-field--compare.is-off > label:first-child { color: var(--text-faint); }

/* Toolbars (RedTrack): row actions on the left; the table tools (Export,
   Columns, Density, Table reset) on their own right-aligned row just above
   the table. Only when the first group holds actions — Logs' first group is
   a row count, so its toolbar stays one line. */
.workspace-toolbar:has(> .workspace-toolbar__group:first-child .wt-action) { row-gap: 0; }
.workspace-toolbar__group:first-child:has(.wt-action) + .workspace-toolbar__group {
    flex-basis: 100%; justify-content: flex-end;
}
.workspace-toolbar__group:first-child:has(.wt-action) + .workspace-toolbar__group .wt-action { color: var(--text-dim); font-size: var(--fs-xs); }

.workspace-toolbar--tools-only { justify-content: flex-end; }
.workspace-toolbar--tools-only .wt-action { color: var(--text-dim); font-size: var(--fs-xs); }
/* Per-row actions column (Meta Pixels, like RedTrack's "Actions"). */
.pixel-actions-col { text-align: center !important; white-space: nowrap; }
.pixel-actions-col .icon-btn { display: inline-flex; vertical-align: middle; }

/* "More filters" toggle (app.js) — extra filters beyond RedTrack's set. */
.workspace-filterbar:not(.show-more) .wf-field--more { display: none; }
.wf-more-toggle {
    height: 36px; padding: 0 10px; border: 0; border-radius: var(--radius-sm); background: none;
    display: inline-flex; align-items: center; gap: 6px;
    font-size: var(--fs-sm); font-weight: 500; font-family: inherit; color: var(--brand); cursor: pointer; white-space: nowrap;
}
.wf-more-toggle:hover { background: var(--brand-tint); }
.wf-more-toggle__count {
    min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--radius-md);
    background: var(--brand); color: #fff; font-size: var(--fs-2xs); line-height: 18px; text-align: center;
}

/* × clear button inside text filters (RedTrack's Title / Pixel ID). */
.wf-clearable { position: relative; display: inline-flex; }
.wf-clearable > input { flex: 1; padding-right: 30px !important; } /* flex: a wide Search field stays wide */
.wf-clear {
    position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
    width: 20px; height: 20px; padding: 0; border: 0; border-radius: 50%;
    background: none; color: var(--text-faint); cursor: pointer; display: none;
    align-items: center; justify-content: center;
}
.wf-clear:hover { background: var(--surface-alt); color: var(--text); }
.wf-clearable.has-value .wf-clear { display: inline-flex; }

/* ================= Hover & motion (RedTrack / Material) =================
   RedTrack runs on Material-UI: every interactive element eases its
   background / border / shadow over 250ms, text buttons get a faint dark
   tint (not a colour change), outlined controls darken their border,
   primary buttons darken and lift, links underline, and a hovered table
   row turns light yellow across all its cells. Same behaviour here, in
   SMFlow's own palette. */
:root {
    --ease: cubic-bezier(.4, 0, .2, 1);
    --hover-tint: rgba(16, 24, 40, .06);     /* text/ghost buttons, menu rows */
    --press-tint: rgba(16, 24, 40, .10);
    --hover-border: #667085;                 /* outlined controls */
    --row-hover: #FFF9C4;                    /* RedTrack's table-row hover */
    --row-current: #FFF59D;                  /* clicked row (app.js), a shade stronger */
}

/* Motion on everything clickable. */
a, button, .btn, .btn-secondary, .wt-action, .icon-btn, .nav-link, .page-tab, .tab-link,
.rpt-chip, .rpt-grouping__btn, .wf-more-toggle, .wf-compare-toggle, .drp, .drp-step, .drp-trigger,
.drp-preset, .drp-day, .columns-panel label, select, input, textarea {
    transition: background-color .25s var(--ease), color .2s var(--ease), border-color .25s var(--ease), box-shadow .25s var(--ease), opacity .2s var(--ease);
}

/* Text buttons: faint dark tint (the old surface-alt tint was lighter than the page, so invisible). */
.wt-action:hover, .wf-more-toggle:hover, .drp-step:hover:not(:disabled), .drp-trigger:hover,
.drp-preset:hover, .drp-nav:hover, .drp-day:hover, .columns-panel label:hover, .filters-menu a:hover,
.chip-search-menu a:hover, .cs-row:hover, .wf-clear:hover { background-color: var(--hover-tint); }
.wt-action:active:not(:disabled), .wf-more-toggle:active, .drp-step:active:not(:disabled) { background-color: var(--press-tint); }
.wt-action:disabled { opacity: .45; }
.wt-action:disabled:hover { background: none; }

/* Sidebar: same tint (the old var(--surface-alt) barely showed on white). */
.nav-link:hover { background: var(--hover-tint); color: var(--text-strong); }
.nav-link.active:hover { background: rgba(37, 99, 235, .12); color: var(--brand); }

/* Primary buttons: darker + a small lift; pressed sinks back. */
.btn:hover { background: var(--brand-hover); box-shadow: 0 1px 1px rgba(16, 24, 40, .16), 0 3px 5px -2px rgba(16, 24, 40, .28); }
.btn:active { box-shadow: none; filter: brightness(.95); }

/* Outlined controls: the border darkens (RedTrack goes near-black). */
.btn-secondary:hover, .rpt-grouping__btn:hover, .wf-compare-toggle:not(.is-active):hover, .drp:hover,
.workspace-filterbar .wf-field select:hover, .workspace-filterbar .wf-field input:not([type=checkbox]):hover,
select:not([multiple]):not([size]):hover, .editor-body select:hover { border-color: var(--hover-border); }
.btn-secondary:hover, .rpt-grouping__btn:hover { background-color: var(--hover-tint); }
.drp.is-open, .drp.is-open:hover { border-color: var(--brand); }

/* Icon buttons (row actions): tint instead of a colour jump; pressed a bit deeper. */
.icon-btn:hover { background: var(--hover-tint); border-color: var(--hover-border); color: var(--text); }
.icon-btn:active { background: var(--press-tint); }

/* Table links underline on hover (plain links already do, see a:hover at the top). */
.entity-name-link:hover, .click-id-link:hover { text-decoration: underline; }

/* Table rows: RedTrack's light-yellow hover across every cell — pinned
   columns and red/green-tinted rows included (their rules pin a background
   on cells, hence !important). The clicked row stays its stronger yellow. */
:is(.logs-clicks-table, .landers-table) tbody tr:hover > td { background-color: var(--row-hover) !important; filter: none !important; }
/* Tables inside edit forms / modals (sub-parameter mappings, account
   pickers…) get no row hover at all — RedTrack's forms don't highlight rows. */
:is(.modal, .editor-body, .modal-section) table tbody tr:hover > td { background-color: transparent !important; }

/* Traffic Channel "Additional Parameters" (RedTrack layout): a row of four
   outlined fields per parameter, each labelled in its own border. */
.param-rows { display: flex; flex-direction: column; gap: 16px; padding-top: 8px; }
.param-row { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
.param-row .field { margin: 0; }
.param-row .field input::placeholder { color: var(--text-faint); }
/* Offer Sources' postback fields: parameter + network macro + a Required switch. */
.param-row--postback { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto; align-items: center; }
.param-row__switch { display: inline-flex; align-items: center; gap: 10px; font-size: var(--fs-sm); color: var(--text); white-space: nowrap; cursor: pointer; padding-right: 4px; }
@media (max-width: 760px) { .param-row, .param-row--postback { grid-template-columns: 1fr 1fr; } }
:is(.logs-clicks-table, .landers-table) tbody tr.is-current > td,
:is(.logs-clicks-table, .landers-table) tbody tr.is-current:hover > td { background-color: var(--row-current) !important; }
:is(.logs-clicks-table, .landers-table) tbody tr:hover .row-hover-actions { background: var(--row-hover) !important; }
:is(.logs-clicks-table, .landers-table) tbody tr.is-current .row-hover-actions { background: var(--row-current) !important; }

/* ================= Typography (RedTrack) =================
   What made pages feel dated: buttons/inputs fell back to the browser's
   Arial, metric values were in a monospace "terminal" font, and labels were
   tiny (10–10.5px) faint ALL-CAPS with letter-spacing. RedTrack uses one
   font throughout, sentence-case labels at 12px+, 500-weight headings and
   numbers, and dark secondary text. Same system here, keeping Inter. */
:root { --text-2: var(--text-2); } /* secondary text: labels, periods — darker than --text-faint for contrast */

/* One font everywhere: form controls don't inherit it by default (they were Arial). */
button, input, select, textarea, optgroup { font-family: inherit; }
body { font-feature-settings: 'cv11', 'ss01'; } /* Inter's cleaner "a"/"1" alternates */

/* Page titles: bigger and a touch tighter, like RedTrack's. */
.workspace-header__title { font-size: 24px; font-weight: 600; letter-spacing: -0.02em; }
.panel__title { font-size: var(--fs-md); font-weight: 600; }

/* Numbers: the UI font with even-width digits — not monospace. */
.kpi-card__value, .kpi-card__delta, table.data-table td, .hero-kpi__value, .mc-tile__value,
.logs-clicks-table td.num, .landers-table td.num, .th-total { font-family: var(--font-ui); font-variant-numeric: tabular-nums; }
.kpi-card__value { font-size: var(--fs-2xl); font-weight: 500; letter-spacing: -0.01em; }
.hero-kpi__value { font-size: var(--fs-2xl); font-weight: 500; letter-spacing: -0.01em; }
.hero-kpi__value--sub { font-size: var(--fs-lg); font-weight: 500; }
.mc-tile__value { font-size: var(--fs-2xl); font-weight: 500; }

/* Labels: sentence case, 12px, readable grey (was 10–10.5px faint caps). */
.kpi-card__label, .hero-kpi__period, .mc-tile__label, .best-perf-table__head td {
    font-size: var(--fs-xs); font-weight: 400; letter-spacing: 0; text-transform: none; color: var(--text-2) !important;
}
.best-perf-label { font-size: var(--fs-xs); color: var(--text); }
.best-perf-table td { font-size: var(--fs-sm); }
.field label { font-size: var(--fs-2xs); font-weight: 400; color: var(--text-2); }
.field__hint { font-size: var(--fs-xs); color: var(--text-dim); }
table.data-table th { font-size: var(--fs-xs); letter-spacing: 0; color: var(--text-2); }
.health-item { font-size: var(--fs-sm); }

/* Small-caps section titles → sentence case (menus, drawers, column panels). */
.filters-menu__group-title, .cs-cat, .columns-panel__group, .click-drawer__section-title, .saved-views__label {
    font-size: var(--fs-2xs); font-weight: 600; text-transform: none; letter-spacing: 0; color: var(--text-2);
}
.tm-tabs__tab, .funnel-mode-tabs__tab, .filters-btn { text-transform: none; letter-spacing: 0; font-size: var(--fs-xs); }

/* Status badges: a size you can read. */
.badge { font-size: var(--fs-2xs); font-weight: 500; }

/* Tables (RedTrack's grid): header labels medium (500) and a size up, the
   totals under them bold, every body cell regular (400) — names included,
   they were 500 and read heavier than the row — and the coloured metric
   values (profit, ROI… on green/red rows) bold in a deep shade so they
   carry the row, where they had been a light 400. */
:is(.logs-clicks-table, .landers-table, .report-table) thead th,
:is(.logs-clicks-table, .landers-table, .report-table) thead th .th-label { font-size: var(--fs-sm); font-weight: 500; color: var(--text); }
:is(.logs-clicks-table, .landers-table, .report-table) thead .th-total,
:is(.logs-clicks-table, .landers-table) tr.totals-row td { font-size: var(--fs-sm); font-weight: 700; color: var(--text); }
:is(.logs-clicks-table, .landers-table, .report-table) tbody td { font-size: var(--fs-sm); font-weight: 400; color: var(--text); }
:is(.logs-clicks-table, .landers-table, .report-table) tbody td :is(.entity-name-link, .campaigns-grid__name-link, a) { font-weight: 400; }
.landers-table tbody td:nth-child(2).num { color: var(--text-2); } /* entity lists' # / ID column: readable, not faint */
:is(.logs-clicks-table, .landers-table, .report-table) :is(td, th, .th-total) :is(.num-positive, .num-negative),
:is(.logs-clicks-table, .landers-table, .report-table) :is(td, .th-total):is(.num-positive, .num-negative) { font-weight: 600; }
:is(.logs-clicks-table, .landers-table, .report-table) :is(td, .th-total).num-positive,
:is(.logs-clicks-table, .landers-table, .report-table) :is(td, th, .th-total) .num-positive { color: #067647; }
:is(.logs-clicks-table, .landers-table, .report-table) :is(td, .th-total).num-negative,
:is(.logs-clicks-table, .landers-table, .report-table) :is(td, th, .th-total) .num-negative { color: var(--negative); }

/* Keyboard focus: a clear ring, only for keyboard users (not on mouse clicks). */
:is(a, button, .btn, .btn-secondary, .wt-action, .icon-btn, .nav-link, .rpt-chip):focus-visible {
    outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 4px;
}

/* ================= Switches, radios, toggle groups (RedTrack / Material) =================
   RedTrack's forms use toggle switches for on/off settings (not checkboxes),
   Material radios, and tinted toggle-button groups for pick-one choices.
   Table row selectors stay plain native checkboxes, as RedTrack's do. */

/* Switch: <input type="checkbox" class="switch"> — still a real checkbox, so
   forms submit unchanged. Track 34×14, thumb 20px (RedTrack's metrics);
   the thumb is the input's ::before (same technique as .radio-option). */
input[type="checkbox"].switch,
.field label > input[type="checkbox"].switch {
    appearance: none; -webkit-appearance: none; position: relative; flex-shrink: 0;
    width: 34px; height: 14px; margin: 3px 3px; padding: 0; border: 0; border-radius: var(--radius-sm);
    background: rgba(16, 24, 40, .30); cursor: pointer; vertical-align: middle;
    transition: background-color .2s var(--ease);
}
input[type="checkbox"].switch::before {
    content: ''; position: absolute; top: -3px; left: -3px; width: 20px; height: 20px; border-radius: 50%;
    background: var(--surface-alt);
    box-shadow: 0 1px 3px rgba(16, 24, 40, .35), 0 0 0 1px rgba(16, 24, 40, .05);
    transition: transform .2s var(--ease), background-color .2s var(--ease), box-shadow .2s var(--ease);
}
input[type="checkbox"].switch:checked { background: rgba(37, 99, 235, .45); }
input[type="checkbox"].switch:checked::before { transform: translateX(20px); background: var(--brand); }
/* Material's halo around the thumb on hover / keyboard focus. */
input[type="checkbox"].switch:hover::before { box-shadow: 0 1px 3px rgba(16, 24, 40, .35), 0 0 0 9px var(--hover-tint); }
input[type="checkbox"].switch:checked:hover::before { box-shadow: 0 1px 3px rgba(16, 24, 40, .35), 0 0 0 9px rgba(37, 99, 235, .10); }
input[type="checkbox"].switch:focus-visible { outline: none; }
input[type="checkbox"].switch:focus-visible::before { box-shadow: 0 1px 3px rgba(16, 24, 40, .35), 0 0 0 9px rgba(37, 99, 235, .20); }
input[type="checkbox"].switch:disabled { opacity: .45; cursor: default; }
/* A little more room between the switch and its label text. */
label:has(> input.switch) { gap: 12px !important; cursor: pointer; }

/* Radio: Material proportions — 18px ring (2px, grey → brand) with a 10px dot. */
.radio-option { gap: 10px; font-size: var(--fs-sm); }
.radio-option input[type="radio"] {
    width: 18px; height: 18px; border: 2px solid rgba(16, 24, 40, .45);
    transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.radio-option input[type="radio"]:checked { border-color: var(--brand); }
.radio-option input[type="radio"]:checked::after { width: 8px; height: 8px; }
.radio-option input[type="radio"]:hover { box-shadow: 0 0 0 8px var(--hover-tint); }
.radio-option input[type="radio"]:checked:hover { box-shadow: 0 0 0 8px rgba(37, 99, 235, .10); }

/* Toggle-button group (.segmented, e.g. Lander Type): RedTrack's look — a
   thin tinted outline, the chosen option filled with a soft tint in the
   brand colour, the others muted; no white "lifted" pill. */
.segmented { background: var(--surface); border-color: rgba(16, 24, 40, .14); border-radius: var(--radius-sm); }
.segmented label {
    height: 36px; padding: 0 18px; font-size: var(--fs-xs); font-weight: 500; letter-spacing: 0;
    color: var(--text-dim); border-right-color: rgba(16, 24, 40, .12);
    transition: background-color .2s var(--ease), color .2s var(--ease);
}
.segmented label:hover { background: var(--hover-tint); color: var(--text); }
.segmented input[type="radio"]:checked + label { background: var(--brand-tint); color: var(--brand); box-shadow: none; }

/* ================= Surfaces, navigation & feedback (RedTrack / Material) ================= */
:root {
    /* Material elevations as RedTrack uses them. */
    --elev-1: 0 0 0 1px rgba(63, 63, 68, .05), 0 1px 2px rgba(63, 63, 68, .15);   /* cards, panels */
    --elev-2: 0 0 1px rgba(0, 0, 0, .31), 0 7px 12px -4px rgba(0, 0, 0, .18);      /* edit-form sections */
    --elev-8: 0 0 1px rgba(0, 0, 0, .31), 0 5px 8px -2px rgba(0, 0, 0, .25), 0 12px 24px -6px rgba(16, 24, 40, .14); /* menus, popovers */
    --elev-24: 0 0 1px rgba(0, 0, 0, .31), 0 24px 36px -8px rgba(0, 0, 0, .25);  /* dialogs */
}

/* 11. Cards: a soft Material shadow instead of a flat grey border. */
.panel, .hero-kpi, .kpi-card, .health-item { border-color: transparent; box-shadow: var(--elev-1); }
.kpi-card, .health-item { background: var(--surface); }

/* 4. Modals / edit forms: a deep dialog shadow; sections are shadowed cards
   (no border) with a larger title, spaced like RedTrack's. */
.modal { box-shadow: var(--elev-24); border-radius: var(--radius-sm); }
.modal__header .modal__title, .modal__header h2, .modal__header h3 { font-size: var(--fs-lg); font-weight: 600; }
.modal-section, .editor-body .modal-section { border: 0; box-shadow: var(--elev-2); border-radius: var(--radius-sm); padding: 16px 18px; margin-bottom: 16px; }
.modal-section__title, .editor-body .modal-section__title { font-size: var(--fs-md); font-weight: 500; color: var(--text); margin-bottom: 14px; }
.modal-subsection-title { font-size: var(--fs-xs); color: var(--text-2); }

/* 3. Tabs: RedTrack's — uppercase 12px medium, tall, dark text for every tab,
   a 2px brand underline on the active one, a hairline under the row. */
.page-tabs, .editor-tabs, .modal__tabs { gap: 0; border-bottom: 1px solid rgba(16, 24, 40, .12); }
.page-tab, .editor-tab, .tab-link, .modal__tabs a, .modal__tabs button {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 120px; height: 44px; padding: 0 16px; margin: 0 0 -1px;
    font-size: var(--fs-xs); font-weight: 500; letter-spacing: .03em; text-transform: uppercase;
    color: var(--text); border-bottom: 2px solid transparent; text-decoration: none;
}
.page-tab:hover, .editor-tab:hover, .tab-link:hover { background: var(--hover-tint); color: var(--text); text-decoration: none; }
.page-tab.is-active, .editor-tab.active, .tab-link.active { color: var(--brand); border-bottom-color: var(--brand); }

/* 6. Menus & popovers: rounder, Material shadow, roomier rows. */
.columns-panel, .drp-panel, .filters-menu, .chip-search-menu { border-color: transparent; border-radius: var(--radius-md); box-shadow: var(--elev-8); }
.columns-panel { padding: 6px; }
.columns-panel label, .filters-menu a, .chip-search-menu a, .drp-preset { min-height: 34px; padding: 6px 10px; border-radius: var(--radius-sm); font-size: var(--fs-sm); }
.rpt-grouping__panel { border-radius: var(--radius-md); }

/* 1. Pagination: RedTrack's bar — wide grey Previous / Next at the ends,
   "Page [ n ] of N" + rows in the middle, on a strip with a soft top shadow. */
.pagination-bar {
    justify-content: space-between; gap: 12px; margin-top: 0; padding: 6px;
    background: var(--surface); border-top: 2px solid rgba(0, 0, 0, .08);
    box-shadow: 0 0 15px rgba(0, 0, 0, .08); border-radius: 0 0 6px 6px;
}
.pagination-bar > :first-child, .pagination-bar > :last-child {
    flex: 1 1 0; max-width: 320px; height: 30px; justify-content: center;
    background: rgba(0, 0, 0, .06); color: rgba(0, 0, 0, .65); border-radius: 4px; font-size: var(--fs-xs); font-weight: 500;
}
.pagination-bar > :first-child:hover:not(:disabled):not(.is-disabled),
.pagination-bar > :last-child:hover:not(:disabled):not(.is-disabled) { background: rgba(0, 0, 0, .28); color: #fff; }
.pagination-bar > :is(:first-child, :last-child):is(:disabled, .is-disabled) { opacity: .45; cursor: default; }
.pagination-bar__label { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-xs); color: var(--text-2); }
.pagination-bar__jump {
    width: 64px; height: 28px; padding: 0 6px; text-align: center; font-size: var(--fs-xs);
    border: 1px solid rgba(0, 0, 0, .12); border-radius: 4px; background: var(--surface); color: var(--text);
}
.pagination-bar__jump:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-tint); }
.pagination-bar select { height: 28px; font-size: var(--fs-xs); }

/* 2. Status in tables: RedTrack shows a coloured dot, not a text pill
   (the word stays for screen readers and as the tooltip — app.js). */
/* Entity lists only (.landers-table: Campaigns, Offers, Landers…) — log
   tables reuse .badge.active for "sent" / "accepted" / "info", which must
   never collapse into an unlabelled dot. */
.landers-table td .badge:is(.active, .paused, .archived) {
    display: inline-block; width: 10px; height: 10px; min-width: 0; padding: 0; border: 0; border-radius: 50%;
    font-size: 0; line-height: 0; overflow: hidden; vertical-align: middle;
}
.landers-table td .badge.active { background: #4CAF50; }
.landers-table td .badge.paused { background: #FF9800; }
.landers-table td .badge.archived { background: #B0B7C3; }
.landers-table td[data-col="status"]:has(.badge:is(.active, .paused, .archived)) { text-align: center; }

/* Logs tables (RedTrack's log grids): everything is plain regular text —
   no blue/monospace IDs, no coloured status pills, no green "Yes" — on
   alternating light-grey / white rows. The Click ID still opens the click
   drawer; it just looks like text until hovered. */
:is(#clicks-table, #conv-table, #pb-table, #sys-table, [id^="logs-event-table"]) tbody :is(td, td.mono, td code) { font-family: var(--font-ui); font-weight: 400; color: var(--text); }
:is(#clicks-table, #conv-table, #pb-table, #sys-table, [id^="logs-event-table"]) tbody td code { background: none; padding: 0; font-size: inherit; }
:is(#clicks-table, #conv-table, #pb-table, #sys-table, [id^="logs-event-table"]) .click-id-link { color: inherit; font-family: inherit; }
:is(#clicks-table, #conv-table, #pb-table, #sys-table, [id^="logs-event-table"]) .click-id-link:hover { color: var(--brand); text-decoration: underline; }
:is(#clicks-table, #conv-table, #pb-table, #sys-table, [id^="logs-event-table"]) :is(.num-positive, .num-negative) { color: inherit !important; font-weight: 400 !important; }
:is(#clicks-table, #conv-table, #pb-table, #sys-table, [id^="logs-event-table"]) .badge { background: none !important; border: 0 !important; padding: 0; font-size: inherit; font-weight: 400; color: inherit !important; }
:is(#clicks-table, #conv-table, #pb-table, #sys-table, [id^="logs-event-table"]) .text-faint { color: var(--text-dim); }
:is(#clicks-table, #conv-table, #pb-table, #sys-table, [id^="logs-event-table"]) tbody tr:nth-child(odd) > td { background-color: var(--surface-alt); }
:is(#clicks-table, #conv-table, #pb-table, #sys-table, [id^="logs-event-table"]) tbody tr:nth-child(even) > td { background-color: var(--surface); }

/* 7. Tooltips: RedTrack's dark rounded tooltip (app.js turns title="" into it). */
.sm-tip {
    position: fixed; z-index: 1000; max-width: 300px; padding: 5px 9px; border-radius: 4px;
    background: rgba(38, 50, 56, .94); color: #fff; font-size: var(--fs-xs); font-weight: 500; line-height: 1.4;
    pointer-events: none; opacity: 0; transform: translateY(2px);
    transition: opacity .15s var(--ease), transform .15s var(--ease); white-space: pre-line; overflow-wrap: anywhere;
}
.sm-tip.is-on { opacity: 1; transform: none; }
.tt .tt-bubble { background: rgba(38, 50, 56, .94); border-radius: 4px; font-size: var(--fs-xs); font-weight: 500; }

/* 8. Empty states: an icon above the message, a proper title. */
.empty-state { padding: 48px 24px; }
.empty-state::before {
    content: ''; display: block; width: 44px; height: 44px; margin: 0 auto 12px; border-radius: 50%;
    background: var(--brand-tint) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232563EB' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 12h-6l-2 3h-4l-2-3H2'/%3E%3Cpath d='M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z'/%3E%3C/svg%3E") center / 22px no-repeat;
}
.empty-state__title { font-size: var(--fs-md); font-weight: 500; }
.empty-state__body { font-size: var(--fs-sm); color: var(--text-dim); }

/* 9. Scrollbars: thin and rounded, darker on hover (not the thick OS bars). */
* { scrollbar-width: thin; scrollbar-color: rgba(16, 24, 40, .22) transparent; }
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(16, 24, 40, .18); border-radius: var(--radius-md); border: 2px solid transparent; background-clip: padding-box; }
::-webkit-scrollbar-thumb:hover { background-color: rgba(16, 24, 40, .38); }
::-webkit-scrollbar-corner { background: transparent; }

/* 10. Toasts (flash messages): top-right, slide in; success fades out by itself (app.js). */
.toast-stack { position: fixed; top: 56px; right: 16px; /* just under the top bar, not over Settings / Sign out */ z-index: 1100; display: flex; flex-direction: column; gap: 8px; max-width: min(420px, calc(100vw - 32px)); }
.toast {
    display: flex; align-items: flex-start; gap: 10px; padding: 12px 14px; border-radius: var(--radius-sm);
    background: var(--text); color: #fff; font-size: var(--fs-sm); line-height: 1.45; box-shadow: var(--elev-8);
    animation: toast-in .25s var(--ease);
}
.toast--success { background: #1E7B4A; }
.toast--error { background: var(--negative); }
.toast__msg { flex: 1; min-width: 0; }
.toast__close { border: 0; background: none; color: rgba(255, 255, 255, .8); font-size: var(--fs-xl); line-height: 1; cursor: pointer; padding: 0 2px; }
.toast__close:hover { color: #fff; }
.toast.is-leaving { opacity: 0; transform: translateX(12px); transition: opacity .25s var(--ease), transform .25s var(--ease); }
@keyframes toast-in { from { opacity: 0; transform: translateX(16px); } to { opacity: 1; transform: none; } }

/* ================= Material controls (app.js "Material controls") ================= */

/* 1. Dropdown menu that replaces the browser's own <select> list. */
.sm-menu {
    position: fixed; z-index: 1200; max-width: min(420px, calc(100vw - 16px));
    background: var(--surface); border-radius: var(--radius-md); box-shadow: var(--elev-8);
    padding: 6px 0; display: flex; flex-direction: column;
    animation: sm-pop .16s var(--ease); transform-origin: top left;
}
.sm-menu.is-leaving { opacity: 0; transition: opacity .12s var(--ease); pointer-events: none; }
.sm-menu__search { padding: 4px 8px 6px; border-bottom: 1px solid rgba(16, 24, 40, .08); margin-bottom: 4px; }
.sm-menu__search input {
    width: 100%; height: 32px; padding: 0 10px; font-size: var(--fs-sm); border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--text);
}
.sm-menu__search input:focus { outline: none; border-color: var(--brand); box-shadow: inset 0 0 0 1px var(--brand); }
.sm-menu__list { max-height: 320px; overflow-y: auto; }
.sm-menu__item {
    position: relative; display: flex; align-items: center; gap: 10px; min-height: 36px; padding: 6px 14px;
    font-size: var(--fs-sm); color: var(--text); cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    transition: background-color .15s var(--ease);
}
.sm-menu__item.is-active { background: var(--hover-tint); }
.sm-menu__item.is-selected { background: var(--brand-tint); color: var(--brand); font-weight: 500; }
.sm-menu__item.is-selected.is-active { background: rgba(37, 99, 235, .14); }
.sm-menu__item.is-disabled { color: var(--text-faint); cursor: default; }
.sm-menu__item.is-empty { color: var(--text-faint); }
.sm-menu__group { padding: 10px 14px 4px; font-size: var(--fs-2xs); font-weight: 600; color: var(--text-2); }
.sm-menu__none { padding: 10px 14px; font-size: var(--fs-sm); color: var(--text-faint); }
/* Multi-select: a Material checkbox square on each row. */
.sm-menu--multi .sm-menu__item.is-selected { background: none; color: var(--text); font-weight: 400; }
.sm-menu--multi .sm-menu__item.is-selected.is-active { background: var(--hover-tint); }
.sm-menu__check {
    width: 18px; height: 18px; flex-shrink: 0; border: 2px solid rgba(16, 24, 40, .45); border-radius: 3px;
    transition: background-color .15s var(--ease), border-color .15s var(--ease);
}
.sm-menu__item.is-selected .sm-menu__check {
    background: var(--brand) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / 13px no-repeat;
    border-color: var(--brand);
}
select.is-open { border-color: var(--brand) !important; box-shadow: inset 0 0 0 1px var(--brand) !important; }

/* 2. Multi-select chip box (<select multiple data-chips>) — looks like the other filter fields. */
.chipbox__native { display: none !important; }
.chipbox {
    position: relative; display: flex; align-items: center; gap: 4px; flex-wrap: nowrap; overflow: hidden;
    height: 36px; min-width: 210px; width: auto; max-width: 360px; padding: 0 30px 0 8px; /* grows for chips */
    border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); cursor: pointer;
    transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
}
.chipbox::after { /* the dropdown chevron, as on the selects */
    content: ''; position: absolute; right: 10px; top: 50%; width: 10px; height: 6px; margin-top: -3px;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%2398A2B3' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
}
.chipbox:hover { border-color: var(--hover-border); }
.chipbox:focus, .chipbox.is-open { outline: none; border-color: var(--brand); box-shadow: inset 0 0 0 1px var(--brand); }
.chipbox__placeholder { font-size: var(--fs-sm); color: var(--text); padding-left: 4px; }
.chipbox__more { font-size: var(--fs-xs); font-weight: 500; color: var(--text-2); padding: 0 2px; flex-shrink: 0; }

/* 8. Chips (filter values, tags): Material — rounded, grey, a round × to remove. */
.sm-chip, .camp-tag, .chip-input__chip {
    display: inline-flex; align-items: center; gap: 4px; max-width: 150px; height: 24px; padding: 0 10px;
    border: 0; border-radius: 12px; background: rgba(16, 24, 40, .08); color: var(--text);
    font-size: var(--fs-xs); font-weight: 400; line-height: 24px; white-space: nowrap;
}
.sm-chip { padding-right: 3px; flex-shrink: 1; min-width: 0; }
.sm-chip__label, .camp-tag { overflow: hidden; text-overflow: ellipsis; }
.sm-chip__x, .camp-tag__x, .chip-input__chip button {
    display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 18px; height: 18px; padding: 0; margin: 0; border: 0; border-radius: 50%;
    background: rgba(16, 24, 40, .26); color: #fff; font-size: var(--fs-sm); line-height: 1; opacity: 1; cursor: pointer;
    transition: background-color .15s var(--ease);
}
.sm-chip__x:hover, .camp-tag__x:hover, .chip-input__chip button:hover { background: rgba(16, 24, 40, .5); color: #fff; }
.camp-tag { height: 22px; line-height: 22px; font-size: var(--fs-xs); padding: 0 9px; }
.camp-tag:has(.camp-tag__x) { padding-right: 3px; }
.camp-tag--pick { cursor: pointer; }
.camp-tag--pick:hover { background: rgba(16, 24, 40, .14); }
.camp-tag--pick.is-on { background: var(--brand-tint); color: var(--brand); }

/* 3. Ripple (app.js adds a .sm-ripple span to the pressed element). */
.sm-ripple { position: absolute; inset: 0; overflow: hidden; border-radius: inherit; pointer-events: none; }
.sm-ripple__dot {
    position: absolute; border-radius: 50%; background: currentColor; opacity: .18; transform: scale(0);
    animation: sm-ripple .45s var(--ease) forwards;
}
.sm-ripple__dot.is-fading { opacity: 0; transition: opacity .35s var(--ease); }
@keyframes sm-ripple { to { transform: scale(1); } }

/* 4. Material focus: a 2px brand border and the label in brand colour — no glow. */
.workspace-filterbar .wf-field select:focus,
.workspace-filterbar .wf-field input:not([type=checkbox]):not([type=radio]):focus,
.field input:not([type=checkbox]):not([type=radio]):focus, .field select:focus, .field textarea:focus,
.editor-body select:focus {
    outline: none; border-color: var(--brand); box-shadow: inset 0 0 0 1px var(--brand);
}
.drp.is-open, .drp.is-open:hover { box-shadow: inset 0 0 0 1px var(--brand); }
.chip-input:focus-within, .chip-input.chip-input--menu-open { box-shadow: inset 0 0 0 1px var(--brand); }
.workspace-filterbar .wf-field:focus-within > label:first-child,
.workspace-filterbar .wf-field:has(.is-open) > label:first-child,
.field:focus-within > label:first-child:not(:has(input)),
.field:has(select.is-open) > label:first-child { color: var(--brand); }

/* 5. Opening animations: menus and popovers grow in; modals rise; the backdrop fades. */
@keyframes sm-pop { from { opacity: 0; transform: scale(.97) translateY(-4px); } to { opacity: 1; transform: none; } }
@keyframes sm-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes sm-rise { from { opacity: 0; transform: translateY(14px) scale(.985); } to { opacity: 1; transform: none; } }
.columns-panel.open, .drp-panel.open, .rpt-grouping__panel.open { animation: sm-pop .16s var(--ease); transform-origin: top left; }
.modal-backdrop { animation: sm-fade .2s var(--ease); }
.modal { animation: sm-rise .24s var(--ease); }

/* 6. Uppercase labels where RedTrack uses them: edit-form header/footer
   buttons, the dashboard's Apply / Refresh, and the table tools row
   (EXPORT · COLUMNS · DENSITY · TABLE RESET). */
.modal__header .btn, .modal__header .btn-secondary, .modal__footer .btn, .modal__footer .btn-secondary, .mc-side .btn,
.workspace-toolbar__group + .workspace-toolbar__group .wt-action, .workspace-toolbar--tools-only .wt-action {
    text-transform: uppercase; letter-spacing: .04em; font-size: var(--fs-xs); font-weight: 500;
}

/* 7. Top progress bar while the next page loads. */
.sm-progress { position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 2000; overflow: hidden; pointer-events: none; opacity: 0; transition: opacity .2s; }
.sm-progress.is-on { opacity: 1; background: rgba(37, 99, 235, .18); }
.sm-progress.is-on::before {
    content: ''; position: absolute; top: 0; bottom: 0; left: 0; width: 40%; background: var(--brand);
    animation: sm-progress 1.1s cubic-bezier(.65, .815, .735, .395) infinite;
}
@keyframes sm-progress { from { left: -40%; } to { left: 100%; } }

/* 9. A soft shadow under the sticky table header once the table is scrolled. */
.logs-clicks-wrap.is-scrolled thead tr:last-child > th { box-shadow: 0 3px 6px -3px rgba(16, 24, 40, .22); }
.logs-clicks-wrap.is-scrolled .landers-table thead tr:last-child > th:nth-child(3) { box-shadow: 1px 0 0 var(--border), 0 3px 6px -3px rgba(16, 24, 40, .22); }

/* ===========================================================
   Phase 1 — design-token layer (loaded last on purpose).
   Applies the new radius / elevation / type / colour tokens to the
   shared components. Page-specific rules above keep working; this only
   restyles the common surfaces. Edit tokens in :root, not here.
   =========================================================== */
html, body { line-height: 1.5; }
.workspace-header__title { font-size: var(--fs-2xl); font-weight: 700; letter-spacing: -0.02em; color: var(--text-strong); }

/* Surfaces: softer corners + a whisper of elevation */
.panel, .kpi-card, .hero-kpi { border-radius: var(--radius-md); box-shadow: var(--shadow-1); }
.panel__header { padding: 12px 16px; }
.panel__title { font-size: var(--fs-sm); font-weight: 600; color: var(--text-strong); letter-spacing: -0.005em; }
.kpi-card { padding: 14px 16px; transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease); }
.kpi-card:hover { box-shadow: var(--shadow-2); }
.kpi-card__label { font-weight: 600; text-transform: uppercase; letter-spacing: .05em; }
.kpi-card__value { font-size: var(--fs-2xl); font-weight: 700; letter-spacing: -0.02em; color: var(--text-strong); }
.modal { border-radius: var(--radius-lg); box-shadow: var(--shadow-3); }
.modal-backdrop { backdrop-filter: blur(3px); }
.modal__title { font-size: var(--fs-md); font-weight: 600; color: var(--text-strong); }

/* Dashboard hero cards: tonal header + gradient icon chip (blue/violet, green/teal, amber) */
.hero-kpi { transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease); }
.hero-kpi:hover { box-shadow: var(--shadow-2); transform: translateY(-1px); }
.hero-kpi__icon { border-radius: var(--radius-md); box-shadow: 0 2px 6px rgba(16,24,40,.18); }
.hero-kpi__title { font-weight: 600; color: var(--text-strong); }
.hero-kpi__value { font-size: var(--fs-2xl); font-weight: 700; letter-spacing: -0.02em; color: var(--text-strong); }
.hero-kpi--blue   .hero-kpi__head { background: linear-gradient(135deg, var(--brand-tint), var(--accent-2-tint)); }
.hero-kpi--blue   .hero-kpi__icon { background: linear-gradient(135deg, var(--brand), var(--accent-2)); }
.hero-kpi--green  .hero-kpi__head { background: linear-gradient(135deg, var(--positive-tint), var(--teal-tint)); }
.hero-kpi--green  .hero-kpi__icon { background: linear-gradient(135deg, var(--positive), var(--teal)); }
.hero-kpi--orange .hero-kpi__head { background: linear-gradient(135deg, var(--warning-tint), #FDECEF); }
.hero-kpi--orange .hero-kpi__icon { background: linear-gradient(135deg, var(--warning), #EF6C2E); }

/* Buttons: depth, rhythm, tactile press */
.btn, .btn-secondary, .btn-add { transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease),
    box-shadow var(--dur) var(--ease), color var(--dur) var(--ease), transform var(--dur) var(--ease); }
.btn { font-weight: 600; box-shadow: 0 1px 2px rgba(37,99,235,.28); }
.btn:hover { box-shadow: 0 3px 10px rgba(37,99,235,.30); }
.btn:active, .btn-secondary:active, .btn-add:active { transform: translateY(1px); box-shadow: none; }
.btn-secondary { font-weight: 500; box-shadow: var(--shadow-1); }
.btn-secondary:hover { border-color: var(--border-strong); background: var(--surface-hover); }
.btn-add { box-shadow: 0 1px 2px rgba(21,154,98,.28); }

/* Badges: pill shape, tinted, slightly bolder */
.badge { border-radius: var(--radius-pill); padding: 2px 9px; font-weight: 600; letter-spacing: .01em; }
.badge.active { background: var(--positive-tint); color: #0E7A4C; }

/* Sidebar: rounded pills + a clear active state */
.nav-link { border-radius: var(--radius-sm); transition: background var(--dur) var(--ease), color var(--dur) var(--ease); }
.nav-link.active { background: var(--brand-tint); color: var(--brand); font-weight: 600; }
.nav-link.active svg { color: var(--brand); }

/* Forms: consistent focus ring */
input:not([type="checkbox"]):not([type="radio"]):focus, select:focus, textarea:focus { outline: none; border-color: var(--brand); box-shadow: var(--ring); }

/* Thin, quiet scrollbars */
* { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: var(--radius-pill); border: 2px solid transparent; background-clip: padding-box; }
::-webkit-scrollbar-thumb:hover { background: var(--text-faint); background-clip: padding-box; border: 2px solid transparent; }

/* Phones / touch: bigger targets, no iOS zoom-on-focus */
@media (max-width: 900px) {
    .workspace-header { flex-wrap: wrap; gap: 10px; }
    .workspace-header__title { font-size: var(--fs-xl); }
    .hero-kpi-grid, .best-performing-grid { grid-template-columns: 1fr; }
    .kpi-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 900px) and (pointer: coarse) {
    input:not([type="checkbox"]):not([type="radio"]), select, textarea { font-size: 16px; }
    .btn, .btn-secondary, .btn-add { min-height: 40px; }
}

/* Motion: honour the OS "reduce motion" setting */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important;
        transition-duration: .01ms !important; scroll-behavior: auto !important; }
    .hero-kpi:hover { transform: none; }
}

/* ===========================================================
   Phase 2 — unified components (loaded last on purpose).
   One look for buttons, tables, empty states and trend pills across
   every page; markup is unchanged, these only restyle what exists.
   =========================================================== */

/* ---- Buttons: shared size / radius / weight across .btn, .btn-secondary, .btn-add, .icon-btn ---- */
:is(.btn, .btn-secondary, .btn-add, .filters-btn) { border-radius: var(--radius-sm); letter-spacing: -0.003em; }
.btn-secondary { background: var(--surface); color: var(--text-2); border-color: var(--border-strong); font-weight: 500; }
.btn-secondary:hover { color: var(--text-strong); }
.btn-add:hover, .filters-btn:hover { filter: none; background: #0F8A57; }
.icon-btn { border-radius: var(--radius-sm); transition: background var(--dur) var(--ease), color var(--dur) var(--ease), border-color var(--dur) var(--ease); }
/* Opt-in variants for new markup (existing buttons keep working unchanged). */
.btn--tonal { background: var(--brand-tint); color: var(--brand); box-shadow: none; }
.btn--tonal:hover { background: var(--brand-container); box-shadow: none; }
.btn--danger { background: var(--negative); box-shadow: 0 1px 2px rgba(217,45,58,.28); }
.btn--danger:hover { background: #B8232E; box-shadow: 0 3px 10px rgba(217,45,58,.3); }
.btn--sm { height: 28px; padding: 0 10px; font-size: var(--fs-xs); }

/* ---- Tables: one hover, header and numeric style for every table component ---- */
:is(.data-table, .logs-clicks-table, .landers-table, .report-table, .campaigns-grid) tbody tr { transition: background var(--dur) var(--ease); }
:is(.data-table, .logs-clicks-table, .landers-table, .report-table, .campaigns-grid) tbody tr:hover td { background: var(--surface-hover); }
:is(.data-table, .logs-clicks-table, .landers-table, .report-table, .campaigns-grid) thead th { border-bottom: 1px solid var(--border-strong); }
:is(.data-table, .logs-clicks-table, .landers-table, .report-table, .campaigns-grid) td { font-variant-numeric: tabular-nums; }
table.data-table th { color: var(--text-dim); font-weight: 600; text-transform: uppercase; letter-spacing: .05em; }
.workspace-table-wrap, .table-scroll { border-radius: 0 0 var(--radius-md) var(--radius-md); }
.num-positive { color: #0E7A4C; }

/* ---- Trend pills (dashboard + KPI deltas) ---- */
.trend { display: inline-flex; align-items: center; gap: 2px; padding: 1px 7px; border-radius: var(--radius-pill);
    font-size: var(--fs-2xs); font-weight: 600; vertical-align: middle; margin-left: 4px; font-variant-numeric: tabular-nums; }
.trend--up { background: var(--positive-tint); color: #0E7A4C; }
.trend--down { background: var(--negative-tint); color: var(--negative); }

/* ---- Hero sparklines ---- */
.hero-kpi__head { position: relative; }
.hero-kpi__spark { margin-left: auto; display: inline-flex; flex-direction: column; align-items: flex-end; line-height: 1; color: var(--brand); }
.hero-kpi--green  .hero-kpi__spark { color: var(--positive); }
.hero-kpi--orange .hero-kpi__spark { color: #EF6C2E; }
.hero-kpi__spark em { font-style: normal; font-size: 10px; color: var(--text-faint); margin-top: 2px; letter-spacing: .04em; }
.hero-spark { width: 96px; height: 30px; display: block; overflow: visible; }
.hero-spark__area { fill: currentColor; opacity: .14; }
.hero-spark__line { fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }

/* ---- Empty states: tonal icon, clear hierarchy, same everywhere ---- */
.empty-state { background: var(--surface); }
.empty-state__title { font-weight: 600; color: var(--text-strong); }
.alerts-empty, .best-perf-empty { display: flex; align-items: center; gap: 8px; color: var(--text-faint); }
.alerts-empty::before, .best-perf-empty::before { content: ''; flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--border-strong); }
.alerts-empty { padding: 18px 16px; }
.best-perf-empty { padding: 4px 0 10px; }

/* Metrics chart with nothing to plot: dim the empty axes, say why */
.mc-chart-wrap { position: relative; }
.mc-chart-wrap.is-empty .mc-chart { opacity: .25; }
.mc-empty { position: absolute; inset: 40px 0 0 0; display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 4px; text-align: center; padding: 0 24px; pointer-events: none; }
.mc-empty strong { font-size: var(--fs-md); font-weight: 600; color: var(--text-strong); }
.mc-empty span { font-size: var(--fs-sm); color: var(--text-dim); max-width: 340px; }

/* ---- Touch / phones: row actions flow under the name instead of overlapping it ---- */
@media (hover: none), (max-width: 900px) {
    :is(.campaigns-grid__name-cell, .entity-name-cell) { white-space: normal; overflow: visible; }
    .campaigns-grid__name-link { padding-right: 0; }
    :is(.campaigns-grid__name-cell, .entity-name-cell) .row-hover-actions {
        position: static; transform: none; opacity: 1; pointer-events: auto; margin-top: 4px; background: none;
    }
}
/* Topbar on phones: keep it one tidy line (email truncates, links stay tappable) */
@media (max-width: 900px) {
    .topbar { flex-wrap: wrap; row-gap: 4px; padding-top: 6px; padding-bottom: 6px; }
    .topbar__user { max-width: 100%; display: flex; align-items: center; gap: 12px; }
    .topbar__user > span { max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .topbar__user a { margin-left: 0; padding: 4px 0; }
}

/* ---- Small screens: grids that were fixed at 4 columns, and wrapping action rows ---- */
.health-item { min-width: 0; }
.workspace-header__actions { flex-wrap: wrap; }
@media (max-width: 900px) { .health-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .health-grid { grid-template-columns: 1fr; } }

/* ===========================================================
   Phase 3 — navigation drawer, topbar controls, collapsible filters, dark mode.
   =========================================================== */
.topbar__menu, .topbar__theme {
    display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; padding: 0;
    border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--topbar-text); cursor: pointer;
    transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.topbar__menu:hover, .topbar__theme:hover { background: rgba(255, 255, 255, .09); color: #fff; }
.topbar__menu { display: none; margin-right: 8px; flex: none; }
.topbar__theme { margin-right: 6px; }
.topbar__menu svg, .topbar__theme svg { width: 18px; height: 18px; }
.topbar__theme .i-sun { display: none; }
:root[data-theme="dark"] .topbar__theme .i-moon { display: none; }
:root[data-theme="dark"] .topbar__theme .i-sun { display: block; }
body.nav-locked { overflow: hidden; }
@media (max-width: 900px) {
    .topbar__menu { display: inline-flex; }
    .topbar__user > .topbar__theme { margin-right: 0; }
}

/* Filters: a toggle on phones; always expanded on desktop (button hidden) */
.filters-toggle { display: none; }
@media (max-width: 900px) {
    .filters-toggle {
        display: flex; align-items: center; gap: 8px; width: 100%; height: 38px; padding: 0 12px; margin: 0 0 10px;
        border: 1px solid var(--border-strong); border-radius: var(--radius-sm); background: var(--surface); color: var(--text-2);
        font: inherit; font-size: var(--fs-sm); font-weight: 500; cursor: pointer; box-shadow: var(--shadow-1);
    }
    .filters-toggle svg { width: 15px; height: 15px; flex: none; }
    .filters-toggle__chev { margin-left: auto; transition: transform var(--dur) var(--ease); }
    .filters-toggle.is-open .filters-toggle__chev { transform: rotate(180deg); }
    .workspace-filterbar:not(.is-open) { display: none; }
}

/* ---- Dark theme: token overrides only; components inherit them ---- */
:root[data-theme="dark"] {
    color-scheme: dark;
    --bg: #0D111A; --surface: #151B27; --surface-alt: #1A2130; --surface-hover: #1F2738;
    --border: #273044; --border-strong: #364158;
    --text: #E3E8F2; --text-strong: #F3F6FB; --text-2: #B4BDCE; --text-dim: #97A2B8; --text-faint: #6F7B92;
    --brand: #4C8DF6; --brand-hover: #6BA0F8; --brand-tint: rgba(76, 141, 246, .16); --brand-container: rgba(76, 141, 246, .26);
    --on-brand-container: #CFE0FF;
    --positive: #2DB67C; --positive-tint: rgba(45, 182, 124, .16);
    --negative: #EF5B68; --negative-tint: rgba(239, 91, 104, .16);
    --warning: #F5B93A; --warning-tint: rgba(245, 185, 58, .16);
    --accent-2: #A78BFA; --accent-2-tint: rgba(167, 139, 250, .18);
    --teal: #2DD4BF; --teal-tint: rgba(45, 212, 191, .15);
    --topbar: #0A0D13; --topbar-text: #9AA3B5;
    --chart-1: #60A5FA; --chart-2: #A78BFA; --chart-3: #2DD4BF; --chart-4: #FBBF24; --chart-5: #F472B6; --chart-6: #34D399;
    --shadow-1: 0 1px 2px rgba(0, 0, 0, .35), 0 1px 3px rgba(0, 0, 0, .3);
    --shadow-2: 0 4px 8px rgba(0, 0, 0, .3), 0 8px 24px rgba(0, 0, 0, .35);
    --shadow-3: 0 12px 24px rgba(0, 0, 0, .4), 0 32px 64px rgba(0, 0, 0, .5);
    --elev-1: 0 0 0 1px rgba(255, 255, 255, .04), 0 1px 2px rgba(0, 0, 0, .5);
    --elev-2: 0 0 0 1px rgba(255, 255, 255, .05), 0 7px 12px -4px rgba(0, 0, 0, .5);
    --elev-8: 0 0 0 1px rgba(255, 255, 255, .06), 0 8px 16px -2px rgba(0, 0, 0, .55);
    --elev-24: 0 0 0 1px rgba(255, 255, 255, .06), 0 24px 36px -8px rgba(0, 0, 0, .6);
    --ring: 0 0 0 3px rgba(76, 141, 246, .4);
    --hover-tint: rgba(255, 255, 255, .06); --press-tint: rgba(255, 255, 255, .10); --hover-border: #8B96AB;
    --row-hover: #1F2738; --row-current: #474223;
}
:root[data-theme="dark"] .modal-backdrop, :root[data-theme="dark"] .nav-backdrop { background: rgba(0, 0, 0, .6); }
:root[data-theme="dark"] .form-info { background: var(--brand-tint); border-color: var(--brand-container); color: var(--on-brand-container); }
:root[data-theme="dark"] :is(.num-positive, .trend--up, .badge.active) { color: #4ADE80; }
:root[data-theme="dark"] .badge.paused { color: #FBBF24; }
:root[data-theme="dark"] :is(.logs-clicks-table, .landers-table, .report-table) :is(td, th, .th-total) .num-positive { color: #4ADE80; }
:root[data-theme="dark"] .hero-kpi--orange .hero-kpi__head { background: linear-gradient(135deg, var(--warning-tint), rgba(239, 108, 46, .14)); }
/* RedTrack-style ROI row tints, as opaque dark equivalents (pinned columns must not be see-through) */
:root[data-theme="dark"] :is(.logs-clicks-table, .landers-table) tbody tr.row-positive-strong td,
:root[data-theme="dark"] .landers-table tbody tr.row-positive-strong td:nth-child(-n+3) { background: #1C403E; }
:root[data-theme="dark"] :is(.logs-clicks-table, .landers-table) tbody tr.row-positive td,
:root[data-theme="dark"] .landers-table tbody tr.row-positive td:nth-child(-n+3) { background: #192F34; }
:root[data-theme="dark"] :is(.logs-clicks-table, .landers-table) tbody tr.row-negative td,
:root[data-theme="dark"] .landers-table tbody tr.row-negative td:nth-child(-n+3) { background: #2F2330; }
:root[data-theme="dark"] :is(.logs-clicks-table, .landers-table) tbody tr.row-negative-strong td,
:root[data-theme="dark"] .landers-table tbody tr.row-negative-strong td:nth-child(-n+3) { background: #452A36; }
:root[data-theme="dark"] :is(.logs-clicks-table, .landers-table) tbody tr.row-warning td,
:root[data-theme="dark"] .landers-table tbody tr.row-warning td:nth-child(-n+3) { background: #312F27; }
:root[data-theme="dark"] :is(.logs-clicks-table, .landers-table) tbody tr.is-current td,
:root[data-theme="dark"] .landers-table tbody tr.is-current td:nth-child(-n+3) { background: #474223; }
:root[data-theme="dark"] img.sidebar__logo { box-shadow: 0 0 0 1px rgba(255, 255, 255, .06); }
:root[data-theme="dark"] * { scrollbar-color: var(--border-strong) transparent; }
:root[data-theme="light"] { color-scheme: light; }

/* ===========================================================
   Phase 4 — SMGuard-inspired look: grey canvas, stronger type weights,
   simpler text boxes with a tinted focus ring. Tokens live in :root
   (light) and :root[data-theme="dark"]; this layer only applies them.
   =========================================================== */

/* ---- Type weights: confident headings, quiet body (SMGuard: 600 / 700 / 800) ---- */
.workspace-header__title { font-weight: 800; letter-spacing: -0.025em; }
.sidebar__brand { font-weight: 800; letter-spacing: -0.02em; }
.panel__title, .modal__title, .hero-kpi__title { font-weight: 700; }
.kpi-card__value, .hero-kpi__value, .mc-tile__value { font-weight: 800; letter-spacing: -0.02em; }
.hero-kpi__value--sub { font-weight: 600; }
.nav-link { font-weight: 600; color: var(--text-dim); }
.nav-link:hover { color: var(--text-strong); }
.nav-group__label { font-weight: 700; letter-spacing: .07em; }
.btn-secondary { font-weight: 600; }
.badge, .trend { font-weight: 700; }
:is(.logs-clicks-table, .landers-table, .report-table) thead th .th-label { font-weight: 600; }
.empty-state__title, .mc-empty strong { font-weight: 700; }
.entity-name-link, .campaigns-grid__name-link { font-weight: 600; }

/* ---- Grey canvas: panels and their headers read as cards on grey ---- */
.panel__header { background: var(--surface-alt); border-radius: var(--radius-md) var(--radius-md) 0 0; }
.panel, .kpi-card, .hero-kpi, .modal { border-color: var(--border); }
:is(.data-table, .logs-clicks-table, .landers-table, .report-table, .campaigns-grid) thead th { background: var(--surface-alt); }
.sidebar { background: var(--surface); }
.workspace-table-wrap { border-top-color: var(--border); }

/* ---- Text boxes: one consistent look for every input / select / textarea ---- */
:where(input[type="text"], input[type="number"], input[type="date"], input[type="email"], input[type="password"],
input[type="url"], input[type="search"], textarea), select:not([multiple]):not([size]) {
    border-color: var(--border-strong); border-radius: var(--radius-sm); color: var(--text); font-weight: 500;
    transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), background-color var(--dur) var(--ease);
}
:where(input[type="text"], input[type="number"], input[type="date"], input[type="email"], input[type="password"],
input[type="url"], input[type="search"], textarea):hover, select:not([multiple]):not([size]):hover { border-color: var(--text-faint); }
:where(input[type="text"], input[type="number"], input[type="date"], input[type="email"], input[type="password"],
input[type="url"], input[type="search"], textarea)::placeholder { color: var(--text-faint); font-weight: 400; }
.field input, .field select { font-size: var(--fs-sm); }
.field label, .wf-field label { font-weight: 600; color: var(--text-dim); }
.wf-field select, .wf-field input { height: 32px; font-size: var(--fs-sm); border-color: var(--border-strong); }

/* Pagination: let the controls wrap instead of pushing past the edge on narrow screens */
.pagination-bar { flex-wrap: wrap; row-gap: 8px; }

/* ---- Grey sidebar (SMGuard-style): tokens first, then the nav states that sit on it ---- */
:root {
    --sidebar-bg: #E8EBF0;
    --sidebar-border: #D8DCE3;
    --sidebar-text: #374151;
    --sidebar-hover: rgba(255, 255, 255, .65);
    --sidebar-active-bg: #FFFFFF;
}
:root[data-theme="dark"] {
    --sidebar-bg: var(--surface);
    --sidebar-border: var(--border);
    --sidebar-text: var(--text-dim);
    --sidebar-hover: var(--hover-tint);
    --sidebar-active-bg: var(--brand-tint);
}
.sidebar { background: var(--sidebar-bg); border-right-color: var(--sidebar-border); }
.sidebar__brand { border-bottom-color: var(--sidebar-border); }
.nav-link { color: var(--sidebar-text); }
.nav-link:hover { background: var(--sidebar-hover); color: var(--text-strong); }
.nav-link.active, .nav-link.active:hover { background: var(--sidebar-active-bg); color: var(--brand); box-shadow: var(--shadow-1); }
:root[data-theme="dark"] .nav-link.active, :root[data-theme="dark"] .nav-link.active:hover { box-shadow: none; }
.nav-group__label { color: var(--text-dim); }
