/* ══════════════════════════════════════════════════════════════════════
   AIToolsay — Browser Extensions · DETAIL PAGE kit (.cxp-)
   ----------------------------------------------------------------------
   Route-gated: linked only by the /browser-extensions* pages. Loads AFTER
   custom.<dir>.css so it can consume the --aits-* tokens declared there.

   ⚠ SCOPE NARROWED 2026-08-14. This sheet used to dress BOTH public pages.
   The LISTING no longer uses a single `.cxp-` class — it wears the AI
   Directory's own `.dir-*` design, styled by
   assets/css/ext/v2-public-directory-listing.css. What remained here was a
   complete second listing kit (hero, orbit, stat deck, facet rail, toolbar,
   sortbox, card grid, pager) plus the ~610-line "AI-Directory parity layer"
   written to make those `.cxp-` parts LOOK like the directory — all of it
   unreachable, all of it still shipping on every page view.

   Stripped: 192 rules / 203 selectors / 9 @media blocks, 61.5KB → 28.5KB
   (-53.7%). Audited, not guessed: every `.cxp-` class was checked against
   show.blade.php and CxSection::breakpointClasses(), a rule survived if ANY
   of its selectors survived, and the 35 classes the detail page uses were
   confirmed still styled afterwards.

   THIS FILE NOW STYLES ONE PAGE: /browser-extensions/{slug}. Adding a
   listing rule here will do nothing — the listing cannot see `.cxp-`.

   The `cxp-hide-{breakpoint}` classes are NOT dead despite having no blade
   reference: CxSection::breakpointClasses() builds them by concatenation for
   the detail page's Page-Editor bands. A grep for the literal string finds
   nothing; deleting them breaks an admin toggle.

   IMPORTANT dark-mode rule this file follows deliberately:
   custom.*.css declares --aits-blue-dark and several --aits-*-ink values
   ONLY in the light block — they are never redefined under .theme-dark.
   Using them as a text colour on a tinted chip is therefore invisible at
   night. This sheet declares its own --cxp-*-ink set with explicit dark
   twins (the same workaround notifications.css uses) and never reaches for
   --aits-blue-dark as a foreground.
   ══════════════════════════════════════════════════════════════════════ */


