/**
 * PistonTribe — ACTION BOARD
 *
 * Shared styling for the one-click decision-queue pattern (Review Hub was the first build; Offers
 * is the second). Anything else built on the pattern should use these classes rather than copying
 * them under a new prefix — that is how the two review surfaces drifted apart.
 *
 * PT design rules apply throughout: hairline #eee borders, 12px radius, NO shadows, no lift on
 * hover, active filter = grey fill + black border (never a black fill — that is a primary-action
 * colour and it outshouts the real buttons on the card).
 */

.pt-ab-wrap { max-width: 960px; margin: 0 auto; }

/* Head: title + the single contextual report link the pattern allows. */
.pt-ab-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 18px;
}
.pt-ab-title { margin: 0 0 6px; font-size: 1.35rem; font-weight: 800; color: #0a0a0a; }
.pt-ab-sub   { margin: 0; font-size: 0.85rem; line-height: 1.6; color: #6b7280; max-width: 60ch; }

.pt-ab-analytics {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 10px 16px;
    border-radius: 30px;
    background: #16a34a;
    color: #fff;
    font-weight: 700;
    font-size: 0.85rem;
    text-decoration: none;
    white-space: nowrap;
    transition: background 0.2s;
}
.pt-ab-analytics:hover, .pt-ab-analytics:focus { background: #15803d; color: #fff; }

/* Stat cards = the filters. */
.pt-ab-stats { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 20px; }
.pt-ab-stat {
    flex: 1 1 130px;
    border: 1px solid #eee;
    border-radius: 12px;
    padding: 14px 16px;
    background: #fff;
    text-decoration: none;
    color: inherit;
    display: block;
}
.pt-ab-stat:hover { color: inherit; }
.pt-ab-stat--due  { border-color: #0a0a0a; }
.pt-ab-stat.is-active { background: #f3f4f6; border-color: #0a0a0a; }
.pt-ab-stat-value {
    display: block;
    font-size: 1.5rem;
    font-weight: 800;
    color: #0a0a0a;
    line-height: 1.1;
}
.pt-ab-stat-label {
    display: block;
    margin-top: 2px;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: #6b7280;
}

/* The stack. */
.pt-ab-list { display: flex; flex-direction: column; gap: 12px; }
.pt-ab-list[hidden] { display: none !important; }

.pt-ab-card {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    border: 1px solid #eee;
    border-radius: 12px;
    padding: 14px 16px;
    background: #fff;
}
.pt-ab-card.is-done { background: #f0fdf4; border-color: #bbf7d0; }

.pt-ab-thumb {
    flex: 0 0 64px;
    width: 64px; height: 64px;
    border-radius: 8px;
    background: #f3f4f6 center/cover no-repeat;
}

.pt-ab-body { flex: 1 1 220px; min-width: 0; }
.pt-ab-item {
    display: block;
    font-size: 0.92rem;
    font-weight: 700;
    color: #0a0a0a;
    text-decoration: none;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pt-ab-item:hover { text-decoration: underline; color: #0a0a0a; }
.pt-ab-meta {
    display: flex; gap: 5px; flex-wrap: wrap;
    margin-top: 3px;
    font-size: 0.74rem;
    color: #6b7280;
}
.pt-ab-role { font-weight: 600; color: #374151; }
.pt-ab-expiry.is-gone { color: #b91c1c; }

.pt-ab-price {
    flex: 0 0 auto;
    font-size: 1.05rem;
    font-weight: 800;
    color: #0a0a0a;
    font-variant-numeric: tabular-nums;
}

.pt-ab-actions { flex: 0 0 auto; display: flex; gap: 8px; flex-wrap: wrap; }

.pt-ab-btn {
    display: inline-block;
    border: 0;
    border-radius: 8px;
    padding: 9px 16px;
    font-size: 0.8rem;
    font-weight: 700;
    text-decoration: none;
    text-align: center;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.15s ease;
}
.pt-ab-btn[disabled] { opacity: 0.5; cursor: default; }

/* Accept carries the weight; decline stays quiet. Neither is red — declining an offer is a normal
   outcome, not a failure, and red is reserved for genuine failure states. */
.pt-ab-btn--accept  { background: #0a0a0a; color: #fff; }
.pt-ab-btn--accept:hover, .pt-ab-btn--accept:focus { background: #1f1f1f; color: #fff; }
.pt-ab-btn--decline { background: #f3f4f6; color: #374151; }
.pt-ab-btn--decline:hover, .pt-ab-btn--decline:focus { background: #e5e7eb; color: #374151; }
.pt-ab-btn--ghost   { background: transparent; color: #0a0a0a; border: 1px solid #d1d5db; }
.pt-ab-btn--ghost:hover, .pt-ab-btn--ghost:focus { background: #f3f4f6; color: #0a0a0a; }

.pt-ab-waiting { font-size: 0.76rem; color: #9ca3af; align-self: center; }

.pt-ab-msg {
    flex: 1 1 100%;
    font-size: 0.74rem;
    color: #6b7280;
    min-height: 0;
}
.pt-ab-msg.is-error { color: #b91c1c; min-height: 1em; }

.pt-ab-done { display: flex; align-items: center; gap: 10px; font-size: 0.85rem; color: #166534; line-height: 1.5; }
.pt-ab-done-tick {
    flex: 0 0 auto;
    width: 24px; height: 24px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 50%;
    background: #dcfce7;
    color: #15803d;
    font-weight: 800;
}

.pt-ab-empty {
    border: 1px solid #eee;
    border-radius: 12px;
    padding: 28px 22px;
    text-align: center;
    color: #6b7280;
    font-size: 0.85rem;
    line-height: 1.6;
}
.pt-ab-empty strong { color: #0a0a0a; display: block; margin-bottom: 4px; }
.pt-ab-empty p { margin: 0; }

/* Account content runs edge-to-edge on small screens. */
@media (max-width: 1024px) { .pt-ab-wrap { padding-left: 24px; padding-right: 24px; } }
@media (max-width: 768px) {
    .pt-ab-wrap { padding-left: 16px; padding-right: 16px; }
    .pt-ab-actions { width: 100%; }
    .pt-ab-actions .pt-ab-btn { flex: 1; }
}


/* =============================================================================================
   TOOLS ROW — search · Filter · sort dropdowns
   Moved here from the offers-hub <style> block on 2026-08-23. It rendered completely unstyled on
   /account/offers/?listing_id=… because that page emits its own <style> and never the hub's.
   Anything shared by more than one screen belongs in this file, not in a per-screen block.
   ============================================================================================= */

/* ── TOOLS ROW — search · filter · sorts  (2026-08-23) ──────────────────────────────────────
   Leon: *"under pt-ab-cards insert a search bar and on the right to the search bar in same row, I
   want a filter button... remove the sort buttons from the filter and set them as buttons to the
   right of the filter button as dropdowns."*

   Sort was buried two levels down — inside a popover, below the filters — which made the most
   common reordering (oldest first) a three-click job behind a control labelled "Filter". Sorting
   is not filtering, and hiding one inside the other taught the wrong model. Now the row states
   all three jobs at once: FIND (search), NARROW (filter), ORDER (sorts). */
.pt-ab-tools { margin: 0 0 10px; }
/* ⚠️ `.pt-sidebar-toggles` is the state holder and is declared `flex-direction: column` in this
   same stylesheet — the exact rule that stacked the status pills vertically when the pill bar
   shipped. Scoped at (0,2,0) so it wins on specificity rather than on source order, which is the
   only version of this that survives someone appending a rule later. */
.pt-ab-tools .pt-sidebar-toggles {
    display: flex; flex-direction: row; align-items: center;
    flex-wrap: wrap; gap: 8px;
}

.pt-ab-search {
    position: relative;
    flex: 1 1 190px;                    /* takes the room; the buttons keep their natural width */
    min-width: 0;
    display: flex; align-items: center;
}
.pt-ab-search__icon {
    position: absolute; left: 10px; display: flex; color: #9ca3af; pointer-events: none;
}
/* 🎯 GeneratePress styles `input[type="search"]` at (0,1,1) — a bare `.pt-ab-search__input` at
   (0,1,0) LOSES to it ([[reference-css-specificity-theme-override]]). Scoped to the wrapper so
   this is (0,2,0) and wins honestly, with no !important. */
.pt-ab-search .pt-ab-search__input {
    width: 100%; min-width: 0;
    padding: 8px 30px 8px 32px;
    border: 1px solid #e4e6ea; border-radius: 8px;
    background: #fff; color: #0a0a0a;
    font-size: .82rem; font-weight: 500; line-height: 1.4;
    box-shadow: none; margin: 0;
    transition: border-color .13s, background .13s;
}
.pt-ab-search .pt-ab-search__input::placeholder { color: #9ca3af; font-weight: 500; }
.pt-ab-search .pt-ab-search__input:focus {
    border-color: #b9bdc6; background: #fff; outline: none; box-shadow: none;
}
/* Kill WebKit's own clear button — it lands on top of ours and the two look like a bug. */
.pt-ab-search .pt-ab-search__input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
.pt-ab-search__clear {
    position: absolute; right: 6px;
    display: none; align-items: center; justify-content: center;
    width: 20px; height: 20px; border: 0; border-radius: 50%;
    background: #eef0f3; color: #6b7280;
    font-size: .8rem; line-height: 1; cursor: pointer; padding: 0;
    transition: background .13s, color .13s;
}
.pt-ab-search.has-text .pt-ab-search__clear { display: inline-flex; }
.pt-ab-search__clear:hover, .pt-ab-search__clear:focus,
.pt-ab-search__clear:active { background: #e2e5ea; color: #4b5563; outline: none; }

/* Sort dropdowns reuse the PT standard filter button and its popover wholesale
   ([[feedback-pt-header-filter-button]]) — same shell, same open/close listener, so there is one
   control language in this row rather than two that merely look alike. */
/* 🔴 `relative`, NOT `static`. The component's default is `position: absolute` (it used to be
   pinned inside the accordion head). Here it is a normal flex child — but `.pt-gf__pop` is
   `position: absolute; top: 34px; right: 0`, so the wrapper MUST stay a positioning context or
   the popover anchors to whatever ancestor happens to be positioned and opens somewhere else on
   the page entirely. */
/* z-index on the WRAPPER, not just the popover. `position: relative` + a z-index here makes each
   control its own stacking context, and the popover inside then rides on whatever this wins against
   the list below — the same trap the card tooltip fell into earlier today, where raising the child's
   z-index did nothing because the child only ever competed with its own siblings. */
.pt-ab-tools .pt-gf { position: relative; top: auto; right: auto; flex: 0 0 auto; z-index: 300; }
.pt-ab-tools .pt-gf[data-pt-gf]:has([data-pt-gf-pop]:not([hidden])) { z-index: 600; }
/* The open popover must clear the card list, the row separators and any sticky header above it. */
.pt-ab-tools .pt-gf__pop { z-index: 620; }
.pt-ab-sortstate { display: none; }
.pt-ab-empty { padding: 22px 16px; text-align: center; color: #6b7280; font-size: .82rem; }

@media (max-width: 480px) {
    /* The search keeps the first row to itself and the three controls share the second. Squeezing
       an input and three buttons onto one 390px row leaves a search field too narrow to read what
       you typed into it. */
    .pt-ab-search { flex: 1 0 100%; }
}


/* =============================================================================================
   PT STANDARD FILTER BUTTON + POPOVER (`.pt-gf`) and its toggle rows
   Moved out of the offers-hub <style> block on 2026-08-23. The same component renders on the
   per-listing page, which emits its own <style> — so there the button was an unstyled black
   rectangle. A shared component belongs in the stylesheet.
   ⚠️ `.pt-gf` defaults to `position: absolute` for the action-board headings it was born in; both
   the tools row and the L2 header reset it. Keep those resets if you touch this.
   ============================================================================================= */

.pt-gf { position: absolute; top: 9px; right: 46px; z-index: 60; }
/* ⭐ PT STANDARD — FILTER BUTTON IN A HEADER (adopted 2026-08-23, Leon: *"save the design as PT
   standard filter buttons in header design as I love it"*).
   Rest: light grey pill, grey text — present but subordinate to the heading it sits beside.
   Hover/open: fills dark with white text, so the control you are using is unmistakable.
   Reuse this class anywhere a header needs a filter; do not invent a second one. */
.pt-gf__btn {
    display: inline-flex; align-items: center; gap: 6px;
    height: 30px; padding: 0 13px;
    background: #f2f2f4; border: 1px solid transparent; border-radius: 999px;
    color: #4b5563; font-size: .74rem; font-weight: 700; font-family: inherit;
    cursor: pointer; white-space: nowrap;
    transition: color .13s, background .13s, border-color .13s, box-shadow .13s;
}
/* 🖤 DIM ON HOVER — NEVER RECOLOUR (Leon 2026-08-23, now a company-wide rule).
   The first cut flipped grey → near-black with white text, which reads as a different button
   rather than the same button being touched. A control should acknowledge the cursor, not
   change identity. Same principle as [[feedback-button-hover-noir]], generalised: whatever the
   resting colour, hover and active DIM it. */
.pt-gf__btn:hover              { background: #e6e7ea; color: #374151; }
.pt-gf__btn[aria-expanded="true"] { background: #dfe1e5; color: #1f2328; }
.pt-gf__btn:active             { background: #d9dbe0; }
.pt-gf__btn:focus-visible { outline: 2px solid #111; outline-offset: 2px; }

/* NOTE: the controls were briefly inverted to white here, back when the open heading was the
   darker #f2f3f5 and they vanished into it. With the heading now at #fafbfc the default grey
   controls contrast again, so the override is gone — white on near-white would have reproduced
   the original problem in the opposite direction. One rule, both states. */
.pt-gf__pop {
    position: absolute; top: 34px; right: 0; z-index: 20;
    min-width: 226px; padding: 12px 13px; z-index: 61;
    background: #fff; border: 1px solid #e6e6e9; border-radius: 11px;
    box-shadow: 0 8px 24px rgba(15,23,42,.12);
}
.pt-gf__pop[hidden] { display: none; }
.pt-gf__label {
    font-size: .62rem; font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
    color: #9ca3af; margin: 2px 0 7px;
}
.pt-gf__n {
    display: inline-block; margin-left: 6px; padding: 0 6px;
    background: #f0f1f3; color: #6b7280; border-radius: 999px;
    font-size: .64rem; font-weight: 800;
}
.pt-gf__label + .pt-gf__label,
.pt-sidebar-toggle-row + .pt-gf__label { margin-top: 12px; }
/* The popover reuses the sidebar's rows, which were built for a 220px column — that is exactly
   the width here, so they need no changes beyond sitting on a white surface. */
.pt-gf__pop .pt-sidebar-toggles { display: flex; flex-direction: column; gap: 0; }

.pt-sidebar-toggle-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 7px 0;
    cursor: pointer;
    gap: 8px;
}
.pt-sidebar-toggle-label {
    font-size: 0.78rem;
    font-weight: 500;
    color: #444;
    flex: 1;
    line-height: 1.3;
}
.pt-sidebar-switch { position: relative; flex-shrink: 0; width: 36px; height: 20px; }
.pt-sidebar-switch input { display: none; }
.pt-sidebar-slider {
    position: absolute;
    inset: 0;
    background: #ddd;
    border-radius: 20px;
    transition: background 0.2s;
}
.pt-sidebar-slider::before {
    content: '';
    position: absolute;
    width: 14px;
    height: 14px;
    left: 3px;
    top: 3px;
    background: #fff;
    border-radius: 50%;
    transition: transform 0.2s;
    box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}
.pt-sidebar-switch input:checked + .pt-sidebar-slider { background: #d00; }
.pt-sidebar-switch input:checked + .pt-sidebar-slider::before { transform: translateX(16px); }


/* =============================================================================================
   FLOATING PANELS — the shared tooltip node, and the popover in fixed mode      (2026-08-24)
   Positioned by `place()` in action-board.js. Everything here is APPEARANCE only — no `left`,
   `right` or `top` offsets, because a static offset is exactly what was truncating these.
   ============================================================================================= */

/* The one tooltip node, appended to <body> so no ancestor's overflow or stacking context reaches it. */
.pt-float-tip {
    position: fixed;
    z-index: 9999;                       /* above every panel, header and popover on the site */
    max-width: 320px;
    padding: 9px 11px;
    background: #1f2328;
    color: #fff;
    border-radius: 8px;
    font-size: .72rem;
    font-weight: 500;
    line-height: 1.45;
    letter-spacing: 0;
    text-align: left;
    text-transform: none;
    white-space: normal;
    box-shadow: 0 8px 24px rgba(15, 23, 42, .22);
    pointer-events: none;                /* never steals the click that is closing it */
}
.pt-float-tip[hidden] { display: none; }

/* 🔴 The CSS-only `::after` bubble stands down once the JS is live — otherwise BOTH render and the
   old one is the one that gets clipped. It is deliberately left in place for the no-JS case: a
   tooltip that is sometimes cut off still beats no explanation at all. */
.pt-float-ready .pt-ab-card__tip::after { content: none !important; display: none !important; }

/* While a popover is being positioned it is `position: fixed` (set inline by the placer), so the
   component's own `top`/`right` must not fight it. Cleared only in that state. */
.pt-gf__pop[style*="position: fixed"],
.pt-gf__pop[data-pt-flip] { top: auto; right: auto; z-index: 9998; }


/* =============================================================================================
   SORT TOGGLES — one tap, states its own answer                                  (2026-08-24)
   Leon: *"just a switch button, so click once and change sort asc, click again desc."*
   Replaced two-item popovers: three interactions to express one bit of information, and the list's
   current order was hidden until you opened something. Built on the same pill as `.pt-gf__btn` so
   the row reads as one set of controls, not a filter plus two strangers.
   ============================================================================================= */
.pt-sorttog {
    display: inline-flex; align-items: center; gap: 5px;
    flex: 0 0 auto;
    padding: 7px 11px;
    border: 0; border-radius: 999px;
    background: #eef0f3; color: #6b7280;
    font: inherit; font-size: .78rem; font-weight: 700; line-height: 1.2;
    cursor: pointer; white-space: nowrap; box-shadow: none;
    transition: background .13s, color .13s;
}
/* The axis in force reads dark and states its direction; the others state only their name in grey.
   That difference IS the "which way is this list sorted" answer, visible without opening anything. */
.pt-sorttog.is-on   { background: #dfe1e5; color: #1f2328; }
.pt-sorttog.is-idle { background: #eef0f3; color: #9ca3af; }
/* Dim on hover, never recolour — the company rule, whatever the resting colour. */
.pt-sorttog:hover, .pt-sorttog:focus, .pt-sorttog:active {
    background: #e6e7ea; color: #374151; outline: none; box-shadow: none;
}
.pt-sorttog.is-on:hover, .pt-sorttog.is-on:focus, .pt-sorttog.is-on:active {
    background: #d9dbe0; color: #1f2328;
}
.pt-sorttog:focus-visible { outline: 2px solid #111; outline-offset: 2px; }
/* The arrow is the direction, so it only means anything on the active axis. */
.pt-sorttog__dir { font-size: .72rem; opacity: .85; }
.pt-sorttog.is-idle .pt-sorttog__dir { display: none; }
