/* Oppo redesign — Phase 1 (foundation shell).
 *
 * Establishes the new app chrome:
 *   - 240-px dark left sidebar, red `#F8485E` accent stripe on its right edge
 *   - Frosted-glass top bar with the same red stripe along its bottom
 *   - Body region to the right of the sidebar, below the top bar
 *
 * No per-page styling lives here. The existing pages keep mounting into
 * `#content-area` unchanged; only the chrome around them changes.
 *
 * Tokens are pulled from `/css/pulse-theme.css` (loaded earlier in the
 * <head>). Hard-coded hex values are only used where Figma references a
 * raw value with no semantic token (e.g. the red accent stripe `#F8485E`,
 * which lives under `Destructive/Red40` in Figma but isn't yet exposed
 * via a CSS var on our side).
 */

:root {
    --oppo-sidebar-w:        240px;
    --oppo-topbar-h:         56px;
    --oppo-accent-red:       #F8485E;   /* Destructive/Red40 — chrome accent */
    --oppo-sidebar-bg:       var(--base-dark-bg-primary);    /* #080323 */
    --oppo-sidebar-active:   var(--base-dark-hover);          /* #1E1845 */
    --oppo-sidebar-text:     var(--base-grey-20);             /* #F3F4F6 */
    --oppo-topbar-bg:        rgba(8, 3, 35, 0.5);

    /* Type ramp — verbatim from Figma `CMP font styles/*` (file 168:1238).
     * All Montserrat, letter-spacing 0. Pair `font:` shorthand with
     * `letter-spacing: 0` because shorthand resets it. */
    --oppo-font-family:       'Montserrat', ui-sans-serif, system-ui, sans-serif;
    --oppo-type-h1:           600 24px/32px var(--oppo-font-family);  /* H1 header style    — Montserrat SemiBold 24/32 */
    --oppo-type-h2:           600 18px/28px var(--oppo-font-family);  /* H2 header type     — Montserrat SemiBold 18/28 */
    --oppo-type-h3:           600 14px/24px var(--oppo-font-family);  /* H3 header type     — Montserrat SemiBold 14/24 */
    --oppo-type-body-l:       500 14px/24px var(--oppo-font-family);  /* BODY (L)           — Montserrat Medium  14/24 */
    --oppo-type-body-m:       500 12px/16px var(--oppo-font-family);  /* BODY (M)           — Montserrat Medium  12/16 */
    --oppo-type-body-m-strong:600 12px/16px var(--oppo-font-family);  /* BODY (M) Highlighted — SemiBold 12/16 */
    --oppo-type-body-s:       500 11px/14px var(--oppo-font-family);  /* BODY (S)           — Montserrat Medium  11/14 */
    --oppo-type-highlighted-m:600 12px/16px var(--oppo-font-family);  /* Highlighted Text M — Montserrat SemiBold 12/16 */
    --oppo-type-block-l:      500 14px/24px var(--oppo-font-family);  /* Block Text L       — Montserrat Medium  14/24 */
    --oppo-type-block-m:      500 12px/16px var(--oppo-font-family);  /* Block Text M / BODY (M) — Montserrat Medium 12/16 */
}

/* Bind Montserrat globally so legacy pages stop falling back to the
 * Tailwind system-sans default. Pulse already loads the @font-face
 * declarations in pulse-theme.css; we just need to point body at them. */
html, body {
    font-family: var(--oppo-font-family);
    letter-spacing: 0;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    /* Document-level safety net against horizontal wobble. The known
     * source (the 1680-px page-glow halo on `.oppo-main::before`) is
     * already clamped further down with `overflow-x: clip` on
     * `.oppo-main`, but anything ever leaking *outside* `.oppo-main`
     * (a future global toast, debug overlay, full-bleed banner) would
     * re-introduce the wobble. `overflow-x: clip` here clips without
     * spawning a scroll container, so `position: sticky` on the topbar
     * and sidebar keeps working. */
    overflow-x: clip;
}

