Skip to content

chore(deps): Bump actions/setup-node from 4 to 6 - #2

Open
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/github_actions/actions/setup-node-6
Open

chore(deps): Bump actions/setup-node from 4 to 6#2
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/github_actions/actions/setup-node-6

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Mar 4, 2026

Copy link
Copy Markdown

Bumps actions/setup-node from 4 to 6.

Release notes

Sourced from actions/setup-node's releases.

v6.0.0

What's Changed

Breaking Changes

Dependency Upgrades

Full Changelog: actions/setup-node@v5...v6.0.0

v5.0.0

What's Changed

Breaking Changes

This update, introduces automatic caching when a valid packageManager field is present in your package.json. This aims to improve workflow performance and make dependency management more seamless. To disable this automatic caching, set package-manager-cache: false

steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
  with:
    package-manager-cache: false

Make sure your runner is on version v2.327.1 or later to ensure compatibility with this release. See Release Notes

Dependency Upgrades

New Contributors

Full Changelog: actions/setup-node@v4...v5.0.0

v4.4.0

... (truncated)

Commits

Dependabot compatibility score

You can trigger a rebase of this PR by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Note
Automatic rebases have been disabled on this pull request as it has been open for over 30 days.

Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 6.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](actions/setup-node@v4...v6)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file github_actions Pull requests that update GitHub Actions code labels Mar 4, 2026
rodanaya added a commit that referenced this pull request Apr 24, 2026
…ion detector

Tier 1 #2 from the ultrathink plan. The anti-model page: no logistic
regression, no SHAP, no PU-learning. Just arithmetic on COMPRANET.

For every federal institution × year 2018-2025, sum each vendor's
contracts, divide by that year's institution total, and detect
monotonic growth curves where the vendor's share jumped from ≤ 25%
to ≥ 50% across at least 4 observed years.

## Why this page exists

The /intersection page proves RUBLI's model novelty. This page proves
something different: there are findings that don't need a model at
all — they're deterministic arithmetic on public contract awards. Every
row is a publishable journalism finding of the form:

  "Over N years, Vendor X grew from A% to B% of Institution Y's
   procurement. Neither RUBLI nor external registries flag this —
   but the numbers don't lie."

## Live findings from the smoke test (13 captures)

  1. EDUARDO SERNA ROBLES → ASIPONA Salina Cruz: 4.6%→76.3% (4.23B MXN)
  2. IGT MÉXICO LOTTERY → LOTERIA: 3.0%→76.6% (3.05B)
  3. SCONTINUIDAD LATAM → INSTITUTO POTOSINO: 12.5%→75.7%
  4. EDENRED MEXICO → SPF: 3.9%→70.0%
  5. OPERADORA COMEDORES SALUDABLES → CONACULTA: 12.8%→57.1%
  6. TOKA INTERNACIONAL → CIJ, INAL (appears twice — known GT case)
  ...

Each of these is immediately checkable via the underlying COMPRANET
records.

## Implementation

- backend/api/routers/capture.py (253 LOC)
  - `GET /api/v1/capture/top?limit=50[&sector_id=N]`
  - Single SQL pass with CTE to build (inst, vendor, year) vendor-share
    matrix, then Python filters for monotonic 25%→50% curves with
    ≥ 4 years of data, ≥ 50M captured, institution ≥ 100M total
  - Score = Δshare × √(captured_value_MXN)
  - Cached 30 min (TTL); cold query ~6.8s, warm <30ms
