/*
 * app-overrides.css — INTENTIONAL, user-requested deviations from the
 * verbatim live app.
 *
 * Everything else in this app is a faithful 1:1 port (shell.css /
 * tools-base.css / aplusModules.css / gates.css are extracted VERBATIM and
 * must stay byte-faithful so they can be re-extracted losslessly). This file
 * is the ONE place deliberate behaviour/UX changes live, loaded AFTER
 * shell.css so it wins by cascade order (no !important needed). Same
 * separation discipline as harden-inputs.js: an additive override layer, not
 * a patch to the verbatim source. Each rule below cites why it deviates.
 */

/* ── Marketplace dropdown: open on HOVER (deviation from live app) ─────────
 * Live app: the grouped nav menus open on hover
 *   (.topnav-group:hover .topnav-dropdown { display:block })
 * but the marketplace picker opens only on CLICK
 *   (.topnav-mkt-dd.open .topnav-mkt-menu).
 * User asked twice for the marketplace to open on hover "like all the other
 * menu items" for consistency. Mirror the grouped-menu hover behaviour here.
 * The verbatim click handler (topnavMktToggle → .open) is untouched and still
 * works as a fallback / for touch; this just adds the hover affordance.
 */
.topnav-mkt-dd:hover .topnav-mkt-menu,
.topnav-mkt-dd:focus-within .topnav-mkt-menu {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

/* ── Marketplace dropdown: selected row gets a tinted background ──────────
 * shell.css base only swaps text colour on `.active` (blue + bold), with no
 * background tint — when the menu is open the currently-selected market
 * (e.g. US in the screenshot) looks like every other unhovered row apart
 * from being blue. User wants the active row to read as "the one that's
 * picked" the same way a hovered row does. Mirror the hover background so
 * the active row looks like a hovered row at rest.
 *
 * NOTE: the existing hover rule in shell.css uses `background:var(--b0)`
 * — but `--b0` is NOT defined as a token (shell.css L449 supplies an inline
 * fallback `,rgba(255,255,255,0.06)`). Using `var(--b0)` alone here would
 * silently no-op. Use `--bg-h` (the defined hover token, both themes).
 */
.topnav-mkt-menu-item.active {
  background: var(--bg-h) !important;
}
.topnav-mkt-menu-item.active:hover {
  background: var(--bg-e) !important;
  color: var(--blue);
}
/* Hover on NON-active rows: shell.css L467 declares
 *   .topnav-mkt-menu-item:hover { background:var(--b0); }
 * with NO fallback. `--b0` is not a defined token (same trap as the
 * `.active` fix above), so the property resolves invalid and is dropped —
 * hovering AU/UK/etc. in the open menu shows zero highlight. User feedback
 * (2026-05-22): "if i hover over AU it does not highlight it. only if i
 * click AU in marketplace". Same fix: route to the defined `--bg-h` token
 * so hover actually paints. Scoped `:not(.active)` so the .active row's
 * stronger `--bg-e` hover (above) still wins by specificity logic
 * (.active:hover has more class weight). */
.topnav-mkt-menu-item:not(.active):hover {
  background: var(--bg-h) !important;
  color: var(--t1);
}

/* ── Keyword Explorer drilldown (KDE) — port KWE grid approach to <table> ─
 * User direction (2026-05-20): "go check how KWE table does it and copy it."
 * The KWE outer table (keyword-research.css L735) uses CSS-grid with an
 * explicit per-column track list:
 *   grid-template-columns:
 *     minmax(200px,280px) 48px 80px 64px 96px 72px 84px 64px 84px 80px
 *     74px 72px 72px 160px 104px 92px 136px;
 * — every column gets a fixed pixel width, so headers can never collapse
 * under cell content, never clip, never overlap.
 *
 * The KDE drilldown is a `<table>` so we can't use grid, but the equivalent
 * is `table-layout: fixed` + explicit `width:` per column (NOT min-width —
 * fixed-layout ignores content size entirely and uses the first row's
 * declared widths). Pair with the KWE width values per column where they
 * map (format=96px from KWE, bsr=80px, etc.) and pad the cell so the SVG
 * icon centers cleanly in the wider column.
 *
 * Use attribute selector on `onclick="kdeToggleSort('<key>')"` — the only
 * stable per-column marker on a `kde-sortable` th, mirroring the
 * `.kwe-col-<key>` class targeting KWE uses on its grid cells.
 */

/* Approach: leave the verbatim sticky leading cells alone (chk/rank/cover/
 * title — their widths + left offsets in keyword-research.css L1377-1388
 * already work and we MUST NOT change the freeze-pane geometry). Just give
 * each DYNAMIC `<th>` a sensible min-width so FORMAT (and friends) can no
 * longer collapse to the 13px icon width of their TDs.
 *
 * Using min-width (not width) in auto-layout: the column is still allowed
 * to grow with wider content (long category names) but can never shrink
 * below the declared floor. Pair with `padding-left: 12px` on the FIRST
 * non-sticky column (FORMAT) so its label isn't covered by the sticky
 * Title's right-edge `box-shadow: 1px 0 0 var(--b1)` (L1384). */
/* Per-key min-widths so each column has a sensible floor regardless of
 * position (reordering via the Columns picker shuffles render order, so
 * we MUST NOT bind sizing to a positional :nth-child — the column's
 * identity stays the same, only its column-index changes). Sticky cover/
 * title widths come from verbatim keyword-research.css L1377-1388 (those
 * positional `left:` offsets only apply to the 4 LEADING sticky cells,
 * which the picker can't reorder). */
.kde-table thead th.kde-sortable[onclick*="format"]   { min-width: 64px; }
.kde-table thead th.kde-sortable[onclick*="bsr"]      { min-width: 80px; }
.kde-table thead th.kde-sortable[onclick*="salesD"]   { min-width: 76px; }
.kde-table thead th.kde-sortable[onclick*="royD"]     { min-width: 72px; }
.kde-table thead th.kde-sortable[onclick*="royalty"]  { min-width: 80px; }
.kde-table thead th.kde-sortable[onclick*="price"]    { min-width: 64px; }
.kde-table thead th.kde-sortable[onclick*="reviews"]  { min-width: 80px; }
.kde-table thead th.kde-sortable[onclick*="rating"]   { min-width: 70px; }
.kde-table thead th.kde-sortable[onclick*="age"]      { min-width: 56px; }
.kde-table thead th.kde-sortable[onclick*="pages"]    { min-width: 64px; }
.kde-table thead th.kde-sortable[onclick*="pub"]      { min-width: 80px; }
.kde-table thead th.kde-sortable[onclick*="category"] { min-width: 160px; }

/* ── Sticky-Title clearance (POSITIONAL, reorder-safe) ─────────────────────
 * The sticky Title TH/TD (verbatim left:172px + width:280px + right-edge
 * box-shadow 1px 0 0 var(--b1)) visually pins x=172..452 in the scroll
 * container regardless of scroll. The natural auto-layout position of the
 * FIRST non-sticky column is ~chk(36)+rank(~64)+cover(~40)+title(280) =
 * ~420 from left, so the sticky Title's right edge overlaps ~32px into
 * whatever column is currently at index 5. Previous fix bound the padding
 * to `[onclick*="format"]` — but the Columns picker reorders the dynamic
 * THs, so when the user drags BSR (or any other column) to position 5,
 * that new column had no clearance and the sticky Title painted over its
 * header label.
 *
 * Fix: target the 5th `<th>` / `<td>` positionally — that's always the
 * first dynamic (non-sticky-leading) cell, whatever its key currently is.
 * Match TH min-width to header padding (36+8 floor = ~44px label space)
 * so the column never collapses below the padded zone. */
.kde-table thead tr > th:nth-child(5),
.kde-table tbody tr > td:nth-child(5) {
  padding-left: 36px;
}
.kde-table thead tr > th:nth-child(5) {
  /* Override any per-key min-width to guarantee the padded zone fits any
   * column label (longest dynamic label is "ROYALTY" ~50px + 36+8 = 94). */
  min-width: 100px;
}

/* ── Global ASIN click-to-copy affordance ───────────────────────────────────
 * User asked (2026-05-20): "anywhere ASIN is displayed on the web page if
 * its not part of a search input it should able to be copied when user
 * clicks on it". The behaviour is implemented in src/lib/globalAsinCopy.js
 * (delegated doc click handler). This CSS just makes ASIN-bearing elements
 * (any element with data-asin OR matching the ASIN regex caught at runtime)
 * visually clickable. The runtime adds `.ps-asin-copyable` to qualifying
 * text nodes' parents.
 */
/* Affordance: cursor + tiny color hint on hover. NO background overlay, NO
 * box, NO padding/border — user explicitly rejected "green box overlays" and
 * asked for "just the text Copied flash". The runtime swaps the element's
 * textContent to "Copied" for ~1200ms (see globalAsinCopy.js flashCopied) and
 * adds `.ps-asin-copied-text` purely as a color hook during the flash. */
.ps-asin-copyable {
  cursor: pointer;
  transition: color 0.12s;
}
.ps-asin-copyable:hover {
  color: var(--blue, #3b82f6);
}
/* Standalone selector (no `.ps-asin-copyable` compound) so ANY node tagged by
 * flashCopied — including nodes the runtime tagger never tagged (e.g. nested
 * children inside ASIN-bearing spans that the new ancestor-walk in
 * findAsinFromTarget now resolves) — goes green during the flash. !important
 * needed because per-tool inline `onclick` handlers sometimes write
 * `el.style.color = 'var(--mint)'` (see serp-intelligence L506, asin-keywords
 * L1317) and inline style would otherwise beat the class rule. */
.ps-asin-copied-text {
  color: var(--green, #22c55e) !important;
}

/* ── AI Description "Improve" box padding ───────────────────────────────────
 * Verbatim _ported/ai-description.css L276 declares:
 *   .ad-improve-box { margin-top:14px; padding-top:14px; border-top:1px solid var(--b1); display:none; }
 * No horizontal or bottom padding, so when the user clicks "Improve" the
 * textarea + ↺ Regenerate row stretch to the very left/right/bottom edges of
 * the variant card and look unframed against the card border. Live-page bug
 * too (byte-faithful port) — user-confirmed UX deviation. Mirror the card's
 * existing .ad-variant-actions horizontal padding (20px) and add bottom
 * breathing room so the action row doesn't kiss the card border. */
.ad-improve-box {
  padding: 14px 20px 16px 20px;
}

/* ── Authority Audit loading skeleton: unify with A+ Builder ────────────────
 * User screenshot diff (2026-05-21): A+ Builder's shimmer cards stack flush
 * (`.ap-module` has no margin-bottom — cards sit edge-to-edge), but Authority
 * Suite's namespaced `.as-ap-module` ([_ported/authority-suite.css:388]) has
 * `margin-bottom: 14px`, so its 5 loading cards show a visible gap between
 * each card while A+ Builder's don't. User wants both consistent: A+ is the
 * reference. The audit-results live cards (.ps-field-card) are unaffected —
 * only `.as-ap-module` (the skeleton-card variant) is overridden here. */
.as-ap-module {
  margin-bottom: 0;
}

/* ── AI Description form card: drop the panel shadow ──────────────────────
 * Verbatim _ported/ai-description.css:30 declares:
 *   .ad-form-card { ... box-shadow: var(--sh-panel); ... }
 * Every other form-card across the Optimise / Authority menus (Listing
 * Optimiser, Listing Builder, A+ Builder, Authority Suite, Deep SEO) has
 * NO panel shadow — they read as flat bordered cards. AI Description is the
 * only outlier with an elevation shadow, so it looks slightly "floating"
 * next to its peers. User flagged the inconsistency directly. Strip the
 * shadow only — keep border + radius + background so the card identity is
 * preserved; only the elevation cue goes away. */
.ad-form-card {
  box-shadow: none !important;
}

/* ── Window scroll: let body grow past viewport so window scrollbar appears ──
 * shell.css L225 sets `html, body { height: 100% }` which CAPS body at the
 * viewport height. Combined with `body { overflow-x: hidden }` (L226) the
 * window can never produce a vertical scrollbar — when a page's content
 * exceeds viewport, the user has no way to reach the cut-off content.
 *
 * Fix: drop the explicit `height` (removes the cap so body grows with
 * content) and keep `min-height` so body still fills viewport when content
 * is shorter. `html` needs `min-height: 100%` so it stretches to body's
 * computed height, which establishes the scrollable root for the window.
 * `body { min-height: 100vh }` ensures full-viewport when content is short.
 *
 * `!important` because shell.css L225 is loaded into the same cascade and
 * its `height: 100%` is a hard cap that defeats our min-height otherwise. */
html {
  height: auto !important;
  min-height: 100% !important;
}
body {
  height: auto !important;
  min-height: 100vh !important;
  /* shell.css L226 declares `body { overflow-x: hidden }`. With overflow-y
   * left at default (`visible`), the asymmetric pair forces the browser to
   * establish a SEPARATE scrolling context on body (CSS spec promotes
   * `overflow-y: visible` to `auto` when paired with non-visible/non-clip
   * `overflow-x`). Swap to `overflow-x: clip` — clips visually without
   * establishing a scrolling context, so vertical scroll consolidates back
   * at the html/viewport level.
   *
   * `overflow: clip` is supported in Chrome 90+ / Firefox 81+ / Safari 16+
   * (universal at this point). */
  overflow-x: clip !important;
}

/* ── .admin-main: stop it establishing its own vertical scroll context ────
 * shell.css L501 sets `height: calc(100vh - 48px)` (fixed) and L503 sets
 * `overflow-x: hidden`. Together with default `overflow-y: visible`, the
 * CSS spec's asymmetric-overflow rule promotes overflow-y to `auto` — so
 * `.admin-main` becomes a fixed-height scrollable region with its OWN
 * vertical scrollbar. Combined with the body-grow fix above (which gives
 * tall pages a window scrollbar), the user sees TWO vertical scrollbars
 * side-by-side at the right edge of the viewport on My Books, A+ Builder,
 * and any other tall page.
 *
 * Fix for normal pages: drop the explicit height so admin-main grows with
 * its content (min-height keeps the viewport-filling baseline) and change
 * overflow-x to `clip` so the asymmetric-pair rule no longer forces a
 * scrolling context. Content overflow extends body → window scrollbar
 * handles vertical → single scrollbar.
 *
 * Carve-out for Category Explorer: CE genuinely depends on admin-main
 * being a fixed-height container so its split-pane layout (left tree,
 * right detail) can position children with their own scroll regions
 * (see [[project-ce-scroll-resize-fix-2026-05-22]] for the original CE
 * geometry fix). When CE is active, restore the original `height` +
 * `overflow-x: hidden` so the asymmetric-overflow rule re-enables
 * admin-main's internal scroll for CE's pane. `:has()` keys off the
 * `ce-active` class CE adds to `#content-area` on mount.
 *
 * `:has()` is supported in Chrome 105+ / Firefox 121+ / Safari 15.4+
 * (universal at this point). */
.admin-main {
  height: auto !important;
  min-height: calc(100vh - 48px) !important;
  overflow-x: clip !important;
}
.admin-main:has(#content-area.ce-active) {
  height: calc(100vh - 48px) !important;
  min-height: 0 !important;
  overflow-x: hidden !important;
}

/* ── My Books role tabs: match the Keyword Research segmented pill ────────
 * User-requested visual consistency. _ported/my-books.css ships its own
 * `.mb-role-tabs` / `.mb-role-tab` chrome (`var(--b1)` track + 1px border +
 * smaller text + smaller radius). The Keyword Research segmented pill at
 * `_ported/keyword-research.css` L7-9 uses the canonical `--seg-track` /
 * `--seg-active-bg` / `--seg-active-text` tokens with `--radius-lg` track
 * + `--radius-md` pills + `--sh-sm` lift on active. Aligning Books to the
 * KR style here without touching the verbatim port.
 *
 * Two locations use `.mb-role-tabs` — the main page-level Mine/Competitor
 * tabs AND the Add-book modal's My Book/Competitor toggle — both get the
 * unified style for free since they share the class name. The verbatim
 * inline `style="display:inline-flex;margin-bottom:14px"` on the modal
 * variant overrides the `inline-flex` track (matches KR's `display: flex`
 * with width:fit-content — same effective shape).
 *
 * The `.count` chip inside each tab stays MB-specific (KR has no count).
 * Active count chip already uses --blue-d/--blue → mint via accent.css. */
.mb-role-tabs {
  display: inline-flex !important;
  gap: 2px !important;
  background: var(--seg-track) !important;
  border: 0 !important;
  border-radius: var(--radius-lg) !important;
  padding: 3px !important;
  width: fit-content !important;
}
.mb-role-tab {
  padding: 7px 20px !important;
  border-radius: var(--radius-md) !important;
  font-size: 0.85rem !important;
  font-weight: 600 !important;
  font-family: var(--fb) !important;
  letter-spacing: normal !important;
  color: var(--t3) !important;
  background: transparent !important;
  transition: all 0.18s !important;
  white-space: nowrap !important;
}
.mb-role-tab:hover {
  color: var(--t1) !important;
}
.mb-role-tab.active {
  background: var(--seg-active-bg) !important;
  color: var(--seg-active-text) !important;
  box-shadow: var(--sh-sm) !important;
}