/* Utility classes for new Oppo components — match Figma styles 1:1. */
.oppo-type-h1            { font: var(--oppo-type-h1);            letter-spacing: 0; }
.oppo-type-h2            { font: var(--oppo-type-h2);            letter-spacing: 0; }
.oppo-type-h3            { font: var(--oppo-type-h3);            letter-spacing: 0; }
.oppo-type-body-l        { font: var(--oppo-type-body-l);        letter-spacing: 0; }
.oppo-type-body-m        { font: var(--oppo-type-body-m);        letter-spacing: 0; }
.oppo-type-body-m-strong { font: var(--oppo-type-body-m-strong); letter-spacing: 0; }
.oppo-type-body-s        { font: var(--oppo-type-body-s);        letter-spacing: 0; }
.oppo-type-highlighted-m { font: var(--oppo-type-highlighted-m); letter-spacing: 0; }
.oppo-type-block-l       { font: var(--oppo-type-block-l);       letter-spacing: 0; }
.oppo-type-block-m       { font: var(--oppo-type-block-m);       letter-spacing: 0; }

/* Whole-app layout grid: sidebar | main column.
 * `.oppo-shell` replaces the document's flow at <body> level.
 *
 * The Oppo redesign is dark-themed per Figma — body bg is always `#080323`
 * (`--base-dark-bg-primary`) regardless of the legacy light/dark toggle.
 * Force the dark token-set on every descendant so inherited
 * `var(--text-main)` / `var(--bg-card)` references inside legacy markup
 * keep the right contrast against the Figma canvas. */
.oppo-shell {
    display: grid;
    grid-template-columns: var(--oppo-sidebar-w) 1fr;
    min-height: 100vh;
    background: var(--oppo-sidebar-bg);     /* #080323 */
    color: var(--oppo-sidebar-text);        /* #F3F4F6 */
    /* Override the legacy theme tokens for everything mounted inside the
     * shell so the cards, inputs and modals all see the dark palette
     * Figma was designed against. */
    --bg-body: #080323;
    --bg-card: rgba(255, 255, 255, 0.05);   /* canonical card surface — see docs/design-system.md §5.1 */
    --bg-input: #080323;
    --bg-nav: #080323;
    --bg-modal-backdrop: rgba(8, 3, 35, 0.8);  /* design-system.md §1.7 — page bg at 80% */
    --text-main: #F3F4F6;
    --text-muted: #C4C4C4;
    --border-dim: #1C3D5E;
}

/* ── Sidebar ─────────────────────────────────────────────────────────── */
/* Menu Desktop (Figma 374:6750): 240 × 100vh (Figma fixes 1024px),
 * padding 12px, gap 24px, background #080323. Right edge is a 1-px
 * 3-stop linear gradient (top→bottom): Destructive/Red40 #F8485E → Blue
 * Lagoon 100 #1C3D5E → Blue Lagoon 90 #2E689E. Stop positions sampled
 * from the published Figma render (red holds 0–6%, transitions to
 * blue100 by ~17%, eases to blue90 by ~70% and holds to bottom). The
 * design-system tool surfaces only the three colour stops (Hex panel),
 * not the positions — those are derived. Implemented with
 * `border-image` so the gradient maps onto the 1-px right edge with no
 * extra DOM. The other three border sides have width 0 so the gradient
 * paints only on the right. */
.oppo-sidebar {
    position: sticky;
    top: 0;
    align-self: start;
    height: 100vh;
    background: var(--oppo-sidebar-bg);
    border-right: 1px solid transparent;            /* width 1 — colour comes from border-image */
    border-image-source: linear-gradient(
        to bottom,
        #F8485E 0%,
        #1C3D5E 17%,
        #2E689E 70%,
        #2E689E 100%
    );
    border-image-slice: 1;
    padding: 12px;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 24px;
    z-index: 40;
    color: var(--oppo-sidebar-text);
    box-sizing: border-box;
}

