/* ══════════════════════════════════════════════════════════════════════════
   AI EVENTS — the /ai-directory DELTA.  Scope: .v2x.evx
   Loaded by resources/views/livewire/public/events/{hub,archive,categories}
   .blade.php, AFTER public-partials-styles.css (the .v2x token layer) and
   v2-public-directory-listing.css (/ai-directory's own LIVE sheet).

   Everything the directory already does is INHERITED, not copied. What lives
   here is only what an events listing needs and a tools directory has no
   concept of.

   ⚠ THIS FILE MUST NOT BE LOADED WITHOUT THE TWO SHEETS ABOVE IT. Every
     var(--dtc-*) / var(--v2-*) below is declared there; alone they resolve
     invalid and the rules silently do nothing.

   ⚠ Anything that belongs to ALL listing pages goes in the shared sheet, not
     here — an edit there now reaches SEVEN pages (/ai-directory,
     /browser-extensions, /gpts, /workflows, /ai-projects, /cheat-sheet*,
     /events*). Check them all.

   ⚠ Breakpoints follow the SHARED sheet's ladder, measured by frequency:
     820 ×7 · 520 ×5 · 1180 ×5 · 640 ×2 · 900/680/560/480/420/400/1500 ×1.
     NOT Bootstrap's 991.98/767.98. A delta that breaks 140px before the page
     does is how a card goes column-wise while its neighbour has not.

   ⚠ NO :has() — zero precedent in the shared sheet; Safari <15.4 drops the
     whole selector, taking the rest of the rule with it.

   ── SECTIONS ──────────────────────────────────────────────────────────────
     §DP      the date plate — the events card's signature element
     §FLAG    the featured / cancelled ribbon
     §PILL    an icon inside the shared type pill
     §FACT    the icon+text facts under a card
     §FOOT    price + CTA row (the grid card's foot)
     §PRICE   the price / free badge
     §TILE    an SVG (not an <img>) inside a hero orbit tile
     §MONO    an SVG (not a letter) inside a rail logo plate
     §SHELF   the curated admin bands between the grid and the category rail
     §TYPE    the browse-by-format pill row
     §CATGRID /events/categories — the same cards, a browse layout
     §CRUMB   breadcrumbs
     §HERE    "you are here" on a rail
     §BUSY    `is-busy` — defined in NO sheet in the stack; sixth module in a
              row to hit this. wire:loading.class lands a dead class without it
     §IOS     16px search input so iOS Safari does not zoom on focus
     §RESP    the responsive fixes the above need
     §MOTION  reduced-motion
   ══════════════════════════════════════════════════════════════════════════ */


/* ═══ §DP — the date plate ══════════════════════════════════════════════════
   The directory puts a tool LOGO here. An event has none: `banner` and
   `og_image` are NULL on all 11 published events and only 1 of 11 organizers
   has a logo, so a media strip would be an empty gradient on every card and a
   logo plate would differ on exactly one. The date is also the thing a reader
   scans an events listing FOR.

   NO accent is injected. `.dir-tc-logo` already paints var(--dtc-bg) behind
   var(--dtc-ink-dark) — a positionally-cycled pair the directory designed and
   contrast-checked together, with a full dark twin. Replacing it with a
   category colour would swap a curated pair for an arbitrary one; that is the
   mistake §PLATE on /workflows and /ai-projects had to undo with a white
   scrim. Here the fix is simply not to make it.

   Three states, and each carries TEXT or a GLYPH as well as its colour
   (WCAG 1.4.1): a dated event shows its date, a live one says "Live" beside a
   pulse, an on-demand one shows a play glyph and says "Watch".
   ────────────────────────────────────────────────────────────────────────── */