- frontend/src/pages/CaptureCreep.tsx (290 LOC)
  - Editorial row layout: rank + SVG sparkline (with 50% capture line
    visualized as dashed rule) + narrative sentence ("Vendor X
    captured Institution Y — from A% in year1 to B% in year2")
  - Click-through to vendor/institution profiles
  - Methodology caveat + threshold transparency
- frontend/src/api/client.ts — captureApi + DTOs
- Route: /capture (new entry in sidebar INVESTIGATE section, between
  Intersection and Cases). Sidebar now 9 items.
- EN/ES i18n keys added.

## Verification

- npx tsc --noEmit: 0 errors
- npm run build: succeeded (33.69s)
- Live smoke against prod DB: 13 captures returned, all with
  publishable narratives

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
rodanaya added a commit that referenced this pull request Apr 26, 2026
The memo panel is now visible on every Vendor Profile (P2.5 surfaced it
in commit 30aa00e). Its TierBadge was using bg-red-600/20, bg-orange-600/20,
bg-yellow-600/20, bg-blue-600/20 — non-canonical colors that escaped the
token gate but violate v3.0 hard rule #2 (risk tokens via @/lib/constants).

Fixed: T1→risk-critical, T2→risk-high, T3→risk-medium, T4→text-muted.
Also tightened label "Tier 1" → "T1" with mono uppercase tracking to
match the EntityIdentityChip tier-badge grammar.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
rodanaya added a commit that referenced this pull request Apr 29, 2026
Improvement-table batch — small, high-leverage UI corrections from
the alignment plan. Each is independent.

#3 — RISK FLOOR / RIESGO MÍNIMO label (Atlas.tsx)
  • Was: "X-RAY / RAYOS X" — niche jargon, doesn't read naturally
  • Now: "RISK FLOOR / RIESGO MÍNIMO" — matches the existing
    aria-label "Risk floor filter / Filtro mínimo de riesgo"
  • One-line rename, no behavior change

#6 — In-bar long-form CTA on the playback bar (Atlas.tsx)
  • Adds a small <FileText> chip next to the story title in the
    playback bar, label "FULL / COMPLETA" on sm+ viewports
  • Only renders when activeStory.longformSlug is set (i.e. the
    tour has a paired /stories long-form — currently 2 of 3
    tours: pharma_cartel + estafa_maestra)
  • Opens /stories/<slug> in a new tab so the playing tour state
    persists; readers don't have to wait for the end-card if they
    already know they want the article
  • Click stops propagation to keep the playback bar in place

#9 — Dashboard mini-Observatory "Open full Observatory" footer
  (Executive.tsx)
  • Adds a small <ArrowUpRight> link below the embedded
    constellation in "§ 1 · The Observatory" section
  • Preserves the active lens via ?lens=<atlasMode> when not
    'patterns' (default lens — no param needed)
  • Pure additive — no change to the embedded mini-constellation

Imports added: Link from react-router-dom in both files (Atlas.tsx
already had useNavigate; Executive.tsx already had ArrowUpRight).

Skipped from the improvement table for this commit:
  • #2 vendor search index expansion — needs editorial-data work
    to curate the next 20–30 vendors from recent commits
  • #4 COMPARE YEARS coachmark — needs design call (location,
    persistence, dismiss behavior)
  • #7 X close state preservation — already preserved (the
    URL-sync effect carries lens/year/pin through close)
  • #10 "as of {date}" timestamp on story hero — small but needs
    a separate decision about whether story freshness should be
    surfaced editorially or not
  • #1 Stories button label clarity — replaced indirectly by the
    Tier-2 #7 footer link "Long-form investigations · P3" which
    is more informative than "Stories"

Verified live in browser preview:
  • /atlas?story=pharma_cartel shows the new "FULL" chip in the
    playback bar (sm+ viewport)
  • Risk-floor row reads "RISK FLOOR" not "X-RAY"; "X-RAY" /
    "RAYOS X" no longer appears anywhere
  • Dashboard renders "Open full Observatory" link below the
    embedded constellation, routes to /atlas

Gates: tsc clean, build clean (37s), lint:tokens 0 forbidden,
warnings unchanged from prior commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
rodanaya added a commit that referenced this pull request Apr 29, 2026
Three remaining items from the improvement table.