/* Frame 747 — logo row. 216×40, padding 0 4px, flex-row centre.
 * Single composite SVG (Pulse-Oppo-lockup.svg, viewBox 0 0 216 40)
 * holds the Pulse wordmark, "by Devoteam" tagline, vertical divider,
 * and OPPO wordmark at Figma's exact offsets. */
.oppo-sidebar-logo {
    height: 40px;
    padding: 0 4px;
    align-self: stretch;
    display: flex;
    align-items: center;
    /* border-box keeps the 4-px horizontal padding inside the stretched
     * 216-px track. Without it, the 4+4 padding pushed the box to 224 px
     * and the right 8 px poked past the sidebar's red border. */
    box-sizing: border-box;
    min-width: 0;
}

.oppo-sidebar-logo .brand-lockup {
    display: block;
    /* Native size is 216×40, but the sidebar's 12-px padding leaves only
     * 216 px of track and the logo row reserves 4 px on each side — so
     * cap at 100% and let the aspect ratio do the rest. Anything wider
     * would peek past the sidebar's red right border and (combined with
     * the page-glow halo below) restore the horizontal wobble. */
    width: 216px;
    max-width: 100%;
    height: auto;
    flex: none;
}

/* The two nav stacks: the main one fills the available height, the
 * footer stack holds Administration pinned to the bottom. */
.oppo-sidebar-nav {
    display: flex;
    flex-direction: column;
    gap: 8px;
    flex: 1 0 auto;
    min-height: 0;
}

.oppo-sidebar-nav-footer {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: auto;
}

/* `1st level` nav item (Figma 168:1264 active / 168:1267 inactive):
 *   - 36-px tall, 4-px radius, gap 8 between icon + text
 *   - inactive: padding 12px 8px, transparent background
 *   - active:   padding 8px,      background #1E1845
 *   - text: Montserrat 600 12/16, colour Grey/Grey-20 #F3F4F6 */
.oppo-nav-item {
    display: flex;
    align-items: center;
    gap: 8px;
    height: 36px;
    padding: 12px 8px;
    border-radius: 4px;
    background: transparent;
    border: 0;
    color: var(--oppo-sidebar-text);
    font: var(--oppo-type-highlighted-m);
    letter-spacing: 0;
    cursor: pointer;
    text-align: left;
    width: 100%;
    box-sizing: border-box;
    transition: background-color 0.15s ease;
}

.oppo-nav-item:hover {
    background: var(--oppo-sidebar-active);
}

.oppo-nav-item.is-active {
    background: var(--oppo-sidebar-active);
    padding: 8px;
}

/* Active item: tint icon red (Destructive/Red40 #F8485E). Inactive items
 * keep the default white inherited from `.oppo-nav-item-icon` below. The
 * `currentColor` plumbing in inline SVGs and the mask `background-color`
 * on Figma-exported icons both pick this up automatically. */
.oppo-nav-item.is-active .oppo-nav-item-icon {
    color: #F8485E;
}

/* Figma `Icons` slot — fixed 16×16 box per item. The image inside is sized
 * to its native viewBox ratio (Figma exports use
 * `preserveAspectRatio="none"`, so both width AND height must be explicit).
 * Flex centring handles non-square icons (e.g. the Metrics cloud is 16×10.67
 * and ends up with 2.67-px slack top + bottom, matching the Figma layout
 * which uses `inset-[16.67%_0]` on that vector). */