.v2x.evx .evx-dp{
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  width:100%; height:100%; gap:1px; line-height:1;
  color:var(--dtc-ink-dark);
  font-variant-numeric:tabular-nums;
}
.v2x.evx .evx-dp-m{
  font-size:10.5px; font-weight:800; letter-spacing:.10em; text-transform:uppercase;
  opacity:.9;
}
.v2x.evx .evx-dp-d{
  font-size:26px; font-weight:820; letter-spacing:-.03em;
}
.v2x.evx .evx-dp-lbl{
  font-size:9.5px; font-weight:800; letter-spacing:.09em; text-transform:uppercase;
}
.v2x.evx .evx-dp svg{ width:22px; height:22px; }

/* Live. The pulse is decoration; the word "Live" is the signal. */
.v2x.evx .evx-dp-pulse{
  width:9px; height:9px; border-radius:50%;
  background:currentColor;
  box-shadow:0 0 0 0 currentColor;
  animation:evx-pulse 1.8s ease-out infinite;
}
@keyframes evx-pulse{
  0%   { box-shadow:0 0 0 0 rgba(220,38,38,.55); }
  70%  { box-shadow:0 0 0 8px rgba(220,38,38,0); }
  100% { box-shadow:0 0 0 0 rgba(220,38,38,0); }
}
/* A live event overrides the positional tone: "happening now" is a state, not
   a slot in a colour cycle, and it must read the same on every card. */
.v2x.evx .evx-dp.is-live{ color:#B3122B; }
.v2x.evx .dir-tc .evx-dp.is-live,
.v2x.evx .dir-lc .evx-dp.is-live{ color:#B3122B; }
body.theme-dark .v2x.evx .evx-dp.is-live{ color:#FB9BB0; }
body.theme-dark .v2x.evx .dir-tc .evx-dp.is-live,
body.theme-dark .v2x.evx .dir-lc .evx-dp.is-live{ color:#FB9BB0; }

/* The LIVE plate takes its own fill as well as its own ink. Without it a red
   "Live" glyph sits on whatever tint the 8-step positional cycle handed that
   card — green, amber, violet — which is legible but reads as a mistake
   rather than as a state. `has-live` is set on the PLATE (a parent class),
   not with :has(), which has zero precedent in the shared sheet and which
   Safari <15.4 drops entirely. */
.v2x.evx .dir-tc-logo.evx-plate,
.v2x.evx .dir-lc-logo.evx-plate{ position:relative; }

.v2x.evx .evx-plate.has-live{
  background:#FEECEF;
  box-shadow:inset 0 0 0 1px #FBD2DA;
}
body.theme-dark .v2x.evx .evx-plate.has-live{
  background:rgba(244,63,94,.18);
  box-shadow:inset 0 0 0 1px rgba(251,113,133,.30);
}

.v2x.evx .evx-dp.is-demand{ gap:3px; }

/* The list-mode plate is 52px (48 at ≤820, 44 at ≤520) — the grid ramp does
   not fit, so it gets its own. */
.v2x.evx .dir-lc .evx-dp-d{ font-size:20px; }
.v2x.evx .dir-lc .evx-dp-m{ font-size:9px; letter-spacing:.08em; }
.v2x.evx .dir-lc .evx-dp-lbl{ font-size:8px; }
.v2x.evx .dir-lc .evx-dp svg{ width:18px; height:18px; }
.v2x.evx .dir-lc .evx-dp-pulse{ width:8px; height:8px; }


/* ═══ §FLAG — featured / cancelled ribbon ══════════════════════════════════
   Absolute and flush to the corner rather than an inline pill, so it never
   pushes the title down and never competes with the bookmark button on the
   opposite corner. Cancelled outranks featured — an event that is not
   happening is the only thing worth flagging about it.
   ────────────────────────────────────────────────────────────────────────── */
.v2x.evx .evx-flag{
  position:absolute; top:10px; left:10px; z-index:3;
  display:inline-flex; align-items:center; gap:4px;
  padding:3px 8px; border-radius:99px;
  font-size:9.5px; font-weight:800; letter-spacing:.05em; text-transform:uppercase;
  color:#A85B08; background:#FEF4E4; box-shadow:inset 0 0 0 1px #FBE3C0;
  pointer-events:none;
}
.v2x.evx .evx-flag svg{ width:11px; height:11px; }
.v2x.evx .evx-flag.is-cancel{
  color:#B3122B; background:#FEECEF; box-shadow:inset 0 0 0 1px #FBD2DA;
}
body.theme-dark .v2x.evx .evx-flag{
  color:#FBC97A; background:rgba(245,158,11,.18); box-shadow:inset 0 0 0 1px rgba(251,191,36,.30);
}
body.theme-dark .v2x.evx .evx-flag.is-cancel{
  color:#FB9BB0; background:rgba(244,63,94,.18); box-shadow:inset 0 0 0 1px rgba(251,113,133,.30);
}
/* In list mode the row has no free corner, so the same chip goes inline in
   the title row instead of being positioned. */
.v2x.evx .evx-flag.is-inline{ position:static; pointer-events:auto; }


/* ═══ §PILL — an icon inside the shared type pill ══════════════════════════
   `.dir-tc-pill` ships with no gap (its only child is text). Adding the glyph
   without one runs the icon into the first letter.
   ────────────────────────────────────────────────────────────────────────── */
.v2x.evx .dir-tc-pill{ gap:4px; }
.v2x.evx .dir-tc-pill svg{ width:12px; height:12px; flex:0 0 auto; opacity:.9; }


/* ═══ §FACT — the icon+figure facts ════════════════════════════════════════ */
.v2x.evx .evx-fact{
  display:inline-flex; align-items:center; gap:5px;
  min-width:0; max-width:100%;
  font-size:11.5px; font-weight:640; color:var(--v2-muted);
  font-variant-numeric:tabular-nums;
}
.v2x.evx .evx-fact svg{ width:13px; height:13px; flex:0 0 auto; opacity:.8; }
/* min-width:0 alone is not enough on an inline-flex child — the TEXT node
   needs its own shrinkable box or a long venue name refuses to ellipse. */
.v2x.evx .evx-fact-tx{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.v2x.evx .evx-fact time{ white-space:nowrap; }
body.theme-dark .v2x.evx .evx-fact{ color:#9CA2B3; }

/* Scarcity. Colour reinforces the warning triangle; it is never alone. */
.v2x.evx .evx-fact.is-warn{ color:#A85B08; font-weight:720; }
body.theme-dark .v2x.evx .evx-fact.is-warn{ color:#FBC97A; }

.v2x.evx .evx-meta{ row-gap:6px; }


/* ═══ §FOOT — price + CTA ══════════════════════════════════════════════════
   `.dir-tc-btn` carries `margin-top:auto` in the shared sheet, which is what
   pins it to the foot of a card. Wrapping it in a row moves that job to the
   row, so the button's own auto is cancelled here — leave both and the button
   pushes itself to the bottom of a one-line flex container, which does
   nothing visible but makes the next spacing change behave strangely.
   ────────────────────────────────────────────────────────────────────────── */
.v2x.evx .evx-foot{
  display:flex; align-items:center; gap:10px;
  width:100%; margin-top:auto; padding-top:14px;
}
.v2x.evx .evx-foot .dir-tc-btn{ margin-top:0; width:auto; flex:1 1 auto; min-width:0; }


/* ═══ §PRICE ═══════════════════════════════════════════════════════════════
   Reads the same in both themes without depending on the card's cycled tone:
   a price is a fact about the event, not a decorative slot.
   ────────────────────────────────────────────────────────────────────────── */
.v2x.evx .evx-price{
  display:inline-flex; align-items:center; gap:5px; flex:0 0 auto;
  padding:6px 11px; border-radius:11px;
  font-size:12.5px; font-weight:760; letter-spacing:-.005em; white-space:nowrap;
  color:var(--v2-ink); background:#F1F3F8; box-shadow:inset 0 0 0 1px rgba(16,24,40,.05);
  font-variant-numeric:tabular-nums;
}
.v2x.evx .evx-price svg{ width:13px; height:13px; opacity:.75; }
.v2x.evx .evx-price.is-free{
  color:#08795A; background:#E6F8F1; box-shadow:inset 0 0 0 1px #C6EEDF;
}
.v2x.evx .evx-price.is-free svg{ opacity:1; }
body.theme-dark .v2x.evx .evx-price{
  color:var(--v2-ink); background:rgba(255,255,255,.06); box-shadow:inset 0 0 0 1px rgba(255,255,255,.05);
}
body.theme-dark .v2x.evx .evx-price.is-free{
  color:#6EE7BE; background:rgba(16,185,129,.18); box-shadow:inset 0 0 0 1px rgba(52,211,153,.30);
}
/* In list mode the side column stacks; the price sits above the CTA. */
.v2x.evx .dir-lc-side .evx-price{ font-size:12px; padding:5px 10px; }


/* ═══ §TILE — an SVG in a hero orbit tile ══════════════════════════════════
   `.dir-hh-tile img` is sized in the shared sheet; the tiles here hold inline
   SVG (an event category has no logo file), which that rule cannot reach.
   ────────────────────────────────────────────────────────────────────────── */
.v2x.evx .dir-hh-tile > svg{
  width:100%; height:100%; display:block;
  color:var(--brand-blue); opacity:.92;
}
body.theme-dark .v2x.evx .dir-hh-tile > svg{ color:var(--brand-blue-light); }


/* ═══ §MONO — an SVG in a rail logo plate ══════════════════════════════════
   `.dir-tr-mono` / `.dir-tc-mono` are sized for a single monogram LETTER
   (26px/800). An SVG inheriting a font-size renders at its intrinsic box and
   overflows the 34px plate.
   ────────────────────────────────────────────────────────────────────────── */
.v2x.evx .dir-tr-mono svg{ width:18px; height:18px; display:block; }
.v2x.evx .dir-tc-mono svg{ width:28px; height:28px; display:block; }
.v2x.evx .dir-lc-mono svg{ width:22px; height:22px; display:block; }


/* ═══ §SHELF — the curated admin bands ═════════════════════════════════════
   `ev_hub_sections` renders between the result grid and the category rail.
   A shelf is the same `.dir-cards` grid, so it needs no layout of its own —
   only a tighter top rhythm than a full section, or three shelves in a row
   read as three separate pages.
   ────────────────────────────────────────────────────────────────────────── */
.v2x.evx .evx-shelf{ padding-top:6px; }
.v2x.evx .evx-shelf + .evx-shelf{ padding-top:0; }
.v2x.evx .evx-shelf-cta{ display:flex; justify-content:center; margin-top:20px; }
.v2x.evx .evx-shelf-cta .dir-tr-more{ width:auto; min-width:min(320px,100%); }


/* ═══ §TYPE — the browse-by-format pill row ════════════════════════════════
   A pill row, not a second card rail: two identical rails one above the other
   reads as a repeat, and a format ("Webinar", "Hackathon") is a one-word idea
   that does not need a description or a card.

   The tone lands on the ICON PLATE and the count, never on the label text —
   the ten `.dir-tc-pill` tones are calibrated as INK ON A TINT at pill size,
   and at 14px label weight the lighter ones (amber, cyan) would sit under
   4.5:1 on the card surface.
   ────────────────────────────────────────────────────────────────────────── */
/* The band sits directly under the category rail, so it takes a tighter
   top rhythm than a standalone section — at full section padding the two
   read as unrelated pages rather than two ways into the same catalogue. */
.v2x.evx .evx-typeband{ padding-top:6px; }

.v2x.evx .evx-typerow{
  display:flex; flex-wrap:wrap; gap:10px;
  justify-content:center;
}
.v2x.evx .evx-typepill{
  --evx-t-ink:#1B5BB5; --evx-t-bg:#EAF2FD; --evx-t-line:#CFE0FA;
  display:inline-flex; align-items:center; gap:9px; min-width:0;
  padding:9px 14px 9px 10px; border-radius:99px;
  background:#fff; border:1px solid var(--v2-line);
  color:var(--v2-ink); text-decoration:none;
  font-size:13.5px; font-weight:700; letter-spacing:-.008em;
  box-shadow:0 1px 2px rgba(16,24,40,.04);
  transition:transform .2s var(--ease-out), border-color .2s ease, box-shadow .22s ease;
}
.v2x.evx .evx-typepill[data-tone="blue"]   {--evx-t-ink:#1B5BB5;--evx-t-bg:#EAF2FD;--evx-t-line:#CFE0FA}
.v2x.evx .evx-typepill[data-tone="violet"] {--evx-t-ink:#5B33C4;--evx-t-bg:#F0EBFE;--evx-t-line:#DED2FB}
.v2x.evx .evx-typepill[data-tone="indigo"] {--evx-t-ink:#3540B0;--evx-t-bg:#EBEEFE;--evx-t-line:#D3D9FB}
.v2x.evx .evx-typepill[data-tone="rose"]   {--evx-t-ink:#B31D3C;--evx-t-bg:#FEECEF;--evx-t-line:#FBD2DA}
.v2x.evx .evx-typepill[data-tone="amber"]  {--evx-t-ink:#A85B08;--evx-t-bg:#FEF4E4;--evx-t-line:#FBE3C0}
.v2x.evx .evx-typepill[data-tone="emerald"]{--evx-t-ink:#08795A;--evx-t-bg:#E6F8F1;--evx-t-line:#C6EEDF}
.v2x.evx .evx-typepill[data-tone="cyan"]   {--evx-t-ink:#0A6E88;--evx-t-bg:#E4F6FB;--evx-t-line:#C2E9F4}
.v2x.evx .evx-typepill[data-tone="teal"]   {--evx-t-ink:#0B6B63;--evx-t-bg:#E3F7F4;--evx-t-line:#C1EDE7}
.v2x.evx .evx-typepill[data-tone="orange"] {--evx-t-ink:#B4500C;--evx-t-bg:#FEF0E6;--evx-t-line:#FBD9C2}
.v2x.evx .evx-typepill[data-tone="slate"]  {--evx-t-ink:#41506B;--evx-t-bg:#EEF1F6;--evx-t-line:#D8DEE9}

/* Dark twins are load-bearing, not polish: every -ink above is a DARK tone
   chosen for a white surface. On the night panel it measures ~2:1. */
body.theme-dark .v2x.evx .evx-typepill{
  --evx-t-ink:#8CBEFA; --evx-t-bg:rgba(54,128,237,.18); --evx-t-line:rgba(96,164,245,.28);
  background:rgba(28,31,42,.9); border-color:rgba(255,255,255,.08);
  box-shadow:0 1px 2px rgba(0,0,0,.4);
}
body.theme-dark .v2x.evx .evx-typepill[data-tone="violet"] {--evx-t-ink:#BFA6FB;--evx-t-bg:rgba(124,77,240,.18);--evx-t-line:rgba(160,120,250,.30)}
body.theme-dark .v2x.evx .evx-typepill[data-tone="indigo"] {--evx-t-ink:#A9B2FB;--evx-t-bg:rgba(79,70,229,.18);--evx-t-line:rgba(129,140,248,.30)}
body.theme-dark .v2x.evx .evx-typepill[data-tone="rose"]   {--evx-t-ink:#FB9BB0;--evx-t-bg:rgba(244,63,94,.18);--evx-t-line:rgba(251,113,133,.30)}
body.theme-dark .v2x.evx .evx-typepill[data-tone="amber"]  {--evx-t-ink:#FBC97A;--evx-t-bg:rgba(245,158,11,.18);--evx-t-line:rgba(251,191,36,.30)}
body.theme-dark .v2x.evx .evx-typepill[data-tone="emerald"]{--evx-t-ink:#6EE7BE;--evx-t-bg:rgba(16,185,129,.18);--evx-t-line:rgba(52,211,153,.30)}
body.theme-dark .v2x.evx .evx-typepill[data-tone="cyan"]   {--evx-t-ink:#7CD9EE;--evx-t-bg:rgba(6,182,212,.18);--evx-t-line:rgba(34,211,238,.30)}
body.theme-dark .v2x.evx .evx-typepill[data-tone="teal"]   {--evx-t-ink:#79DDD5;--evx-t-bg:rgba(20,184,166,.18);--evx-t-line:rgba(45,212,191,.30)}
body.theme-dark .v2x.evx .evx-typepill[data-tone="orange"] {--evx-t-ink:#FBB07A;--evx-t-bg:rgba(249,115,22,.20);--evx-t-line:rgba(251,146,60,.32)}
body.theme-dark .v2x.evx .evx-typepill[data-tone="slate"]  {--evx-t-ink:#B4BCCC;--evx-t-bg:rgba(148,163,184,.18);--evx-t-line:rgba(203,213,225,.26)}

.v2x.evx .evx-typepill-ico{
  display:inline-grid; place-items:center; flex:0 0 auto;
  width:30px; height:30px; border-radius:50%;
  background:var(--evx-t-bg); color:var(--evx-t-ink);
  box-shadow:inset 0 0 0 1px var(--evx-t-line);
  transition:transform .24s var(--ease-spring);
}
.v2x.evx .evx-typepill-ico svg{ width:16px; height:16px; display:block; }
.v2x.evx .evx-typepill-nm{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.v2x.evx .evx-typepill-cnt{
  flex:0 0 auto; padding:2px 8px; border-radius:99px;
  background:var(--evx-t-bg); color:var(--evx-t-ink);
  font-size:11px; font-weight:800; font-variant-numeric:tabular-nums;
  box-shadow:inset 0 0 0 1px var(--evx-t-line);
}
/* A topic pill carries no icon and no tone — tags have no colour of their own
   in this schema, and inventing one per tag is a colour that means nothing. */
.v2x.evx .evx-typepill.is-tag{ padding-left:14px; }

@media (hover:hover){
  .v2x.evx .evx-typepill:hover{
    transform:translateY(-2px);
    border-color:var(--evx-t-line);
    box-shadow:0 12px 24px -14px rgba(16,24,40,.4);
    text-decoration:none; color:var(--v2-ink);
  }
  .v2x.evx .evx-typepill:hover .evx-typepill-ico{ transform:scale(1.08); }
  body.theme-dark .v2x.evx .evx-typepill:hover{ box-shadow:0 12px 24px -14px rgba(0,0,0,.8); color:var(--v2-ink); }
}
.v2x.evx .evx-typepill:focus-visible{
  outline:none; border-color:var(--evx-t-ink);
  box-shadow:0 0 0 3px var(--evx-t-line);
}

/* The two labelled axes on /events/categories. */
.v2x.evx .evx-axis + .evx-axis{ margin-top:26px; }
.v2x.evx .evx-axis-h{
  display:flex; align-items:center; justify-content:center; gap:7px;
  margin:0 0 14px;
  font-size:12px; font-weight:800; letter-spacing:.09em; text-transform:uppercase;
  color:var(--v2-muted);
}
.v2x.evx .evx-axis-h svg{ width:15px; height:15px; opacity:.8; }
body.theme-dark .v2x.evx .evx-axis-h{ color:#9CA2B3; }


/* ═══ §CATGRID — /events/categories ════════════════════════════════════════
   The same `.dir-cat-card`, laid out as a WRAPPING GRID rather than the
   horizontal snap rail, because seeing every category at once is the entire
   point of that page.

   The rail sets a fixed grid-auto-column and scroll-snap on the card; neither
   applies in a wrapping grid, and `scroll-snap-align` on a non-scroll parent
   is inert but confusing to read, so both are unset explicitly.
   ────────────────────────────────────────────────────────────────────────── */
.v2x.evx .evx-catgrid{
  display:grid; gap:18px;
  grid-template-columns:repeat(auto-fill, minmax(min(250px,100%), 1fr));
}
.v2x.evx .evx-catgrid .dir-cat-card{
  scroll-snap-align:none;
  width:auto; height:100%;
}
/* A category with nothing scheduled is SHOWN, not hidden — it is a real,
   crawlable URL. It is just quieter, so the band above stays the answer to
   "what can I actually go to". */
.v2x.evx .evx-catgrid.is-soon .dir-cat-card{ opacity:.82; }
@media (hover:hover){
  .v2x.evx .evx-catgrid.is-soon .dir-cat-card:hover{ opacity:1; }
}
.v2x.evx .evx-soon{ padding-top:4px; }


/* ═══ §CRUMB ═══════════════════════════════════════════════════════════════ */
.v2x.evx .evx-crumbs{
  display:flex; align-items:center; flex-wrap:wrap; gap:4px;
  list-style:none; margin:0 auto; padding:18px 24px 0;
  max-width:1320px;
  font-size:12.5px; color:var(--v2-muted);
}
.v2x.evx .evx-crumbs li{ display:inline-flex; align-items:center; gap:4px; min-width:0; }
.v2x.evx .evx-crumbs a{ color:var(--v2-muted); text-decoration:none; transition:color .18s ease; }
.v2x.evx .evx-crumbs a:hover{ color:var(--brand-blue); text-decoration:underline; }
.v2x.evx .evx-crumbs svg{ opacity:.45; flex:0 0 auto; }
.v2x.evx .evx-crumbs [aria-current="page"]{
  color:var(--v2-ink); font-weight:700;
  min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
body.theme-dark .v2x.evx .evx-crumbs,
body.theme-dark .v2x.evx .evx-crumbs a{ color:#9CA2B3; }
body.theme-dark .v2x.evx .evx-crumbs a:hover{ color:var(--brand-blue-light); }
body.theme-dark .v2x.evx .evx-crumbs [aria-current="page"]{ color:var(--v2-ink); }


/* ═══ §HERE — "you are here" ═══════════════════════════════════════════════
   The current term stays in the sibling rail rather than being removed:
   dropping it makes the rail jump between pages and loses the reader's place.
   It needs to be visibly the current one, or it reads as a link to the page
   you are already on.
   ────────────────────────────────────────────────────────────────────────── */
.v2x.evx .dir-tr-row.is-here{
  background:var(--v2-accent-soft);
  box-shadow:inset 2px 0 0 var(--brand-blue);
}
.v2x.evx .dir-tr-row.is-here .dir-tr-nm{ color:var(--brand-blue-dark); font-weight:800; }
body.theme-dark .v2x.evx .dir-tr-row.is-here{
  background:rgba(54,128,237,.14);
  box-shadow:inset 2px 0 0 var(--brand-blue-light);
}
body.theme-dark .v2x.evx .dir-tr-row.is-here .dir-tr-nm{ color:var(--brand-blue-light); }

.v2x.evx .dir-cat-card.is-here{
  border-color:var(--dtc-line);
  box-shadow:0 0 0 2px var(--dtc-line), 0 10px 24px -20px rgba(16,24,40,.22);
}
.v2x.evx .dir-cat-card.is-here .dir-cat-card-nm{ color:var(--dtc-ink); }
body.theme-dark .v2x.evx .dir-cat-card.is-here{
  box-shadow:0 0 0 2px var(--dtc-line), 0 10px 24px -20px rgba(0,0,0,.65);
}


/* ═══ §BUSY ════════════════════════════════════════════════════════════════
   `wire:loading.class="is-busy"` lands a class that NO sheet in this stack
   defines — sixth module in a row to hit this. `pointer-events:none` matters
   as much as the dim: mid-filter the rows on screen are the OLD result set,
   and a click lands on a card that is about to be replaced.
   ────────────────────────────────────────────────────────────────────────── */
.v2x.evx .is-busy{
  opacity:.45; pointer-events:none;
  transition:opacity .18s ease;
}


/* ═══ §IOS ═════════════════════════════════════════════════════════════════
   `.dir-hh-search input` is 15.5px in the SHARED sheet (14px under 820px), so
   iOS Safari zooms the viewport on focus and the reader has to pinch back out.
   Pinned to 16px here, scoped to `.v2x.evx` only: raising it in the shared
   sheet would reflow six pages that have not been re-verified.
   ⚠ THE SHARED MISS IS REAL AND STILL WANTS ITS OWN PASS — /ai-directory,
     /browser-extensions, /gpts, /workflows, /ai-projects and /cheat-sheet all
     still trigger it.
   ────────────────────────────────────────────────────────────────────────── */
.v2x.evx .dir-hh-search input{ font-size:16px; }
@media (max-width:820px){
  .v2x.evx .dir-hh-search input{ font-size:16px; }
}


/* ═══ §RESP ════════════════════════════════════════════════════════════════
   Aligned to the shared sheet's own ladder — see the header note.
   ────────────────────────────────────────────────────────────────────────── */
@media (max-width:1180px){
  .v2x.evx .evx-catgrid{ grid-template-columns:repeat(auto-fill, minmax(min(230px,100%), 1fr)); gap:16px; }
}

@media (max-width:820px){
  .v2x.evx .evx-crumbs{ padding:14px 18px 0; font-size:12px; }
  .v2x.evx .evx-catgrid{ grid-template-columns:repeat(auto-fill, minmax(min(210px,100%), 1fr)); gap:14px; }
  .v2x.evx .evx-typerow{ gap:8px; }
  .v2x.evx .evx-typepill{ font-size:12.5px; padding:8px 12px 8px 9px; }
  .v2x.evx .evx-typepill-ico{ width:26px; height:26px; }
  .v2x.evx .evx-typepill-ico svg{ width:14px; height:14px; }

  /* The list row's side column stacks at this width in the shared sheet; the
     price goes above the CTA rather than beside it. */
  .v2x.evx .dir-lc-side{ gap:6px; }
  .v2x.evx .dir-lc-side .evx-price{ font-size:11px; padding:4px 8px; }
}

@media (max-width:640px){
  /* The plate keeps its 66px box down to the smallest card, so the date ramp
     does not need to shrink — but the FOOT does: at 360px a price badge and a
     full-width CTA on one line leaves the button ~90px wide. */
  .v2x.evx .evx-foot{ flex-direction:column; align-items:stretch; gap:8px; }
  .v2x.evx .evx-foot .evx-price{ justify-content:center; }
  .v2x.evx .evx-foot .dir-tc-btn{ width:100%; }
}

@media (max-width:520px){
  .v2x.evx .evx-crumbs{ padding:12px 14px 0; }
  .v2x.evx .evx-catgrid{ grid-template-columns:1fr; }
  .v2x.evx .evx-typerow{ justify-content:flex-start; }
  .v2x.evx .evx-typepill{ font-size:12px; }
  .v2x.evx .evx-typepill-nm{ max-width:150px; }
  .v2x.evx .dir-lc .evx-dp-d{ font-size:18px; }
  .v2x.evx .dir-lc .evx-dp-m{ font-size:8.5px; }
}

@media (max-width:400px){
  /* Two chips per line rather than one long one — a single wrapped fact row
     is taller than the card body it describes. */
  .v2x.evx .evx-meta{ gap:6px; }
  .v2x.evx .evx-fact{ font-size:11px; }
  .v2x.evx .evx-flag{ font-size:9px; padding:2px 6px; }
}


/* ═══ §MOTION ══════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce){
  .v2x.evx .evx-dp-pulse{ animation:none; }
  .v2x.evx .evx-typepill,
  .v2x.evx .evx-typepill-ico,
  .v2x.evx .is-busy{ transition:none; }
  .v2x.evx .evx-typepill:hover{ transform:none; }
}