.cxp{
    --cxp-brand: var(--aits-blue, #2060C0);
    --cxp-brand-ink: #1B4FA6;
    --cxp-brand-soft: var(--aits-blue-tint, rgba(32, 96, 192, .08));
    --cxp-brand-line: var(--aits-blue-line, rgba(32, 96, 192, .22));
    --cxp-green-ink: #0A7F5C;
    --cxp-amber-ink: #A85D06;
    --cxp-red-ink: #B71C1C;
    --cxp-violet-ink: #4C2FBE;

    /* The SOFT tints are declared locally too, and this is not redundancy.
       --aits-green-soft and friends are OPAQUE near-white hexes (#E6FCF3,
       #FFF5E1, #FFECEC, #EEE6FF) and custom.*.css never redefines them under
       .theme-dark. Pairing one with a light --cxp-*-ink at night therefore
       renders light-on-light: measured at 1.47:1 for the risk chip, i.e.
       invisible. Writing `var(--aits-green-soft, rgba(...))` does NOT save you
       — the token exists, so the transparent fallback never applies. */
    --cxp-green-soft: #E6FCF3;
    --cxp-amber-soft: #FFF5E1;
    --cxp-red-soft: #FFECEC;
    --cxp-violet-soft: #EEE6FF;
    --cxp-red-line: rgba(224, 49, 49, .35);
    --cxp-amber-line: rgba(245, 159, 0, .35);

    --cxp-radius: 14px;
    --cxp-gap: 18px;
}

body.theme-dark .cxp,.theme-dark .cxp{
    --cxp-brand-ink: #8DBEFF;
    --cxp-brand-soft: rgba(54, 128, 237, .16);
    --cxp-brand-line: rgba(54, 128, 237, .30);
    --cxp-green-ink: #6BE3B8;
    --cxp-amber-ink: #F0B44E;
    --cxp-red-ink: #FF8A8A;
    --cxp-violet-ink: #B79DFF;

    /* Transparent tints so they darken with whatever surface they sit on. */
    --cxp-green-soft: rgba(12, 166, 120, .18);
    --cxp-amber-soft: rgba(245, 159, 0, .18);
    --cxp-red-soft: rgba(224, 49, 49, .18);
    --cxp-violet-soft: rgba(112, 72, 232, .22);
    --cxp-red-line: rgba(224, 49, 49, .45);
    --cxp-amber-line: rgba(245, 159, 0, .45);
}

/* ── Responsive band visibility (set per band in the Page Editor) ─────
   Named for the breakpoint they HIDE at, matching CxSection::hiddenClasses. */
@media (min-width: 1200px) { .cxp-hide-desktop{ display: none !important; }}
@media (min-width: 768px) and (max-width: 1199.98px) { .cxp-hide-tablet{ display: none !important; }}
@media (max-width: 767.98px) { .cxp-hide-mobile{ display: none !important; }}

/* ── Band shell ──────────────────────────────────────────────────────── */
.cxp-band{ padding: 34px 0; }
.cxp-band + .cxp-band{ padding-top: 6px; }
.cxp-band[data-bg="tint"]{ background: var(--cxp-brand-soft); }
.cxp-band[data-bg="contrast"]{ background: var(--aits-surface-2, #F7F8FA); }
.cxp-band[data-bg="gradient"]{
    background: linear-gradient(135deg, var(--cxp-brand-soft), transparent 70%);
}

.cxp-band-head{ margin-bottom: 18px; }
.cxp-band-title{
    font-size: clamp(1.15rem, 2.4vw, 1.5rem);
    font-weight: 800;
    color: var(--aits-ink, #14161A);
    margin: 0 0 4px;
    line-height: 1.25;
}
.cxp-band-sub{
    font-size: .9rem;
    color: var(--aits-mut, #5B6472);
    margin: 0;
    max-width: 62ch;
    line-height: 1.6;
}

/* ── Hero ────────────────────────────────────────────────────────────── */
.cxp-hero{
    padding: 44px 0 30px;
    background: linear-gradient(160deg, var(--cxp-brand-soft), transparent 62%);
    border-bottom: 1px solid var(--aits-line-soft, #EEF0F3);
}
.cxp-hero h1{
    font-size: clamp(1.6rem, 4vw, 2.5rem);
    font-weight: 850;
    line-height: 1.15;
    color: var(--aits-ink, #14161A);
    margin: 0 0 10px;
}

/* ── Card grid ───────────────────────────────────────────────────────── */
.cxp-grid{
    display: grid;
    gap: var(--cxp-gap);
    grid-template-columns: repeat(var(--cxp-cols, 4), minmax(0, 1fr));
}
@media (max-width: 1199.98px) { .cxp-grid{ grid-template-columns: repeat(min(var(--cxp-cols, 4), 3), minmax(0, 1fr)); }}
@media (max-width: 900px)     { .cxp-grid{ grid-template-columns: repeat(min(var(--cxp-cols, 4), 2), minmax(0, 1fr)); }}
@media (max-width: 560px)     { .cxp-grid{ grid-template-columns: minmax(0, 1fr); }}

/* ── Pills, badges, risk chips ───────────────────────────────────────── */
.cxp-pill{
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 9px;
    border-radius: 999px;
    font-size: .7rem;
    font-weight: 700;
    line-height: 1.65;
    white-space: nowrap;
    background: var(--cxp-brand-soft);
    color: var(--cxp-brand-ink);
}
.cxp-pill[data-tone="green"]{ background: var(--cxp-green-soft);  color: var(--cxp-green-ink); }
.cxp-pill[data-tone="amber"]{ background: var(--cxp-amber-soft);   color: var(--cxp-amber-ink); }
.cxp-pill[data-tone="red"]{ background: var(--cxp-red-soft);     color: var(--cxp-red-ink); }
.cxp-pill[data-tone="violet"]{ background: var(--cxp-violet-soft); color: var(--cxp-violet-ink); }

/* Badge rows carry their own colour twins from the database, injected as
   --cxb-* custom properties by CxBadge::styleVars() on the element itself —
   which is why they are not declared in this sheet. Every reference still
   carries a fallback: an unset custom property resolves to nothing at all, so
   a badge rendered without the inline style would be invisible rather than
   merely unstyled. */
.cxp-badge{
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 9px;
    border-radius: 999px;
    font-size: .7rem;
    font-weight: 700;
    white-space: nowrap;
    color: var(--cxb-fg, var(--cxp-brand-ink));
    background: var(--cxb-bg, var(--cxp-brand-soft));
}
body.theme-dark .cxp-badge,.theme-dark .cxp-badge{
    color: var(--cxb-fg-d, var(--cxp-brand-ink));
    background: var(--cxb-bg-d, var(--cxp-brand-soft));
}

.cxp-risk{
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 9px;
    border-radius: 999px;
    font-size: .7rem;
    font-weight: 700;
    white-space: nowrap;
    background: var(--cxp-green-soft);
    color: var(--cxp-green-ink);
}
.cxp-risk::before{ content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.cxp-risk[data-risk="medium"]{ background: var(--cxp-amber-soft); color: var(--cxp-amber-ink); }
.cxp-risk[data-risk="high"]{ background: var(--cxp-red-soft);   color: var(--cxp-red-ink); }

/* ── Detail header ───────────────────────────────────────────────────── */
.cxp-detail-head{
    display: flex;
    gap: 20px;
    flex-wrap: wrap;
    align-items: flex-start;
    padding: 30px 0 24px;
}
.cxp-detail-icon{
    width: 88px;
    height: 88px;
    flex: 0 0 auto;
    border-radius: 20px;
    border: 1px solid var(--aits-line, #E4E7EC);
    background: var(--aits-card, #fff);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    font-size: 2rem;
    font-weight: 850;
    color: var(--cxp-brand-ink);
}
.cxp-detail-icon img{ width: 100%; height: 100%; object-fit: cover; }
.cxp-detail-main{ min-width: 0; flex: 1 1 320px; }
.cxp-detail-main h1{
    font-size: clamp(1.45rem, 3.4vw, 2.1rem);
    font-weight: 850;
    color: var(--aits-ink, #14161A);
    margin: 0 0 6px;
    line-height: 1.2;
}
.cxp-detail-tagline{
    font-size: 1rem;
    color: var(--aits-mut, #5B6472);
    line-height: 1.6;
    margin: 0 0 12px;
    max-width: 62ch;
}
.cxp-detail-chips{ display: flex; flex-wrap: wrap; gap: 7px; }

.cxp-cta{
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 46px;
    padding: 0 22px;
    border-radius: 999px;
    /* --aits-blue is tuned for tints; white on it is only ~3.1:1, so the
       button uses a deeper solid. */
    background: #1B4FA6;
    color: #fff;
    font-size: .93rem;
    font-weight: 700;
    text-decoration: none;
    border: 0;
    transition: filter .15s ease, transform .15s ease;
}
.cxp-cta:hover{ filter: brightness(1.08); color: #fff; transform: translateY(-1px); }
.cxp-cta.is-ghost{
    background: transparent;
    color: var(--cxp-brand-ink);
    border: 1px solid var(--cxp-brand-line);
}
.cxp-cta.is-ghost:hover{ background: var(--cxp-brand-soft); color: var(--cxp-brand-ink); }

/* ── Spec table / permission list ────────────────────────────────────── */
.cxp-kv{
    display: grid;
    grid-template-columns: minmax(130px, 32%) 1fr;
    border: 1px solid var(--aits-line, #E4E7EC);
    border-radius: var(--cxp-radius);
    overflow: hidden;
}
.cxp-kv > dt,.cxp-kv > dd{
    margin: 0;
    padding: 10px 14px;
    font-size: .85rem;
    border-top: 1px solid var(--aits-line-soft, #EEF0F3);
}
.cxp-kv > dt:first-of-type,.cxp-kv > dd:first-of-type{ border-top: 0; }
.cxp-kv > dt{ background: var(--aits-surface-2, #F7F8FA); color: var(--aits-mut, #5B6472); font-weight: 650; }
.cxp-kv > dd{ color: var(--aits-ink, #14161A); word-break: break-word; }
@media (max-width: 560px) {
    .cxp-kv{ grid-template-columns: 1fr; }
    .cxp-kv > dd{ border-top: 0; padding-top: 0; }}

.cxp-perm{
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 13px 15px;
    border: 1px solid var(--aits-line, #E4E7EC);
    border-radius: 12px;
    background: var(--aits-card, #fff);
}
.cxp-perm + .cxp-perm{ margin-top: 9px; }
.cxp-perm[data-risk="high"]{ border-color: var(--cxp-red-line); }
.cxp-perm-ico{
    width: 34px; height: 34px; flex: 0 0 auto;
    border-radius: 10px;
    display: flex; align-items: center; justify-content: center;
    background: var(--cxp-green-soft);
    color: var(--cxp-green-ink);
}
.cxp-perm[data-risk="medium"] .cxp-perm-ico{ background: var(--cxp-amber-soft); color: var(--cxp-amber-ink); }
.cxp-perm[data-risk="high"] .cxp-perm-ico{ background: var(--cxp-red-soft);   color: var(--cxp-red-ink); }
.cxp-perm-name{ font-size: .89rem; font-weight: 700; color: var(--aits-ink, #14161A); }
.cxp-perm-desc{ font-size: .8rem; color: var(--aits-mut, #5B6472); line-height: 1.55; margin-top: 2px; }
.cxp-perm-note{ font-size: .78rem; color: var(--cxp-brand-ink); margin-top: 5px; }

/* ── Pros / cons ─────────────────────────────────────────────────────── */
.cxp-pc{ display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 14px; }
.cxp-pc-col{
    border: 1px solid var(--aits-line, #E4E7EC);
    border-radius: var(--cxp-radius);
    padding: 16px;
    background: var(--aits-card, #fff);
}
.cxp-pc-col h3{ font-size: .95rem; font-weight: 750; margin: 0 0 10px; }
.cxp-pc-col.is-pro h3{ color: var(--cxp-green-ink); }
.cxp-pc-col.is-con h3{ color: var(--cxp-red-ink); }
.cxp-pc-col ul{ list-style: none; margin: 0; padding: 0; }
.cxp-pc-col li{
    display: flex; gap: 9px; align-items: flex-start;
    font-size: .87rem; color: var(--aits-ink-soft, #2C3340);
    line-height: 1.55; padding: 5px 0;
}
.cxp-pc-col li > i{ margin-top: 3px; flex: 0 0 auto; font-size: .8rem; }
.cxp-pc-col.is-pro li > i{ color: var(--cxp-green-ink); }
.cxp-pc-col.is-con li > i{ color: var(--cxp-red-ink); }

/* ── Gallery ─────────────────────────────────────────────────────────── */
.cxp-gallery{
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(260px, 420px);
    gap: 14px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    padding-bottom: 8px;
}
.cxp-gallery figure{ margin: 0; scroll-snap-align: center; }
.cxp-gallery img{
    width: 100%;
    border-radius: 12px;
    border: 1px solid var(--aits-line, #E4E7EC);
    display: block;
}
.cxp-gallery figcaption{ font-size: .76rem; color: var(--aits-mut, #5B6472); margin-top: 6px; }

/* ── Version list ────────────────────────────────────────────────────── */
.cxp-ver{ display: flex; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--aits-line-soft, #EEF0F3); }
.cxp-ver:last-child{ border-bottom: 0; }
.cxp-ver-tag{
    flex: 0 0 auto;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: .78rem;
    font-weight: 700;
    color: var(--cxp-brand-ink);
    min-width: 74px;
}
.cxp-ver-body{ min-width: 0; }
.cxp-ver-date{ font-size: .73rem; color: var(--aits-faint, #8B93A1); }
.cxp-ver-notes{ font-size: .85rem; color: var(--aits-mut, #5B6472); line-height: 1.55; margin-top: 2px; }

/* ── Sidebar ─────────────────────────────────────────────────────────── */
.cxp-layout{ display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 30px; align-items: start; }
@media (max-width: 992px) { .cxp-layout{ grid-template-columns: minmax(0, 1fr); }}
.cxp-aside{ position: sticky; top: calc(var(--aits-hd-h, 76px) + 20px); display: flex; flex-direction: column; gap: 16px; }
@media (max-width: 992px) { .cxp-aside{ position: static; }}
.cxp-panel{
    border: 1px solid var(--aits-line, #E4E7EC);
    border-radius: var(--cxp-radius);
    background: var(--aits-card, #fff);
    padding: 16px;
}
.cxp-panel h3{ font-size: .88rem; font-weight: 750; color: var(--aits-ink, #14161A); margin: 0 0 10px; }

/* ── Disclosure note ─────────────────────────────────────────────────── */
.cxp-note{
    padding: 11px 14px;
    border: 1px solid var(--cxp-brand-line);
    background: var(--cxp-brand-soft);
    border-radius: 11px;
    font-size: .8rem;
    color: var(--aits-ink-soft, #2C3340);
    line-height: 1.55;
}
.cxp-note.is-warn{
    border-color: var(--cxp-amber-line);
    background: var(--cxp-amber-soft);
}
.cxp-note b{ color: var(--cxp-brand-ink); }
.cxp-note.is-warn b{ color: var(--cxp-amber-ink); }

/* ── Motion / accessibility ──────────────────────────────────────────── */
.cxp :focus-visible{
    outline: 2px solid var(--aits-focus, #3680ED);
    outline-offset: 2px;
    border-radius: 6px;
}
@media (prefers-reduced-motion: reduce) {
    .cxp-cta{ transition: none; }
    .cxp-cta:hover{ transform: none; }}

/* ══════════════════════════════════════════════════════════════════════
   AI-DIRECTORY PARITY LAYER (2026-08-12)
   ----------------------------------------------------------------------
   Brings /browser-extensions onto the /ai-directory visual language: the
   orbit hero,the ring search field,the solid tone-plate icons,and the
   directory's card and tile anatomy.

   Written as a LAYER over the existing .cxp- kit rather than a rewrite,because this sheet also dresses /browser-extensions/{slug} and the band
   markup is admin-editable through the Page Editor — the bands, their
   order and their visibility all still come from cx_sections.

   Own token set with explicit dark twins, for the reason this file's header
   already gives: the --aits-* inks are declared ONLY in the light block, so
   using one as a foreground at night renders light-on-light.
   ══════════════════════════════════════════════════════════════════════ */

.cxp {
    --cxd-ink: #0F0F12;
    --cxd-muted: #4A4A5A;
    --cxd-line: #e7eaf0;
    --cxd-card: #ffffff;
    --cxd-blue: #3680ED;
    --cxd-blue-dark: #2060C0;
    --cxd-blue-light: #60A4F5;
    /* Plate inks — the homepage/directory --hpx-t-*-ink values verbatim, so a
       tone chip here is the same colour as the same tone on / and on
       /ai-directory. */
    --cxd-t-blue: #1B5BB5;   --cxd-t-violet: #5B33C4; --cxd-t-emerald: #08795A;
    --cxd-t-amber: #A85B08;  --cxd-t-rose: #B31D3C;   --cxd-t-cyan: #0A6E88;
    --cxd-t-indigo: #3540B0; --cxd-t-orange: #B4500C; --cxd-t-teal: #0B6E68;
}

body.theme-dark .cxp,.theme-dark .cxp{
    --cxd-ink: #E7E9EE;
    --cxd-muted: #A6ADBB;
    --cxd-line: rgba(255, 255, 255, .09);
    --cxd-card: rgba(28, 31, 42, .85);
    /* Lightened so they can carry a white glyph on a dark surface. Every plate
       rule below layers a scrim over these — see the plate section. */
    --cxd-t-blue: #8CBEFA;   --cxd-t-violet: #BFA6FB; --cxd-t-emerald: #6EE7BE;
    --cxd-t-amber: #FBC97A;  --cxd-t-rose: #FB9BB0;   --cxd-t-cyan: #7CD9EE;
    --cxd-t-indigo: #A9B2FB; --cxd-t-orange: #FBB07A; --cxd-t-teal: #79DDD5;
}

/* ── 1 · HERO ───────────────────────────────────────────────────────────
   `isolation:isolate` rather than a z-index on the orbit: the arcs and dots
   must sit behind the copy without the hero creating a stacking context that
   traps the stat deck under the band that follows it. */
.cxp .cxp-hero{
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 44px 16px 8px;
    text-align: center;
    isolation: isolate;
}

.cxp .cxp-hero > .container{ position: relative; z-index: 1; }
@keyframes cxp-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-14px); } }

.cxp .cxp-hero h1{
    width: 100%;
    margin: 22px 0 0;
    font-size: clamp(32px, 5.4vw, 62px);
    line-height: 1.08;
    font-weight: 800;
    letter-spacing: -.032em;
    color: var(--cxd-ink);
    text-wrap: balance;
}
/* The accent is a clipped gradient, so it stays legible against both canvases
   without a second colour token. */
.cxp .cxp-hero h1 .cxp-accent{
    display: inline;
    color: var(--cxd-blue);
    background: linear-gradient(100deg, var(--cxd-blue) 6%, var(--cxd-blue-dark) 58%, var(--cxd-blue-dark) 100%);
    -webkit-background-clip: text;
            background-clip: text;
    -webkit-text-fill-color: transparent;
}
body.theme-dark .cxp .cxp-hero h1 .cxp-accent{
    background: linear-gradient(100deg, var(--cxd-blue-light) 6%, var(--cxd-blue) 58%, var(--cxd-blue-light) 100%);
    -webkit-background-clip: text;
            background-clip: text;
}

/* ── 2 · HERO SEARCH ────────────────────────────────────────────────────
   The directory field: a lit top edge, an iridescent ring that flows, a glint
   that crosses it, and a brand bloom underneath. The ring is a masked
   border-box gradient rather than a blurred pseudo behind the pill — a pseudo
   would need a negative z-index, which needs a stacking context, which would
   trap the stat deck below it. */
.cxp .cxp-hero .cxp-filters{ margin: 32px auto 0; max-width: 780px; }

.cxp .cxp-hero .cxp-search{
    position: relative;
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 8px 8px 8px 22px;
    background-color: var(--cxd-card);
    background-image: linear-gradient(180deg, rgba(255,255,255,.7) 0%, rgba(255,255,255,0) 46%);
    border: 1px solid var(--cxd-line);
    border-radius: 999px;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, .85),
        0 1px 2px rgba(16, 24, 40, .04),
        0 14px 38px -14px rgba(16, 24, 40, .20),
        0 0 22px -6px rgba(124, 77, 240, .30),
        0 6px 26px -8px rgba(236, 72, 153, .22);
    transition: border-color .25s ease, box-shadow .25s ease, transform .25s ease;
}
body.theme-dark .cxp .cxp-hero .cxp-search{
    background-image: none;
    box-shadow: 0 2px 6px rgba(0,0,0,.46), 0 18px 44px rgba(0,0,0,.5), 0 0 22px -6px rgba(124,77,240,.26);
    -webkit-backdrop-filter: blur(18px);
            backdrop-filter: blur(18px);
}

/* The spectrum is listed TWICE across a 200% image, so a shift of exactly one
   element width lands on an identical pattern — the loop has no seam. */
.cxp .cxp-hero .cxp-search::after{
    content: '';
    position: absolute;
    inset: -3px;
    border-radius: inherit;
    padding: 3px;
    background-image: linear-gradient(90deg,
        #3680ED, #7C4DF0, #EC4899, #F43F5E, #F59E0B, #10B981, #06B6D4,
        #3680ED, #7C4DF0, #EC4899, #F43F5E, #F59E0B, #10B981, #06B6D4, #3680ED);
    background-size: 200% 100%;
    -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
            mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
    opacity: .88;
    animation: cxp-ring-flow 9s linear infinite;
    transition: opacity .3s ease, padding .3s ease, inset .3s ease;
    pointer-events: none;
}
body.theme-dark .cxp .cxp-hero .cxp-search::after{ opacity: .72; }
@keyframes cxp-ring-flow { to { background-position: 100% 50%; } }

.cxp .cxp-hero .cxp-search:focus-within{
    border-color: transparent;
    box-shadow:
        0 0 0 5px rgba(54, 128, 237, .22),
        0 0 30px -4px rgba(124, 77, 240, .42),
        0 8px 34px -6px rgba(236, 72, 153, .30);
    transform: translateY(-1px);
}
.cxp .cxp-hero .cxp-search:focus-within::after{ opacity: 1; inset: -4px; padding: 4px; }

.cxp .cxp-hero .cxp-search > i{
    flex: 0 0 auto;
    width: 22px;
    color: #7d8494;
    font-size: 18px;
    transition: color .25s ease, transform .25s ease;
}
.cxp .cxp-hero .cxp-search:focus-within > i{ color: var(--cxd-blue); transform: scale(1.06); }

.cxp .cxp-hero .cxp-search input{
    flex: 1 1 auto;
    min-width: 0;
    height: 56px;
    border: 0;
    outline: 0;
    background: transparent;
    color: var(--cxd-ink);
    font-size: 16px;
    font-weight: 450;
}
.cxp .cxp-hero .cxp-search input::-webkit-search-cancel-button{ -webkit-appearance: none; }

.cxp .cxp-hero .cxp-search-btn{
    position: relative;
    overflow: hidden;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    flex: 0 0 auto;
    height: 56px;
    padding: 0 26px;
    border: 0;
    border-radius: 999px;
    background: linear-gradient(135deg, var(--cxd-blue) 0%, var(--cxd-blue-dark) 100%);
    color: #fff;
    font-size: 14.5px;
    font-weight: 700;
    letter-spacing: -.005em;
    cursor: pointer;
    box-shadow: 0 6px 18px -6px rgba(54, 128, 237, .55);
    transition: transform .2s ease, box-shadow .25s ease;
}
.cxp .cxp-hero .cxp-search-btn:hover{ transform: translateY(-1px); box-shadow: 0 12px 30px -8px rgba(54,128,237,.6); }
.cxp .cxp-hero .cxp-search-btn:active{ transform: scale(.98); }
.cxp .cxp-hero .cxp-search-btn i{ font-size: 14px; }
/* A sheen that crosses the button on hover — the same sweep the directory's
   primary control uses. */
.cxp .cxp-hero .cxp-search-btn::after{
    content: '';
    position: absolute;
    top: 0; left: -140%;
    width: 55%; height: 100%;
    background: linear-gradient(120deg, transparent, rgba(255,255,255,.5), transparent);
    transform: skewX(-18deg);
    transition: left .7s cubic-bezier(.22,.61,.36,1);
    pointer-events: none;
}
.cxp .cxp-hero .cxp-search-btn:hover::after{ left: 150%; }

/* Tone selection. `data-tone` on the element itself, so a tile and a stat can
   sit in the same grid on different hues. */
.cxp [data-tone="blue"]{ --cxd-plate: var(--cxd-t-blue); }
.cxp [data-tone="violet"]{ --cxd-plate: var(--cxd-t-violet); }
.cxp [data-tone="emerald"],.cxp [data-tone="green"]{ --cxd-plate: var(--cxd-t-emerald); }
.cxp [data-tone="amber"]{ --cxd-plate: var(--cxd-t-amber); }
.cxp [data-tone="rose"]{ --cxd-plate: var(--cxd-t-rose); }
.cxp [data-tone="cyan"]{ --cxd-plate: var(--cxd-t-cyan); }
.cxp [data-tone="indigo"]{ --cxd-plate: var(--cxd-t-indigo); }
.cxp [data-tone="orange"]{ --cxd-plate: var(--cxd-t-orange); }
.cxp [data-tone="teal"]{ --cxd-plate: var(--cxd-t-teal); }

/* ── 5 · RESPONSIVE ─────────────────────────────────────────────────────
   A grid item's automatic minimum is min-content, so a wide row inside a
   narrow track overflows its container silently. `min-width:0` on the cells
   is what stops the deck pushing the page sideways on a phone. */
.cxp .cxp-hero > .container{ min-width: 0; }
@media (max-width: 700px) {
    .cxp .cxp-hero{ padding: 32px 16px 4px; }
    .cxp .cxp-hero .cxp-search{ padding: 6px 6px 6px 16px; gap: 8px; }
    .cxp .cxp-hero .cxp-search input{ height: 48px; font-size: 15px; }
    .cxp .cxp-hero .cxp-search-btn{ height: 48px; padding: 0 16px; }
    .cxp .cxp-hero .cxp-search-btn span{ display: none; }}

@media (prefers-reduced-motion: reduce) {
    .cxp .cxp-hero .cxp-search::after{ animation: none; }
    .cxp .cxp-hero .cxp-search-btn::after{ transition: none; }}

/* ── 6 · CARDS AND TILES ────────────────────────────────────────────────
   The directory's card anatomy: an elevated surface with a lit top edge, an
   accent bar that wipes in on hover, a lift, and the tone plate for the icon.

   Every hover effect sits inside @media (hover:hover). On a touch screen a
   :hover rule sticks after the tap and leaves a card frozen in its lifted
   state until you touch something else. */
.cxp .cxp-card {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    background: var(--cxd-card);
    border: 1px solid var(--cxd-line);
    border-radius: 20px;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, .7),
        0 1px 2px rgba(16, 24, 40, .04),
        0 10px 24px -20px rgba(16, 24, 40, .30);
    transition: transform .25s cubic-bezier(.22,.61,.36,1), box-shadow .28s ease, border-color .2s ease;
}

/* ── 7 · SECTION HEADS ──────────────────────────────────────────────────
   The directory leads a band with a gradient tick, so a heading reads as the
   start of a section rather than as loose text above a grid. */
.cxp .cxp-band-title{
    position: relative;
    letter-spacing: -.028em;
    font-weight: 800;
}
.cxp .cxp-band-head{ position: relative; }
.cxp .cxp-band-title::before{
    content: '';
    position: absolute;
    left: -14px; top: .18em;
    width: 4px; height: .82em;
    border-radius: 99px;
    background: linear-gradient(180deg, var(--cxd-blue) 0%, var(--cxd-blue-dark) 100%);
}
/* The tick needs the gutter it sits in; without this it clips on a narrow
   viewport where the band padding is already tight. */
@media (max-width: 700px) { .cxp .cxp-band-title::before{ display: none; }}
@keyframes cxp-spin { to { transform: rotate(360deg); } }