.oppo-nav-item-icon {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Default icon colour — Grey/Grey-20 (#F3F4F6). Inline SVGs read this
     * via `stroke="currentColor"`; mask icons read it via `background-
     * color: currentColor`. Active state overrides above flips this to red. */
    color: #F3F4F6;
}

.oppo-nav-item-icon img,
.oppo-nav-item-icon svg {
    display: block;
    flex: none;
}

/* Mask-tinted Figma icons (Onboarding / Metrics / Opportunities). The
 * silhouette comes from the SVG's alpha channel; the visible pixels are
 * painted with `background-color: currentColor`, so the icon swaps from
 * white → red purely by changing the parent's `color` value. */
.oppo-nav-item-icon-mask {
    display: block;
    flex: none;
    background-color: currentColor;
    mask-image: var(--icon-url);
    -webkit-mask-image: var(--icon-url);
    mask-size: contain;
    -webkit-mask-size: contain;
    mask-repeat: no-repeat;
    -webkit-mask-repeat: no-repeat;
    mask-position: center;
    -webkit-mask-position: center;
}

/* Text label — Figma's `1st level > <text>` (176×16, Highlighted Text M,
 * Grey/Grey-20 #F3F4F6, flex-grow 1). */
.oppo-nav-item-label {
    flex: 1 0 0;
    min-width: 0;
    height: 16px;
    color: var(--oppo-sidebar-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Hide the entry when the user lacks the role (admin link). */
.oppo-nav-item[hidden] { display: none; }

/* ── Main column (top bar + body) ────────────────────────────────────── */
/* Figma's onboarding canvas has a prominent warm radial glow anchored at
 * the upper-left — a deep red/maroon mass (related to the `#F8485E`
 * Destructive/Red40 accent) that bleeds through purple/magenta and fades
 * into the `#080323` dark navy by the bottom-right. We replicate it with
 * two stacked radial gradients so the colour transitions through three
 * distinct hues, plus `background-attachment: fixed` so the glow stays
 * anchored to the viewport (it's an ambient backdrop, not page content). */
.oppo-main {
    display: flex;
    flex-direction: column;
    min-width: 0;       /* allow grid child to shrink, prevents h-overflow */
    min-height: 100vh;
    background: #080323;
    position: relative;
    isolation: isolate;
    /* Clip the 1680-px gradient halo pseudo-element below so it can't
     * leak past the right edge of the main column and turn the whole
     * document into a horizontal scroll container (= the "wobble").
     * `overflow-x: clip` clips without spawning a scroll container, so
     * the sticky `.oppo-topbar` keeps working (sticky breaks inside a
     * scroll-container ancestor, which `overflow: hidden` would create). */
    overflow-x: clip;
}

/* Figma "Gradient" frame (168:1237 / 78:3232 etc.) — designer-confirmed CSS:
 *   1680×159, left:240 top:0, linear-gradient 126.73deg, 75-px blur.
 * In our shell `.oppo-main` already starts AFTER the 240-px sidebar, so the
 * pseudo-element sits at left:0 of `.oppo-main`. Width is fixed 1680 to
 * match the Figma canvas; the blur extends the visual halo well past the
 * frame edges. */
.oppo-main::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    width: 1680px;
    height: 159px;
    background: linear-gradient(
        126.73deg,
        rgba(248,  72,  94, 0.6) 21.88%,
        rgba( 99,  35, 140, 0.6) 46.59%,
        rgba( 46, 104, 158, 0.6) 71.29%
    );
    filter: blur(75px);
    pointer-events: none;
    z-index: 0;
}
.oppo-main > * { position: relative; z-index: 1; }

/* `.oppo-topbar` is applied to the *legacy* <nav> by oppo-shell.js. The
 * legacy markup is `<nav><div class="max-w-7xl ..."><div class="flex h-16">…`.
 * We need to bulldoze the inner Tailwind containers so the flex row sits
 * directly inside the sticky 56-px Figma bar — and we need to drop the
 * legacy logo since the Pulse wordmark now lives in the sidebar. */
.oppo-topbar {
    position: sticky;
    top: 0;
    z-index: 30;
    height: var(--oppo-topbar-h);
    padding: 10px 32px;
    background: var(--oppo-topbar-bg);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    /* Figma 374:6796 — bottom border is a 4-stop linear gradient running
     * left→right: Destructive/Red40 → Blue Lagoon 100 → Blue Lagoon 90
     * → Blue Lagoon 90 (held to the right edge). Mirrors the sidebar's
     * right-edge gradient so the red corner sits at the upper-left of
     * the layout. Stops sampled from the published Figma render: red
     * holds 0–5%, transitions to blue100 by ~24%, eases to blue90 by
     * ~62% and holds to 100%. The Figma MCP tool collapsed this to a
     * single colour (`border-[#f8485e] border-b border-solid`) because
     * Tailwind can't express border-image gradients — stops are
     * derived from the rendered PNG. */
    border-bottom: 1px solid transparent;
    border-image-source: linear-gradient(
        to right,
        #F8485E 0%,
        #1C3D5E 24%,
        #2E689E 62%,
        #2E689E 100%
    );
    border-image-slice: 1;
    display: flex !important;
    align-items: center;
    justify-content: flex-end;       /* user actions cluster on the right */
    gap: 16px;
    box-sizing: border-box;
}

/* Flatten the legacy `max-w-7xl mx-auto px-…` wrapper. */
.oppo-topbar > div {
    max-width: none;
    margin: 0;
    padding: 0;
    width: 100%;
    height: 100%;
}

.oppo-topbar > div > div {
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 16px;
}

/* Hide the legacy Pulse logo in the topbar (it's already in the sidebar). */
.oppo-topbar #nav-logo,
.oppo-topbar #nav-logo + * { display: none; }
.oppo-topbar > div > div > div:first-child { display: none; }

/* Hide the theme toggle — Oppo is dark-only per Figma. */
.oppo-topbar [onclick="toggleTheme()"] { display: none; }

/* Avatar styling — keep the legacy gradient avatar but make sure it sits
 * cleanly in the bar. */
.oppo-topbar #user-avatar-btn {
    color: #FFFFFF;
}

.oppo-topbar-left {
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 0;
}

.oppo-topbar-right {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-shrink: 0;
}

/* The page content slot. Existing pages still mount into #content-area
 * (kept inside this slot) so per-page work in subsequent PRs is local. */
.oppo-body {
    flex: 1;
    padding: 32px;
    color: var(--text-main);
}

/* Hide the legacy horizontal tab strip; switchTab() keeps toggling the
 * .tab-btn IDs underneath, our sidebar mirrors the active state.
 * NOTE: Do NOT hide `.legacy-top-nav` — that element is *also* tagged
 * `.oppo-topbar` and IS the Figma topbar (avatar + frosted bar). The
 * `.legacy-top-nav` class is just a hook for cleaning up legacy Tailwind. */
.oppo-shell .legacy-tab-strip,
.oppo-shell #tab-strip-wrapper {
    display: none !important;
}