#4 — COMPARE YEARS discoverability hint (Atlas.tsx)
  • The toggle was visually clear but its function wasn't —
    "Compare years" doesn't tell you the button renders a second
    constellation
  • Adds a title attr (native browser tooltip) explaining "Render
    a second constellation alongside this one. Pick a year for
    each canvas to see the same lens at two moments in time —
    e.g. Peña 2014 vs COVID 2020."
  • Adds a more descriptive aria-label
  • No visual change — discoverability via hover/focus only

#2 — Vendor search index 21 → 42 (Atlas.tsx)
  Expanded the curated KNOWN_VENDORS list with named vendors
  surfaced across the long-form stories and recent commits in
  this branch:

  Pharma cartel cluster (full set):
    • Maypo · DIMM (PISA already present)

  P3 intermediaries — pass-through signatures:
    • Constructora ARHNOS · Promotora y Desarrolladora MX
    • CAABSA Constructora · GX2 Desarrollos
    • Técnicas Reunidas (legitimate sole-source contrast)
    • Pride International (legitimate sole-source PEMEX)

  Tech-license direct-award cluster (defensible sole-source):
    • Microsoft (Corp/Licensing/Mexico combined) · Oracle · IBM

  Government media buys (red — non-competitive):
    • Televisa · Estudios Azteca

  DICONSA staple-commodity supply chain:
    • Molinos Azteca · Marcas Nestlé

  Voucher cluster (welfare-program payment-card monopolies):
    • Efectivale · Sodexo · Segalmex (TOKA, Edenred already)

  Tren Maya / large-contract risk:
    • ICA Constructora · Alstom Transport

  Methodology hint copy updated to reflect the new count and
  cluster categories ("42 known cases — pharma cartel, P3
  intermediaries, tech-license cluster, gov media buys,
  DICONSA staples, voucher monopolies").

#10 — Analysis-as-of timestamp on story hero (StoryNarrative.tsx)
  • Adds a small mono-font "Analysis as of April 2026 / Análisis
    a abril de 2026" chip in the byline row, alongside the
    existing chapter count
  • title attr explains the editorial-honesty point: "Stories
    are static analyses of a COMPRANET snapshot dated through
    this period. Live data updates in the Observatory and ARIA
    queue, not in the story body."
  • Single hardcoded date for now (matches v0.6.5 model rescore
    + ARIA pipeline run on Mar 25 2026); a future iteration
    could thread per-story analysisDate via the StoryDef schema

Improvement table items now closed in this branch:
  ✅ #1 STORIES button label (replaced via Tier-2 #7 footer)
  ✅ #2 vendor index (this commit)
  ✅ #3 RISK FLOOR rename (da17e08)
  ✅ #4 COMPARE YEARS hint (this commit)
  ✅ #5 i18n audit (already correct, verified)
  ✅ #6 in-bar long-form CTA (da17e08)
  ✅ #7 X close state preservation (already preserved)
  ✅ #8 Newsroom card tour badge (Tier-1)
  ✅ #9 Dashboard Observatory footer link (da17e08)
  ✅ #10 Story timestamp (this commit)
  ✅ #11 Dashboard KPI anchors (Tier-2 #8)
  ✅ #12 atlas-tour brand parity (ca902d1)

Verified live: /stories/marea-de-adjudicaciones renders the
"Analysis as of April 2026" chip in the byline row.

Gates: tsc clean, build clean (34s), lint:tokens 0 forbidden,
warnings unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
rodanaya added a commit that referenced this pull request May 4, 2026
Pattern #2 — Annotated TemporalRiskChart:
  - Admin era bands (Calderón/Peña/AMLO/Sheinbaum) via ReferenceArea + label
  - EditorialComposedChart: band annotations now support insideTopLeft label
  - Scandal legend → editorial callout cards (year chip + label grid)
  - Narrative title: "Risk patterns have barely shifted in 15 years"

Pattern #3 — Sector small multiples grid (4×3):
  - SectorSmallMultiples component: all 12 sectors, shared Y scale
  - Mini 72px AreaChart per sector, sector-color gradient fill
  - Sorted worst-first (top-left = highest risk, as eye lands)
  - Trend arrow + current % below each panel

Pattern #6 — Diverging vendor benchmark bars (FT Deviation pattern):
  - VendorBenchmarkBars component at top of EvidenceTab
  - Direct award, single-bid, high-risk vs OECD limits (30%/10%/11%)
  - Year-end concentration vs sector average when available
  - Bars right = above limit (crimson), left = below (zinc) — "compared to what?" answered instantly

Pattern #10 — Sledgehammer stat for story chapter 1:
  - DataPullquote: new sledgehammer prop (4.5–7rem stat vs 2.4–3.6rem default)
  - Number first, quote demoted below — Pudding opening structure
  - Auto-applied to chapter idx=1 (first data chapter after hero) in StoryNarrative

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
rodanaya added a commit that referenced this pull request May 4, 2026
…ndors, value-concentration

Three independent bugs surfacing as 500/503 on rubli.xyz (audit at
docs/PROD_BROKEN_AUDIT_2026_05_04.md):

1. **GET /sectors/{id}/model-coefficients** — was 500
   v0.8.5 calibration stores coefficients as parallel arrays
   {names: [...], values: [...]} instead of v6.0's flat {name: coef}
   dict. The sort lambda called abs() on a list and crashed.
   Fix: detect both shapes, normalize to (name, coef) pairs, coerce
   to float defensively before sorting.

2. **GET /analysis/flash-vendors** — was 503
   SQL referenced i.institution_name but the institutions table column
   is named 'name'. Same with v.vendor_name → v.name.
   Fix: column rename in two CTEs of analysis_vendor_sector.py.

3. **GET /analysis/value-concentration** — was 503
   Same pattern as #2; the second CTE in primary_inst.

Backend tests: 52/52 pass.

Audit: docs/PROD_BROKEN_AUDIT_2026_05_04.md
Build: 2026-05-04-p1-bugfix

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
rodanaya added a commit that referenced this pull request May 4, 2026
Implements docs/CATEGORIES_REDESIGN_PLAN.md HERO 2: Cleveland-pair of
#1 vs #2 vendor share over the 12 most-captured categories, sorted by
gap descending. The dollar gap *is* the editorial story — the wider
the dumbbell, the more captured the market.

FT/Pudding "Trolley Problem" Cleveland-pair vocabulary.

Data path: fan-out approach — one getTopVendors(catId, 2) call per
top-12-by-spend category (≥1B MXN filter) via Promise.all inside a
single useQuery with 5-minute staleTime. No new backend endpoint needed;
categoriesApi.getTopVendors already exists at client.ts L2129. 12
round-trips are cheap under cache; backend endpoint can be added later
as cat-P2.1 nicety if tab-switch latency is measured.

Pull-quote on the widest dumbbell. "MERCADO CAPTURADO" pill for any
category where #1 share > 75%. Connector bar thickness encodes category
total_value (clamp 1.5–4px). All entity refs via EntityIdentityChip;
all vendor names via formatVendorName. Pure SVG, no recharts.

Spanish primary copy, English fallback. i18n keys added under
categories.dumbbell namespace in both locale files.

Plan: docs/CATEGORIES_REDESIGN_PLAN.md
Build: 2026-05-04-cat-p2

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
rodanaya added a commit that referenced this pull request May 7, 2026
Established the loop-killing protocol the user asked for:
  - Issues filed by ID (Issue #N) or 'New issue:' prefix
  - I assign severity + acceptance criteria, you negotiate once
  - Tickets close with commit SHA + one-line 'fixed by'
  - New ideas that aren't blocking go to v1.1 candidates section
    (untouched until 2026-06-14)

Opened tickets (10):
  #1 P1  /categories/:id institutional ranking skewed by state institutions
  #2 P1  /categories/:id full conceptual rework
  #3 P1  /vendors/:id below RedThread quality bar
  #4 P1  /institutions/:id below quality bar
  #5 P1  /administrations too many graphs, simplify
  #6 P1  /methodology body i18n + polish
  #7 P1  story chart bilingual coverage gap (12 launch-relevant)
  #8 P1  pick the 5 launch stories
  #9 P2  story chart visual quality gap
  #10 P2  /aria thread vs /vendors profile coherence

Pending docs (background agents running):
  - docs/RUBLI_v1.0_QUALITY_BAR.md (Opus design-visionary)
  - docs/RUBLI_v1.0_CHART_INVENTORY.md (Sonnet general-purpose)
rodanaya added a commit that referenced this pull request May 7, 2026
Two background-agent deliverables landed:

1. docs/RUBLI_v1.0_QUALITY_BAR.md (Opus, 434 lines)
   Defines what 'gold-standard quality' means by reading Atlas +
   Executive + AriaQueue + RedThread. Identifies the 5-bullet
   quality fingerprint. Gap-analyses the 4 'pathetic' surfaces
   (vendors / institutions / categories / administrations) with
   specific deltas + effort estimates.
   Key finding: 'pathetic' feeling = Card chrome usage. Gold
   surfaces use ZERO Cards; InstitutionProfile has 63.

2. docs/RUBLI_v1.0_CHART_INVENTORY.md (Sonnet)
   86 chart files audited. 50% Gold, 46% Decent, 3% Pathetic.
   10 orphan charts identified for kill. 5 launch-blockers
   surfaced (green-token violation, English-only labels, etc).

3. docs/RUBLI_v1.0_ISSUE_TRACKER.md updated:
   - #1 sharpened — backend filter bug source identified.
   - #2 DEFERRED to v1.1 (full categories rework needs an
     editorial decision, not an agent).
   - #9 DOWNGRADED to P3 — only 3 charts truly pathetic, not
     'most.' Likely zero additional work after other tickets.
   - 5 new tickets opened from chart inventory (#11-#15)
     covering orphan kills, green-token fix, bilingual gaps,
     duplicate-chart consolidation.

Effort recalibrated: 12-16 agent-days for full rework, vs 8 days
to launch. Triage sequence locked:
  Day 1 (Fri 05-08): #1 + #5
  Day 2-4: #4 (InstitutionProfile)
  Day 5-7: #3 (VendorProfile)
  Side: #6 (methodology), #7/#8 (stories), #11-#15
  Deferred: #2

No code changes outside this commit.
rodanaya added a commit that referenced this pull request May 11, 2026
Targeted low-risk extraction toward Wed #2 of the week plan
(/administrations refactor). Two self-contained helpers move to
their own files in components/administrations/:

- PresidentAvatar (memoized, ~60 LOC) — fetches Wikipedia portrait,
  falls back to initials. Reusable wherever an admin shows up
  (sidebar mentions, story cards, etc.).
- DeltaBadge (~25 LOC) — trend-arrow + colored value with optional
  invertColor for "higher is good" metrics.

Administrations.tsx: 3,671 → 3,614 LOC. The big AdminDossierPanel
extract (~387 LOC) is still pending — needs ~30 type/import
migrations and is too risky for the current context window. Saving
that for a fresh session with a planning agent.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
rodanaya added a commit that referenced this pull request May 11, 2026
…deCard + types/data

Wraps up Wed #2 of the week plan — the big 372-LOC AdminDossierPanel
extraction that was deferred Mon as too risky for the cycle.

Files added under components/administrations/:
- types.ts (61 LOC)         — AdminName, AdminAgg, AdminMeta, ScandalRef,
                              DossierEntry. Single source of truth for
                              shared shapes.
- data.ts (74 LOC)          — ADMINISTRATIONS, PARTY_COLORS, SEVERITY_COLORS,
                              DOSSIER_DATA. Static content the panel + page
                              both consume.
- ProcurementGradeCard.tsx  — 115 LOC. Computes A-F OECD-benchmark grade
                              from direct-award + high-risk + single-bid
                              rates; renders tier badge + 3 detail tiles.
                              Self-contained; was buried at line 2311 in
                              Administrations.tsx.
- AdminDossierPanel.tsx     — 421 LOC. The flagship per-admin dossier
                              with 3-column layout: political context +
                              scandals + key figures / fingerprint stats +
                              grade card / top vendors + top sectors.

Administrations.tsx: 3,614 → 3,060 LOC (-15%). Cleaned up unused imports
post-extraction (Link, ExternalLink, BookOpen, gradeToTierKey, TIER_STYLES,
DOSSIER_DATA, SEVERITY_COLORS, AdminMeta, ScandalRef, DossierEntry,
ProcurementGradeCard re-import).

Build green; bundle hash unchanged (extraction is structural only,
no behavioral diff).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
rodanaya added a commit that referenced this pull request May 13, 2026
cx calc used hardcoded 24 instead of COL_GAP=56; admin labels now
truncated at 10 chars + ellipsis to prevent overflow.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
rodanaya added a commit that referenced this pull request May 13, 2026
- FlowParticle: Playfair italic 400 source labels (community names left);
  mono target labels right — muted weight parity on both columns
- MacroArc: COVID 2020 callout promoted to Playfair italic pull-out
  (11px #dc2626, 24px box); other 3 callouts stay FT-style mono
- Executive LensVisualization: outer ring serif italic finding label
  "12% of pesos · 6% of contracts" (fontSize=8 → ~11px after stretch)
- Executive TopCategoriesChart: per-cell editorial captions on primary
  row cells (Playfair 8px italic); fallback data annotated with
  investigative one-liners (IMSS cluster, Toka monopoly, Segalmex P6…)
- Executive Finding 04: replaced proportional bars with Cleveland pair
  SVG per institution — filled dot = top vendor, open dot = #2 vendor,
  +Npp gap label; sorted by gap desc so ISSSTE (+82pp capture) leads

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
rodanaya added a commit that referenced this pull request May 14, 2026
All 12 risk factor coefficient entries in EN+ES glossary now reflect
v0.8.5 active model. Key changes:
- price_volatility: 0.5343 → 0.558 (still #1, now 43% ahead of #2)
- price_ratio: 0.2345 → 0.358 (rises to #3 from #4)
- vendor_concentration: 0.3749 → 0.327 (drops to #4 from #2)
- direct_award: +0.031 → -0.081 (SIGN FLIPPED — now protective)
- institution_diversity: -0.3821 → -0.388 (strengthens)
- network_member_count: +0.181 → +0.166
- ad_period_days: +0.042 → +0.090 (stronger)
- All "v0.6.5" references updated to "v0.8.5"
- "Zeroed in v0.6.5" → "regularized in v0.8.5"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
rodanaya added a commit that referenced this pull request May 17, 2026
…elements

- CategoryCaptureDumbbell: add tabIndex+onKeyDown to vendor dot circles (#1 & #2)
- RiskSpendBeeswarm / VendorRiskSpendBeeswarm: add onKeyDown to role=button SVG nodes (keep tabIndex=-1 to avoid tab-spam in dense charts)
- InvestigationCaseDetail: aria-label on evidence URL input, type/credibility selects, date input, case-status select (5 labelling gaps)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
rodanaya added a commit that referenced this pull request May 17, 2026
Replace the old Z1 institution bubble scatter with a structured HTML
overlay panel (Z1Panel) per the Opus editorial redesign. Z1Layer now
renders backdrop gradient only; Z1Panel provides:

- Banner card (top institution by spend): Playfair Italic risk %, tier
  glyph, [DA]/[HR] flag pills, sector share bar, VER INSTITUCIÓN CTA
- 3 feature column cards (#2#4): compact variant of banner layout
- Collapsed tail (remaining institutions) with expand toggle
- OECD DA annotation (cyan) when direct-award rate > 25%
- Tier marks: T1◆/T2◆ (critical/high) · T3●/T4● (medium/low)

Also removes ~110 lines of dead code (shortLabel, ACRONYM_STOP_WORDS,
CANONICAL_ACRONYMS, stripAccents) — all orphaned after InstitutionBodyVisual
was removed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
rodanaya added a commit that referenced this pull request May 20, 2026
The 320px floating card obstructed the constellation, especially at narrow
viewports. Now:
- ✕ button collapses the card (zoom state preserved)
- A compact "{code} · show" chip replaces the card; click to re-expand
- Card auto-reopens whenever a new cluster is zoomed
- escape-zoom is reserved for ESC key + breadcrumb back (intentional exit)
- Card now positioned at top:44 (below the 32px breadcrumb), not top:12

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
rodanaya added a commit that referenced this pull request May 20, 2026
Yesterday's user complaint: at ~730px viewport (tablet/preview pane) the
320px card ate ~half the canvas, obscuring the constellation.

Responsive treatment:
- Card width: 230px (mobile) → 270px (sm) → 320px (lg)
- Card padding: p-2.5 (mobile) → p-3 (sm+)
- Stat row gap: gap-1.5 (mobile) → gap-2 (sm+)
- Playfair label font: clamp(15px, 2.2vw, 18px) — gentle scale-down
- StatCell value font: clamp(14px, 1.8vw, 18px)
- Stat labels truncate + title attr (for narrow cells)
- Top vendor list: text-[10px] (mobile) → text-[11px] (sm+), truncate, name maxLength 32→36
- Card wrapper position: top-[38px] right-1 (mobile) → top-11 right-3 (sm+) — pulls closer to edge on narrow

Mobile (390px) is still constrained — the canvas itself is too small to be
practical at that width — but the dismiss-to-chip escape valve from P2 hotfix #2
still works, so the user can collapse the card and view the constellation.

Verified at 1280, 800, 390 widths via Puppeteer.
TS 0 errors. lint:tokens PASS.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
rodanaya added a commit that referenced this pull request Jun 3, 2026
…ess (15 findings)

Acts on the Opus grading panel (Regular 72→targets Satisfactorio). Critical +
high findings first:

HONESTY (critical/high)
- #1 The fanned y-axis no longer lies. `collapse` is lifted out of subScatter
  into `fanState`; when a cluster's vendors share ~one risk (collapse ≥ 0.5) the
  vertical order is an arbitrary hash, so the axis label switches from "↑ RISK"
  to "≈ EQUAL RISK · ARBITRARY SPREAD" and greys out. The fan can no longer be
  read as a risk gradient.
- #2 The on-chart sample is labelled for what it is — "top N by risk" (backend
  orders avg_risk_score DESC), not a value-complete set.

ACCESSIBILITY (Deficiente 52 → )
- #3 Risk gains a non-colour channel: a redundant tier ring (heavy=critical,
  thin=high, none=medium) keyed off getRiskLevelFromScore — colour-blind safe.
- #4 Visible keyboard-focus ring on every L2 and macro orb (SVG can't render
  :focus-visible); onFocus also surfaces the vendor name.
- #5 Screen-reader narrative: focus group role+aria-label, a live region that
  announces the cluster + count + axes on fly-in, dynamic SVG root label.
- #7 prefers-reduced-motion: camera fly-in/out + orb staggers collapse to 0.

ROBUSTNESS
- #6 NaN/undefined risk_score can no longer poison the layout (safeRisk01 guards
  collapse, ty, riskRamp, getRiskLevelFromScore, the drawer).

INFO DESIGN
- #8 L2 micro-legend (◯ size ∝ contracts · ⊝ documented case) — the encodings
  the macro how-to-read strip can't explain while hidden.
- #9 Drawer = the COMPLETE keyset-paginated tail (load-more), not the on-chart 30.
- #10 "+N unlabeled · open list" cue (click opens the drawer); names also surface
  on keyboard focus.
- #11 Legibility: caption 5.6→7, sub-labels 6→6.8 (boxes resized), axes 6→6.5.
- #12 L2 orbs get a shared sheen gradient (luminous, not flat).
- #13 GT documented-case ring moved outboard, solid ink — no longer sub-pixel fuzz.
- #14 SUB_COUNT 40→30 (dead cap removed; tied to the fetch limit).
- #15 0.2 fan threshold hoisted to RISK_FAN_THRESHOLD with rationale.

Scoped out: the on-chart value-union (#2's optional part) — it would muddy the
"30 shown" model; honest labelling + the now-complete paginated drawer give value
access instead.

Gates: tsc 0 · tsc -b 0 · build 0 · lint:tokens PASS.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
rodanaya added a commit that referenced this pull request Jun 4, 2026
…l ("UN SOLO PATRÓN")

DESIGNUS panel #2 (de-clutter) P1 — approved scheme .claude/designs/administrations-scheme.md.
The page was a data dump (~15 equal-weight blocks across 3 tabs; user got lost). P1 is pure
subtraction + reorder: one vertical scroll, ranked by visual weight = importance.

- CUT the 3-tab structure (Profile/Patterns/Comparison) → single scroll.
- CUT the 5-radar AdministrationFingerprints (anti-pattern #2) + unused PlateFrame import.
- CUT the Sector Risk Correlations block (analyst curio) + the 4 Transition-Impact cards
  (TransitionMetric/TransitionMiniBar gone) — §3 FeaturedComparison covers the one transition.
- PROMOTE the 25-year systemic trend (was hidden on the Patterns tab) to §1, right after the
  hero, with the 65.3% national-avg + OECD reference rules.
- Order: hero "un solo patrón" → §1 25-yr trend → §2 per-admin high-risk bars → §3 the one
  transition → §4 the sortable-ready AdminSectorMatrix → "§ EXPLORAR EN DETALLE" divider →
  demoted single-admin detail (stats/yearly/sectors/events/vendors/cases) → lame-duck +
  compare-period (collapsed footer).
- Removed orphaned ERA_EDITORIAL_KEYS + ADMIN_COLORS consts. Net -460 LOC (1925→1465).

Deferred to P2/P3: the 65.3% DashboardSledgehammer hero swap, sortable standings, DotStrip
party-colored bars, the ?admin= URL drawer. BUILD_ID → 2026-06-04-administrations-declutter-p1.
Gates: tsc (app) 0 · lint:tokens PASS · build ✓.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
rodanaya added a commit that referenced this pull request Jun 4, 2026
… URL sync · bilingual polish

P3 of "UN SOLO PATRÓN" — polish + gates.

MATRIX HEATMAP (user-chosen over the scheme's literal getRiskLevelFromScore): the §4
standings cells are colored by relative intensity within the grid's OWN min–max for the
active metric (scaleToColor 'risk' cream→amber→red), not by absolute risk tiers. Empirically
the avg-risk cells cluster at 0.19–0.32 and never reach RISK_THRESHOLDS (high 0.40 / critical
0.60) — so routing through getRiskLevelFromScore literally would paint 0/60 cells red and read
flat-grey, while the old inline 20/12/6 ladder painted most cells "critical" red (overclaim,
against the platform's honesty ethos). Relative intensity shows where risk concentrates,
honestly. Removed the inline getRiskLevel/getCellBg/getCellColor ladder (Bible hard-rule #2:
no inline risk ladders). Low end is cream — never green (§3.10). OVERALL column gets its own
5-value scale so the worst administration reads reddest. Legend is now a gradient (menor→mayor).

?admin= URL SYNC: selecting an administration writes /administrations?admin=<slug> (replace,
no history spam) and the page reads it on mount → shareable, reload-safe deep links
(?admin=amlo, ?admin=pena-nieto, …).

BILINGUAL: matrixOverall (General/Overall), matrixChrono (Crono/Chrono), matrixOverallHint,
matrixChronoHint, matrixLess/matrixMore (menor/mayor · lower/higher) added to es+en; matrix
subtitle now advertises "sort by any column".

BUILD_ID → 2026-06-04-administrations-p3-heatmap-urlsync. Gates: tsc 0 · lint:tokens PASS
(0 forbidden) · build ✓.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file github_actions Pull requests that update GitHub Actions code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants