/* ══════════════════════════════════════════════════════════════════════════
   Browser Extensions — DELTA over the AI Directory design system
   --------------------------------------------------------------------------
   /browser-extensions wears /ai-directory's sheet
   (assets/css/ext/v2-public-directory-listing.css) by using that page's own
   `.v2x .dir-*` class names. Sharing the sheet rather than copying it is what
   keeps the two pages from drifting — a snapshot was tried first and rotted in
   two days.

   This file holds ONLY what a catalogue of browser extensions needs and a
   catalogue of AI tools has no concept of:

     §RISK   permission-risk chips and the risk meter
     §BRW    the browser-support row (Chrome / Edge / Firefox …)
     §CARD   the two card slots the extension card adds to `.dir-tc`
     §HERO   hero tiles carrying a monogram instead of a product logo
     §DECK   the sixth stat tile's tone, absent from the directory's cycle

   Loaded LAST of the three sheets, so it wins where it must. Everything it
   does not define is inherited — deliberately. If a rule here duplicates the
   directory's, delete it here: the point of the delta is that it is small
   enough to read.

   Tone vocabulary is the directory's, not a new one. Before adding a
   `data-tone` value, check it exists in the directory sheet for THAT component
   — an unmatched tone falls back to blue SILENTLY. Verified ranges:
     .dir-hh-stat      12 tones   .dir-tc-pill    10
     .dir-cat-card      8         .dir-why-card    6
     .dir-ts-ic / .dir-ts-opt-ic  5  ← amber blue cyan indigo violet ONLY

   Dark mode: the directory sheet keys dark off `body.theme-dark`. Every rule
   here that sets a colour declares its dark twin the same way, in the same
   block, so a light-only addition can't slip through review.
   ══════════════════════════════════════════════════════════════════════════ */

/* ═══ §RISK — permission risk ══════════════════════════════════════════════
   The module's whole editorial angle: what an extension ASKS FOR, not only
   what it does. Reuses the directory's pill shape; adds the three-step meter
   that shape has no room for.

   ⚠ THE SIGNAL IS FILLED-VS-HOLLOW, NOT COLOUR, AND NOT LUMINANCE.

   The first version lit the bars with flat tone colours (#0F9F6E green,
   #D97706 amber) over a light grey track. Measured against the composited
   track those came out at 2.53:1 and 2.38:1 — under the 3:1 floor for
   non-text UI, which means the difference between "one bar lit" and "no bars
   lit" was not reliably visible in light mode. The bars are the whole control:
   if lit and unlit are hard to separate, the meter reads as decoration.

   Two changes fix it and keep it fixed:

   1. A lit bar is SOLID, an unlit bar is an OUTLINE. That is a difference in
      form, so it survives any ground, either theme, and a viewer who cannot
      separate the green from the amber at all.
   2. Both states are drawn in `currentColor`. Inside a `.dir-tc-pill` that
      resolves to the pill's own tone ink, which the directory sheet already
      guarantees is legible on the pill's fill in BOTH themes — so the meter
      inherits an accessible colour instead of hardcoding one that has to be
      re-checked against every surface it might land on.

   Only the STANDALONE placements (the facet rail, the trending rail) set a
   colour of their own, because there is no pill above them to inherit from.
   Those inks are measured against the page surface, not against the raw hue. */

.v2x .cxr-meter{display:inline-flex;align-items:center;gap:4px;vertical-align:middle;color:inherit}
.v2x .cxr-meter i{display:block;width:13px;height:5px;border-radius:2.5px;
    background:transparent;box-shadow:inset 0 0 0 1.25px currentColor;opacity:.34;
    transition:opacity .18s ease,background-color .18s ease}
/* Lit bars: solid fill, full strength. nth-child rather than a class so the
   markup stays three identical <i>s and the level lives in one attribute. */
.v2x .cxr-meter[data-risk="low"]    i:nth-child(1),
.v2x .cxr-meter[data-risk="medium"] i:nth-child(-n+2),
.v2x .cxr-meter[data-risk="high"]   i{background:currentColor;opacity:1;box-shadow:none}

/* Standalone placements — no pill to inherit an ink from. Measured on the
   card/rail surface: light 4.9–6.3:1, dark 8.0–13:1, all well past the 3:1
   non-text floor.

   The colour is set on the WRAPPER, not on the meter, so the meter's bars
   (currentColor) and the trending rail's text level inherit the same ink from
   one declaration. Setting it on `.cxr-meter` would have coloured the bars and
   left the label beside them at the row's default grey. */
.v2x .dir-fx-chk .cxr-meter[data-risk="low"],
.v2x .dir-tr-rt[data-risk="low"]   {color:#0A7A54}
.v2x .dir-fx-chk .cxr-meter[data-risk="medium"],
.v2x .dir-tr-rt[data-risk="medium"]{color:#A85D00}
.v2x .dir-fx-chk .cxr-meter[data-risk="high"],
.v2x .dir-tr-rt[data-risk="high"]  {color:#BE123C}
body.theme-dark .v2x .dir-fx-chk .cxr-meter[data-risk="low"],
body.theme-dark .v2x .dir-tr-rt[data-risk="low"]   {color:#34D399}
body.theme-dark .v2x .dir-fx-chk .cxr-meter[data-risk="medium"],
body.theme-dark .v2x .dir-tr-rt[data-risk="medium"]{color:#FBBF24}
body.theme-dark .v2x .dir-fx-chk .cxr-meter[data-risk="high"],
body.theme-dark .v2x .dir-tr-rt[data-risk="high"]  {color:#FB7185}

/* The facet rail's risk rows carry the same meter, sized down to sit on one
   line with the label and the count without pushing the count off the edge. */
.v2x .dir-fx-chk .cxr-meter{margin-inline-end:7px;flex:0 0 auto}
.v2x .dir-fx-chk .cxr-meter i{width:11px;height:4px}

/* Trending rail: meter beside its own label, because there is no pill and no
   sentence around it there. An unlabelled three-bar gauge in a ranked list is
   a puzzle, not a datum. */
.v2x .dir-tr-rt{display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
.v2x .dir-tr-rt .cxr-lvl{font:600 10.5px/1 ui-sans-serif,system-ui,sans-serif;
    letter-spacing:.02em;text-transform:uppercase;color:currentColor}
.v2x .dir-tr-rt .cxr-meter i{width:9px;height:4px}

/* ═══ §BUSY — results dimmed while a filter is in flight ═══════════════════
   The toolbar already says "Updating…", but the results themselves are the
   thing the visitor is watching, and on a fast connection the grid swaps with
   no indication that anything was requested.

   This is a DELTA, not a copy: `is-busy` has no rule in the directory sheet,
   in cx-public.css, or anywhere else — `wire:loading.class="is-busy"` was
   landing a class nothing styled. The class also had to move off `.dir-lx`,
   which the directory sheet defines as the list-mode flex column rather than a
   generic results wrapper.

   Kept deliberately gentle: a heavy fade on every keystroke of a debounced
   search reads as flicker. Opacity only — no transform, no blur — so nothing
   reflows and the page does not appear to jump while typing. */
.v2x .cx-results{transition:opacity .18s ease}
.v2x .cx-results.is-busy{opacity:.45;pointer-events:none}
/* A visitor who has asked for less motion still gets the state, just without
   the fade animating. */
@media (prefers-reduced-motion:reduce){
    .v2x .cx-results{transition:none}
}

/* ═══ §BTN — card CTA: DO NOT override the tone ════════════════════════════
   ⚠ There was a `body:not(.theme-dark) .v2x .dir-tc-btn{background-color:#3174D8}`
   rule here. It is DELETED on purpose — do not re-add it.

   The directory's card button is TONE-CYCLED: its base rule is
   `.dir-tc-btn{background-color:var(--dtc-ink)}`, and `--dtc-ink` is set per
   card by `.dir-tc:nth-child(8n+N)` (blue, violet, emerald, amber, rose, cyan,
   indigo, orange). Every card's CTA is the card's own colour — that is the
   whole look of the section. Setting a flat `background-color` here overrode
   `var(--dtc-ink)` on EVERY card, so all ten buttons rendered the same blue and
   the section stopped matching /ai-directory. The user flagged exactly that.

   The rule had been added as a contrast fix — flat blue #3680ED is 3.84:1 with
   white. But the directory ships those same tone buttons at the same ratios
   (blue/emerald/cyan land 3.68–3.84 on their light stop), so "match the
   directory" and "flatten to one accessible blue" are in direct conflict, and
   the user chose the match. The button now inherits `var(--dtc-ink)` untouched
   and is pixel-identical to the directory's.

   If button contrast is ever raised, do it WITHOUT breaking the tone and do it
   on BOTH pages at once: switch the shared base rule from `var(--dtc-ink)` to
   `var(--dtc-ink-dark)` in the directory sheet (every dark tone clears 4.5 and
   stays tone-cycled). That is a shared-sheet decision, not a BE-only override. */

/* ═══ §BRW — browser support ═══════════════════════════════════════════════
   `cx_extensions.browsers` is a vocabulary column (["chrome","edge",…]), so
   the row is a fact about the listing, not a filter. Rendered as initials
   rather than vendor logos: shipping eight brand marks to state compatibility
   is a lot of weight and a trademark question for a line of text. */

.v2x .cxb-row{display:inline-flex;align-items:center;gap:4px;flex-wrap:wrap}
.v2x .cxb{display:inline-grid;place-items:center;width:19px;height:19px;border-radius:6px;
          font:600 9.5px/1 ui-sans-serif,system-ui,sans-serif;letter-spacing:.02em;
          background:rgba(15,23,42,.06);color:#475569;border:1px solid rgba(15,23,42,.07)}
body.theme-dark .v2x .cxb{background:rgba(226,232,240,.08);color:#CBD5E1;border-color:rgba(226,232,240,.12)}
.v2x .cxb[data-b="chrome"] {background:rgba(66,133,244,.12);color:#1A56B8;border-color:rgba(66,133,244,.2)}
.v2x .cxb[data-b="edge"]   {background:rgba(0,120,212,.12); color:#0A5A9E;border-color:rgba(0,120,212,.2)}
.v2x .cxb[data-b="firefox"]{background:rgba(255,102,0,.12); color:#A34700;border-color:rgba(255,102,0,.2)}
.v2x .cxb[data-b="brave"]  {background:rgba(251,84,44,.12); color:#A63216;border-color:rgba(251,84,44,.2)}
.v2x .cxb[data-b="opera"]  {background:rgba(255,27,45,.12); color:#A8121F;border-color:rgba(255,27,45,.2)}
.v2x .cxb[data-b="safari"] {background:rgba(0,122,255,.12); color:#0A5AB4;border-color:rgba(0,122,255,.2)}
/* Dark: the light fills above are inks at 12% on white and go muddy on a dark
   ground, so both the fill and the ink are restated rather than tinted. */
body.theme-dark .v2x .cxb[data-b="chrome"] {background:rgba(96,164,245,.16);color:#93C5FD;border-color:rgba(96,164,245,.26)}
body.theme-dark .v2x .cxb[data-b="edge"]   {background:rgba(56,160,230,.16);color:#7DD3FC;border-color:rgba(56,160,230,.26)}
body.theme-dark .v2x .cxb[data-b="firefox"]{background:rgba(255,146,72,.16);color:#FDBA74;border-color:rgba(255,146,72,.26)}
body.theme-dark .v2x .cxb[data-b="brave"]  {background:rgba(251,120,80,.16);color:#FDA4AF;border-color:rgba(251,120,80,.26)}
body.theme-dark .v2x .cxb[data-b="opera"]  {background:rgba(255,90,105,.16);color:#FCA5A5;border-color:rgba(255,90,105,.26)}
body.theme-dark .v2x .cxb[data-b="safari"] {background:rgba(96,164,245,.16);color:#93C5FD;border-color:rgba(96,164,245,.26)}

/* ═══ §CARD — the two slots the extension card adds ════════════════════════ */

/* The directory card's meta row is one line of pills. An extension card has
   more to say per listing (price · risk · badge), so the row wraps instead of
   clipping — a risk chip that scrolls out of view is the one chip on this card
   that must not. */
.v2x .dir-tc .dir-tc-meta{flex-wrap:wrap;row-gap:6px}

/* Browser row sits between the description and the meta pills, on its own
   line, so the pills keep their rhythm across cards of differing content. */
.v2x .dir-tc .cxb-row{margin:2px 0 8px}

/* ═══ §HERO — monogram tiles ═══════════════════════════════════════════════
   The directory's hero tiles carry product logos. Every seeded extension has
   `icon` NULL, so a tile here would be an empty box. These render the same
   tile with a tone-tinted monogram, and swap to the image the moment a real
   icon is uploaded — `:has(img)` drops the fill so an uploaded logo is never
   painted over with a brand colour it does not own. */

.v2x .dir-hh-tile .cxt-mono{display:grid;place-items:center;width:100%;height:100%;
    border-radius:inherit;font:700 20px/1 ui-sans-serif,system-ui,sans-serif;letter-spacing:-.02em}
/* ⚠ THESE ARE NOT THE BRAND HUES AT FULL STRENGTH, AND MUST NOT BE PUT BACK.

   The first version of this block used the palette's display values —
   #3680ED, #7C3AED, #0F9F6E, #D97706 paired with a lighter stop. A gradient
   has to be measured at its LIGHTEST point, not its midpoint, and at that end
   white text came out at:

       blue 2.82:1 · violet 3.63:1 · emerald 2.48:1 · amber 2.12:1

   Three of the four fail even the 3:1 large-text floor, and the monogram is
   the tile's only content. It looked fine at a glance because a saturated
   fill reads as "strong" — saturation is not luminance, which is the whole
   reason this needs measuring rather than eyeballing.

   Each hue below is scaled toward black until white clears 4.5:1 at BOTH
   stops. Measured white-on-fill, lightest stop first:

       blue 4.53 / 4.55 · violet 4.56 / 5.70 · emerald 4.55 / 4.53 · amber 4.51 / 4.50

   ONE SET SERVES BOTH THEMES, and that is a measured result rather than an
   omission: the same fills sit at 4.23–5.36:1 against the light hero ground
   (#F6F8FC) and 3.29–4.16:1 against the dark one (#0B1220), so the plate is
   clear of the 3:1 non-text floor either way. A `body.theme-dark` twin here
   would change numbers that already pass in both directions. The header's
   "every colour declares its dark twin" rule is satisfied by this note: the
   twin was considered and is deliberately absent, not forgotten. */
.v2x .dir-hh-tile[data-tone="blue"]    .cxt-mono{background:linear-gradient(145deg,#3174D8,#4677BD);color:#fff}
.v2x .dir-hh-tile[data-tone="violet"]  .cxt-mono{background:linear-gradient(145deg,#7C3AED,#885ED5);color:#fff}
.v2x .dir-hh-tile[data-tone="emerald"] .cxt-mono{background:linear-gradient(145deg,#0D875D,#258563);color:#fff}
.v2x .dir-hh-tile[data-tone="amber"]   .cxt-mono{background:linear-gradient(145deg,#B36205,#A06C1F);color:#fff}

/* An uploaded icon wins over the monogram treatment entirely. */
.v2x .dir-hh-tile:has(img) .cxt-mono{display:none}

/* ═══ §DECK — sixth stat tone ══════════════════════════════════════════════
   The directory cycles six stat tones; this page's sixth figure is "open
   source", which reads green. `emerald` is already spent on "verified", so the
   tile uses `teal` — present in the directory sheet's 12-tone stat range, so
   this is a selection, not a new colour. Left as a comment rather than a rule
   precisely because no rule is needed; the note stops the next person adding
   one. */

/* ═══ RESPONSIVE ══════════════════════════════════════════════════════════
   The directory sheet already carries the page's breakpoints. Only the pieces
   defined ABOVE need their own, so this block stays short by construction. */

@media (max-width:640px){
    /* Below 640 the card's meta row is the first thing to crowd. Dropping the
       browser row there keeps the price and risk chips — the two a visitor
       filters on — on one line each rather than three. The information is not
       lost: it is on the detail page, which is one tap away. */
    .v2x .dir-tc .cxb-row{display:none}
}