/* The legacy `#content-area` carries Tailwind `bg-[var(--bg-body)]` which
 * resolves to a solid `#080323` inside the shell — blocking the canvas
 * glow on `.oppo-main`. Make it (and its inner `<main>`) transparent so
 * the radial gradients show through to the page content. The cards use
 * `rgba(255,255,255,0.05)` over the canvas, so seeing the colour wash
 * underneath is part of the Figma look. */
.oppo-shell #content-area,
.oppo-shell main {
    background: transparent !important;
}

/* Flatten the legacy `<main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8 h-full">`
 * wrapper so `.oppo-main` flow controls page width edge-to-edge. Each Oppo
 * page can then apply its own Figma-faithful inset (e.g. oppo-reports.css
 * caps content at 1328 px with 32 px gutters). */
.oppo-shell .oppo-main > main {
    max-width: none !important;
    width: 100% !important;
    margin: 0 !important;
    padding: 24px 32px !important;
    height: auto !important;
}

/* Per Figma 160:2756 the wizard is its own full-screen page — the 240-px left
 * sidebar (the global Reports/Opportunities/Campaigns navigation) is hidden
 * and the .oppo-shell grid collapses to a single column so the wizard content
 * centers in the full viewport width. Topbar stays visible (avatar etc.).
 * The legacy tab strip is hidden by the global `.legacy-tab-strip` hide-rule. */
.oppo-shell:has(#content-area.oppo-wizard-host) {
    grid-template-columns: 1fr;
}
.oppo-shell:has(#content-area.oppo-wizard-host) .oppo-sidebar {
    display: none !important;
}

/* ── Confirm dialog (`showConfirmCard` in app.js) ───────────────────── */
/* Implements the design-system.md §5.1 Card recipe inside a centered
 * modal scrim. Used app-wide for destructive confirmations (delete
 * report, delete campaign, withdraw claim …). Header / body / footer
 * are 16-px padded sections separated by Blue-100 hairlines. The
 * footer reuses .ds-btn / .ds-btn--ghost / .ds-btn--destructive from
 * admin.css so all buttons are 36 h, 4 px radius, with --shadow-xs. */
.ds-confirm-backdrop {
    position: fixed;
    inset: 0;
    z-index: 70;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-4);
    background: var(--bg-modal-backdrop);       /* rgba(8,3,35,0.8) */
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
}
.ds-confirm-card {
    width: 100%;
    max-width: 420px;
    background: rgba(255, 255, 255, 0.05);      /* §5.1 — canonical card surface */
    backdrop-filter: blur(15px);                /* §5.2 — same blur as KPI tile */
    -webkit-backdrop-filter: blur(15px);
    border: 1px solid var(--base-blue-100);     /* #1C3D5E */
    border-radius: var(--radius-lg);            /* 8 px */
    box-shadow: var(--shadow-xs);
    overflow: hidden;
    color: var(--base-grey-20);
}
.ds-confirm-header {
    padding: var(--space-4);                    /* 16 px */
    border-bottom: 1px solid var(--base-blue-100);
}
.ds-confirm-title {
    margin: 0;
    font: var(--type-h2);                       /* 600 18/28 — modal title sits between page H1 and card H3 */
    color: var(--base-grey-20);                 /* #F3F4F6 — explicit brightest grey, the translucent card surface eats contrast otherwise */
}
.ds-confirm-body {
    padding: var(--space-4);
    font: var(--type-body-l);                   /* 500 14/24 — long-form copy */
    color: var(--base-grey-20);                 /* Match title — Grey 40 reads as faint on this backdrop */
}
.ds-confirm-footer {
    padding: var(--space-3) var(--space-4);     /* 12/16 — tighter than body so buttons sit close to the divider */
    border-top: 1px solid var(--base-blue-100);
    display: flex;
    justify-content: flex-end;
    gap: var(--space-2);                        /* 8 px between Cancel and Confirm */
}

/* ── Pending pill (claim contact state) ───────────────────────────────── */
/* Per Figma node 150:964 — a Solid Badge with grey tinted chrome and
 * white text. Reused by Metrics (app.js renderReports) and Reports
 * (oppo-reports.js claimCellHtml) tab company lists. */
.ds-pending-pill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    padding: 2px 8px;
    background: rgba(196, 196, 196, 0.3);
    border: 1px solid #c4c4c4;          /* --base-grey-40 */
    border-radius: 4px;
    color: #FFFFFF;
    font-family: var(--oppo-font-family, 'Montserrat', sans-serif);
    font-weight: 500;
    font-size: 12px;
    line-height: 16px;
}
.ds-pending-pill__cancel {
    margin-left: 2px;
    background: none;
    border: 0;
    padding: 0;
    color: inherit;
    cursor: pointer;
    line-height: 1;
    transition: color .15s;
}
.ds-pending-pill__cancel:hover { color: #F58484; }  /* --base-red-50 */
