/* Auto-extracted from the MyInvestor MCP render bundle's stylesheet.
   Powers the live product "screens" (.mim-live wrappers). Dark-mode blocks
   stripped; accent re-pointed to the Wealth violet. */

:root {
        color-scheme: light dark;

        /* Host-native aliases with local fallbacks. Brand is accent-only. */
        --app-accent: #0046DE;
        --app-accent-weak: color-mix(in srgb, var(--app-accent) 14%, Canvas 86%);
        /* Text/icon color that sits on a solid `--app-accent` fill. Paired
           with --app-accent so the button surface and its foreground always
           flip together. White over brand-navy in light; deep navy over the
           lifted #80a8ff in dark. */
        --app-accent-on: #fff;
        /* Readable accent for text/icons/borders rendered on top of a card
           surface. Same as --app-accent in light, but lifted to #80a8ff in
           dark so outline buttons, link labels and inline value text keep
           AA contrast against a near-black canvas. */
        --app-accent-fg: var(--app-accent);
        --app-positive: #26BEA7;
        --app-positive-text: #0f6f4b;
        --app-danger: #f37267;
        --app-danger-text: #b42318;
        --app-warning: #b7791f;
        /* Host tokens (Apps SDK) take precedence; system fallbacks preserve
           local debug + non-Claude hosts. SDK variable names per
           McpUiStyleVariableKey in `@modelcontextprotocol/ext-apps`. */
        --app-text: var(--color-text-primary, CanvasText);
        --app-text-soft: var(--color-text-secondary, color-mix(in srgb, CanvasText 76%, Canvas 24%));
        --app-muted: var(--color-text-tertiary, color-mix(in srgb, CanvasText 58%, Canvas 42%));
        /* `--app-text-mute` is referenced by `--brand-text-mute` (kpi subtext,
           footers, empty-state placeholders). Keep aligned with `--app-muted`
           so muted text adapts to the host theme instead of falling back to
           the hardcoded light-mode gray. */
        --app-text-mute: var(--app-muted);
        --app-border: var(--color-border-primary, color-mix(in srgb, CanvasText 14%, Canvas 86%));
        --app-bg: var(--color-background-primary, Canvas);
        --app-bg-soft: color-mix(in srgb, var(--app-accent) 4%, Canvas 96%);
        --app-bg-card: #ECF5FF;
        /* Card surface used by ficha/comparator sections and KPI tiles. Picks
           up the host's secondary background when available; otherwise lifts
           slightly from Canvas so cards stay distinguishable from the page
           in both light and dark mode. Without this token `--brand-bg-cream`
           used to resolve to a hardcoded #FAFAF7 in every theme — cream cards
           plus host-driven white text turned the dark mode unreadable. */
        --app-bg-cream: var(--color-background-secondary, color-mix(in srgb, CanvasText 6%, Canvas 94%));
        /* Brand-dark slab — reserved for any future dark-on-light surface;
           no longer used by `.fs-cta` (migrated to --cmp-surface). In dark
           mode the override lifts it so it stays distinguishable from Canvas.
           Paired with `--app-text-on-dark-slab` for the foreground; that
           token is still used by --cmp-surface-text in dark-mode overrides. */
        --app-bg-dark-slab: #0B0F19;
        --app-text-on-dark-slab: #fff;
        /* Comparator surface — both the hero and the floating CTA share this
           value so they read as a single visual treatment. Light = the brand
           light-blue we use elsewhere as `--app-bg-card`; dark = MyInvestor's
           deep navy so the comparator panel stays distinctive against the
           canvas. Foreground is theme-correct text via --cmp-surface-text;
           soft variants (kicker, cta label, missing note) derive from it
           with color-mix so contrast adapts automatically. */
        --cmp-surface: var(--app-bg-card);
        --cmp-surface-text: var(--app-text);
        /* Border radius scale. Use these tokens; only the hero corner radius
           on `.hero` and asymmetric component radii (e.g. dots, swatches)
           legitimately escape the scale. */
        --app-radius-xs: 4px;
        --app-radius-sm: 6px;
        --app-radius: 8px;
        --app-radius-md: 10px;
        --app-radius-lg: 12px;
        --app-radius-xl: 14px;
        --app-radius-2xl: 18px;
        --app-radius-3xl: 20px;
        /* Hero corner radius. Used by `.hero` and `.cmp-hero` for the
           bottom-only rounding that visually pins the dark slab to the top of
           the viewport. Sits outside the regular scale on purpose — a 28px
           sweep matches the host-chrome's window radii better than 20px. */
        --app-radius-hero: 28px;
        --app-pill: 999px;

        /* Shadow color recipes. Alphas tuned for light mode (subtle); the
           dark-scheme override below raises alpha so card depth survives a
           dark surrounding. Compose with --app-shadow-* recipes; do not write
           `rgba(0,0,0,X)` inline. */
        --app-shadow-c-low: rgb(0 0 0 / 0.04);
        --app-shadow-c-soft: rgb(0 0 0 / 0.08);
        --app-shadow-c-med: rgb(0 0 0 / 0.12);
        --app-shadow-c-strong: rgb(0 0 0 / 0.18);
        --app-shadow-c-cta: rgb(0 0 0 / 0.22);

        /* Composed shadow recipes. Use these in `box-shadow:` declarations. */
        --app-shadow-sm: 0 1px 2px var(--app-shadow-c-soft);
        --app-shadow-md: 0 2px 8px var(--app-shadow-c-med);
        --app-shadow-md-deep: 0 2px 10px var(--app-shadow-c-strong);
        --app-shadow-lg: 0 4px 16px var(--app-shadow-c-strong);
        --app-shadow-card: 0 1px 2px var(--app-shadow-c-low), 0 4px 16px var(--app-shadow-c-low);
        --app-shadow-hover: 0 12px 28px var(--app-shadow-c-soft);
        --app-shadow-cta-back: 0 4px 14px var(--app-shadow-c-soft);
        --app-shadow-cta-back-hover: 0 6px 18px var(--app-shadow-c-med);
        --app-shadow-cta: 0 6px 18px var(--app-shadow-c-cta);
        --app-shadow-banner: 0 2px 6px var(--app-shadow-c-soft);

        /* Motion. Use these instead of inline ms values so cadence stays
           consistent across the UI. `easing-out` is ease-out-quart-ish —
           natural deceleration without bounce/elastic. */
        --motion-fast: 120ms;
        --motion-base: 180ms;
        --motion-enter: 220ms;
        --motion-fade: 160ms;
        --motion-easing-out: cubic-bezier(0.2, 0, 0, 1);
        --motion-stagger: 40ms;
        --safe-top: env(safe-area-inset-top, 0px);
        --safe-right: env(safe-area-inset-right, 0px);
        --safe-bottom: env(safe-area-inset-bottom, 0px);
        --safe-left: env(safe-area-inset-left, 0px);
        --shell-max: 980px;
        --shell-pad-x: 16px;
        --shell-pad-top: 18px;
        --shell-pad-bottom: 24px;
        --tap-target: 44px;
      }

      /* Dark-mode overrides. The host SDK calls `applyDocumentTheme("dark")`
         which sets both `color-scheme: dark` and `data-theme="dark"` on
         `<html>`. We mirror the same overrides on both `prefers-color-scheme`
         (catches OS-level dark in local dev with no host) and on
         `

      /* All three brand surfaces — ficha hero (.hero), ficha sticky CTA
         (.fs-cta), and comparison sticky CTA (.cmp-cta) — share --cmp-surface
         (light blue #ECF5FF in light mode; MyInvestor deep navy #001f3d in
         dark). In dark mode their fills blend into the host's near-black
         Canvas, so a 1px adaptive border restores the panel boundary.
         Mirrored across `prefers-color-scheme` and `

      /* Ficha and comparison are full-takeover views the host renders in
         fullscreen mode, where the host title bar and chat composer can overlay
         the iframe. The host exposes those overlap regions through
         `hostContext.safeAreaInsets`, which the iframe forwards to the
         `--safe-*` CSS custom properties on `:root`. */

      html,
      body,
      #app {
        background: transparent;
      }

      *,
      *::before,
      *::after {
        box-sizing: border-box;
      }

      html {
        font-family: var(--font-sans, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif);
        font-feature-settings: "tnum";
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
      }

      body {
        margin: 0;
        padding: 0;
        color: var(--app-text);
      }

      /* Let `autoResize` size the iframe to actual content height in both
         inline and fullscreen modes. Forcing `min-height: 100vh` here used to
         leave a dark gap below sparse views (e.g. RF ficha, 2-fund comparison)
         because the body filled 100vh of the host-allocated area even when
         content was shorter. The "fullscreen" request is a hint to the host
         to prioritise this view; the iframe itself sizes to its content. */

      /* Crossfade transition for the root container. `is-fading` is toggled by
         `transitionView` in mcp-app.ts; the CSS owns the timing/easing so we
         avoid inline style writes on every view swap. */
      #app {
        transition: opacity var(--motion-fade) ease;
      }
      #app.is-fading { opacity: 0; }

      /* Card surface rendered as a native <button> (.fic-card--interactive
         in the comparator hero) needs the UA defaults stripped (font,
         text-align) before its per-component rules apply. Native button
         preserves keyboard, focus, and SR semantics for free — no
         role="button" / tabindex / keydown wiring needed. Padding is handled
         by the class rule, so we don't reset it here. */
      button.fic-card {
        appearance: none;
        font: inherit;
        color: inherit;
        text-align: left;
        margin: 0;
      }
      /* .ic-card is a <div>, so it needs explicit resets only for its inner
         buttons (handled per-class below). */
      .ic-card { padding: 0; }

      /* Focus styles */
      :focus-visible {
        outline: 2px solid var(--app-accent-fg);
        outline-offset: 2px;
      }

      .mcp-shell {
        width: 100%;
        color: var(--app-text);
        container-type: inline-size;
      }
      body[data-display-mode="fullscreen"] .mcp-shell {
        min-height: 100vh;
      }

      .mcp-shell-inner {
        width: 100%;
        max-width: var(--shell-max);
        margin: 0 auto;
        padding:
          max(var(--shell-pad-top), calc(var(--safe-top) + 12px))
          max(var(--shell-pad-x), var(--safe-right))
          max(var(--shell-pad-bottom), calc(var(--safe-bottom) + 20px))
          max(var(--shell-pad-x), var(--safe-left));
      }

      .mcp-shell-wide {
        --shell-max: 1180px;
      }

      /* Compact: 0-result shells where only a single kicker line is shown. */
      .mcp-shell--compact .mcp-shell-inner {
        padding-top: max(10px, calc(var(--safe-top) + 4px));
        padding-bottom: max(10px, calc(var(--safe-bottom) + 4px));
      }
      .mcp-shell--compact .ic-carousel-head { margin-bottom: 0; }

      .mcp-view-head {
        margin-bottom: 14px;
      }

      .mcp-view-title {
        margin: 0;
        color: var(--app-text);
        font-size: 16px;
        line-height: 1.25;
        font-weight: 700;
      }

      .mcp-view-subtitle {
        margin: 4px 0 0;
        color: var(--app-text-soft);
        font-size: 12px;
        line-height: 1.45;
        font-weight: 500;
      }

      .mcp-touch {
        min-width: var(--tap-target);
        min-height: var(--tap-target);
      }

      .mcp-sr-only {
        position: absolute;
        width: 1px;
        height: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip: rect(0, 0, 0, 0);
        white-space: nowrap;
        border: 0;
      }

      @media (prefers-reduced-motion: reduce) {
        *,
        *::before,
        *::after {
          animation-duration: 0.01ms !important;
          animation-iteration-count: 1 !important;
          scroll-behavior: auto !important;
          transition-duration: 0.01ms !important;
        }
      }

      /* Row entry stagger animation */
      @keyframes row-in {
        from {
          opacity: 0;
          transform: translateY(4px);
        }
        to {
          opacity: 1;
          transform: translateY(0);
        }
      }

      /* View fade transition */
      @keyframes fade-in {
        from {
          opacity: 0;
        }
        to {
          opacity: 1;
        }
      }

      @keyframes skeleton-shimmer {
        0% { background-position: -200% 0; }
        100% { background-position: 200% 0; }
      }

      .skeleton {
        background: linear-gradient(
          90deg,
          color-mix(in srgb, CanvasText 6%, Canvas 94%) 0%,
          color-mix(in srgb, CanvasText 12%, Canvas 88%) 50%,
          color-mix(in srgb, CanvasText 6%, Canvas 94%) 100%
        );
        background-size: 200% 100%;
        animation: skeleton-shimmer 1.4s ease-in-out infinite;
        border-radius: var(--app-radius-xs);
      }
      /* Pause the shimmer when the tab is backgrounded — modern browsers
         throttle infinite animations but don't suspend them, so we explicitly
         pause to free CPU on off-screen iframes. Driven by the body
         `data-doc-hidden` attribute toggled in mcp-app.ts. */
      body[data-doc-hidden="true"] .skeleton {
        animation-play-state: paused;
      }
      .skeleton-hero {
        height: 134px;
        border-radius: 0;
      }
      .skeleton-line { height: 12px; }
      .skeleton-line--kicker { width: 60%; max-width: 280px; height: 14px; }
      .skeleton-line--title  { height: 14px; width: 92%; }
      .skeleton-line--short  { height: 11px; width: 60%; margin-top: 4px; }
      .skeleton-line--cell   { height: 14px; width: 70%; }
      .ic-card--skeleton {
        cursor: default;
        box-shadow: none;
      }
      .ic-card--skeleton:hover {
        transform: none;
        box-shadow: none;
      }
      .ic-card-body__row-skeleton {
        display: grid;
        grid-template-columns: 1fr 1fr 1fr;
        gap: 0;
        padding-top: 10px;
        border-top: 1px solid var(--app-border);
        align-items: center;
      }
      .ic-card-body__row-skeleton > .skeleton + .skeleton {
        margin-left: 10px;
      }

      .animate-row-in {
        animation: row-in var(--motion-enter) var(--motion-easing-out) both;
        /* Cards opt into a staggered entrance by setting `--stagger-i` to
           their index (e.g. `style="--stagger-i: 2"`). Without `--stagger-i`
           the delay resolves to 0 and the animation plays immediately. */
        animation-delay: calc(var(--stagger-i, 0) * var(--motion-stagger));
      }

      .animate-fade-in {
        animation: fade-in var(--motion-fade) ease both;
      }

      /* ============================================================
         New design — carousel + full-screen ficha & comparison
         ChatGPT-Apps style: rich hero gradients, pill controls,
         tinted tiles. Tokens use host-native --app-* where possible.
         ============================================================ */

      :root {
        /* Brand aliases — every fallback used to be a hardcoded light-mode
           color. Now they all reuse the upstream --app-* tokens defined
           above, so the brand layer adapts to whatever the host (or the OS
           in local dev) provides for light vs dark theme. */
        --brand-accent:    var(--app-accent);
        --brand-bg-soft:   var(--app-bg-soft);
        --brand-bg-cream:  var(--app-bg-cream);
        --brand-border:    var(--app-border);
        --brand-text:      var(--app-text);
        --brand-text-soft: var(--app-text-soft);
        --brand-text-mute: var(--app-text-mute);
        /* Signed-value tints on brand surfaces (year bars, perf card, perf
           strip). Alias the `*-text` semantic tokens so both signs adapt to
           light/dark in lockstep with the rest of the system. The previous
           setup pointed `--brand-pos` at `--app-positive` (#26BEA7, no dark
           override) and hardcoded `--brand-neg` to #FD7A7B — symmetrically
           non-adaptive. Now: light = deep teal / deep red; dark = lifted
           mint / lifted coral, matching .ic-card .row .v.pos/.neg which
           already routed through `--app-*-text` directly. See AUDIT.md H-4. */
        --brand-pos:       var(--app-positive-text);
        --brand-neg:       var(--app-danger-text);
      }

      /* Make sure [hidden] beats display:grid/display:block rules on logo
         overlays. The global error handler sets `hidden` when Brandfetch
         returns an error or transparent placeholder. */
      img[data-logo][hidden] { display: none !important; }

      /* ----- Carousel ----- */
      .ic-result-kicker {
        margin: 0;
        color: var(--app-text-soft);
        font-size: 11px;
        font-weight: 700;
        letter-spacing: 0.07em;
        text-transform: uppercase;
        line-height: 1.45;
      }
      .ic-carousel { width: 100%; position: relative; }
      .ic-carousel-head {
        display: flex; align-items: center; justify-content: space-between;
        gap: 12px;
        margin-bottom: 10px;
      }
      .ic-carousel-head .ic-result-kicker { flex: 1; min-width: 0; }
      .ic-carousel-head .lbl {
        font-size: 13px;
        color: var(--app-text-soft);
        font-weight: 500;
      }
      .ic-carousel-head .lbl b {
        color: var(--app-text);
        font-weight: 700;
      }
      .ic-carousel-head .controls { display: flex; gap: 6px; }
      .ic-carousel-head .controls button {
        appearance: none;
        width: var(--tap-target);
        height: var(--tap-target);
        border: 1px solid var(--app-border);
        background: var(--app-bg);
        border-radius: 50%;
        color: var(--app-text-soft);
        cursor: pointer;
        display: grid;
        place-items: center;
        font-family: inherit;
      }
      .ic-carousel-head .controls button:hover {
        background: var(--app-bg-soft);
        color: var(--app-text);
      }
      .ic-carousel-head .controls button:disabled {
        opacity: 0.4;
        cursor: default;
      }

      /* Bleed alineado con shell-pad-x para no provocar overflow horizontal en
         iframes estrechos (Claude inline). overflow:hidden recorta el bleed
         interno cuando el carousel hace scroll. */
      .ic-track-wrap {
        margin: 0 calc(-1 * var(--shell-pad-x));
        padding: 4px var(--shell-pad-x) 8px;
        overflow: hidden;
      }
      .ic-track {
        display: flex;
        gap: 12px;
        scroll-snap-type: x mandatory;
        overflow-x: auto;
        scroll-behavior: smooth;
        padding-bottom: 4px;
        scrollbar-width: none;
      }
      .ic-track::-webkit-scrollbar { display: none; }

      /* Non-interactive wrapper: the two inner buttons (`.ic-tile-cta`,
         `.ic-tile-more`) are the only click targets. No wrap-level cursor or
         hover lift — they used to live here but implied the whole card was
         clickable, which confused users and was inaccessible for keyboard
         navigation (same rationale as `.cc-wrap` above). */
      .ic-card {
        flex: 0 0 min(290px, calc(100vw - 48px - var(--safe-left) - var(--safe-right)));
        scroll-snap-align: start;
        scroll-snap-stop: always;
        border: 1px solid var(--app-border);
        border-radius: var(--app-radius-md);
        background: var(--app-bg-card);
        overflow: hidden;
        display: flex;
        flex-direction: column;
        box-shadow: var(--app-shadow-card);
      }
      .ic-card .ic-card-body {
        padding: 14px 16px 16px;
        display: flex;
        flex-direction: column;
        gap: 12px;
      }
      .ic-card .ic-card-body .name {
        font-size: 14px; font-weight: 600;
        color: var(--app-text);
        line-height: 1.3;
        letter-spacing: -0.01em;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
      }
      .ic-card .ic-card-body .mgr {
        font-size: 11px;
        color: var(--app-text-soft);
        margin-top: 3px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        font-variant-numeric: tabular-nums;
      }
      /* Card identity row: square fund-mark on the left, name/manager
         stacked in the middle. Replaces the coloured `.fund-crest` hero with
         a flat, single-card surface. */
      .ic-card-head {
        display: flex;
        align-items: flex-start;
        gap: 12px;
        min-width: 0;
      }
      .ic-card-head .fund-mark { flex-shrink: 0; }
      .ic-card-ident {
        display: flex;
        flex-direction: column;
        flex: 1;
        min-width: 0;
      }
      /* Morningstar category line — mirrors the ficha hero sub-line. Single
         row, ellipsed if the category name overflows. */
      .ic-card-category {
        font-size: 11px;
        font-weight: 500;
        color: var(--app-text-soft);
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
      /* Descriptor pills (Indexado, EUR, ESG…). Mirrors the ficha hero pill
         set so card and ficha surface the same descriptors. Smaller scale
         than `.hero-pill` to fit a 290px card surface. */
      .ic-card-pills {
        display: flex;
        flex-wrap: wrap;
        gap: 4px;
      }
      .ic-card-pill {
        display: inline-flex; align-items: center;
        padding: 2px 8px;
        border-radius: var(--app-pill);
        background: var(--app-bg-soft);
        border: 1px solid var(--app-border);
        font-size: 10px;
        font-weight: 600;
        letter-spacing: 0.01em;
        color: var(--app-text-soft);
      }
      /* 4-column returns row: YTD · 1A · 3A · TER. Dividers dropped because
         the row is dense enough that vertical lines fight with signed-percent
         values like `+130,9%` that already push the cell width on a 290px
         card. A `gap` separates the columns instead. */
      .ic-card .ic-card-body .row {
        display: grid;
        grid-template-columns: 1fr 1fr 1fr 1fr;
        gap: 6px;
        padding-top: 10px;
        border-top: 1px solid var(--app-border);
      }
      .ic-card .ic-card-body .row > div {
        display: flex; flex-direction: column; gap: 2px;
        min-width: 0;
      }
      .ic-card .ic-card-body .row .lbl {
        font-size: 10px;
        color: var(--app-text-soft);
        text-transform: uppercase;
        letter-spacing: 0.06em;
        font-weight: 700;
      }
      .ic-card .ic-card-body .row .v {
        font-size: 13px;
        font-weight: 600;
        color: var(--app-text);
        font-variant-numeric: tabular-nums;
        letter-spacing: -0.02em;
      }
      .ic-card .ic-card-body .row .v.pos,
      .perf-big.pos {
        color: var(--app-positive-text);
      }

      .ic-card .ic-card-body .row .v.neg,
      .perf-big.neg {
        color: var(--app-danger-text);
      }

      /* Card footer: CTA + "más información" */
      .ic-card .ic-card-footer {
        padding: 12px 16px 14px;
        border-top: 1px solid var(--app-border);
        display: flex;
        flex-direction: column;
        gap: 10px;
        align-items: flex-start;
      }
      .ic-tile-cta {
        appearance: none;
        display: flex;
        align-items: center;
        justify-content: center;
        width: 100%;
        min-height: var(--tap-target);
        padding: 10px 16px;
        border-radius: var(--app-pill);
        border: none;
        background: var(--app-accent);
        color: var(--app-accent-on);
        font-family: inherit;
        font-size: 13px;
        font-weight: 700;
        line-height: 1;
        cursor: pointer;
        transition: background var(--motion-fast);
        white-space: nowrap;
      }
      .ic-tile-cta:hover {
        background: color-mix(in srgb, var(--app-accent) 85%, var(--app-text) 15%);
      }
      .ic-tile-more {
        appearance: none;
        display: flex;
        align-items: center;
        justify-content: center;
        width: 100%;
        min-height: var(--tap-target);
        padding: 8px 16px;
        border-radius: var(--app-pill);
        border: 1.5px solid var(--app-accent-fg);
        background: transparent;
        font-family: inherit;
        font-size: 13px;
        font-weight: 600;
        line-height: 1;
        color: var(--app-accent-fg);
        cursor: pointer;
        transition: background var(--motion-fast);
      }
      .ic-tile-more:hover { background: var(--app-accent-weak); }

      /* Collapsed-ficha placeholder: a single carousel-style tile, centered.
         Width capped at the same 290px as carousel cards but allowed to shrink
         on narrow iframes (Claude inline) so the safe-area insets are honored. */
      .fc-wrap {
        display: flex;
        justify-content: center;
        padding: 4px 0 8px;
      }
      .fc-wrap .ic-card {
        flex: 0 1 min(290px, calc(100vw - 48px - var(--safe-left) - var(--safe-right)));
        width: 100%;
      }

      /* Collapsed-comparator placeholder: shares `--cmp-surface` with the
         comparator hero (light blue in light, navy in dark) so tapping into
         the full comparator keeps the same surface treatment. Vertical stack
         of mini fund tiles plus a "Ver comparativa completa" CTA. */
      .cc-wrap {
        background: var(--cmp-surface);
        color: var(--cmp-surface-text);
        border: 1px solid color-mix(in srgb, var(--cmp-surface-text) 14%, transparent);
        border-radius: var(--app-radius-2xl, 18px);
        padding: 20px;
        margin: 4px 0 8px;
        display: flex;
        flex-direction: column;
        gap: 14px;
        box-shadow: var(--app-shadow-card);
      }
      /* No wrap-level hover/cursor: the visible `.cc-cta` button is the
         only click target (keyboard-reachable via Tab). The hover lift used
         to live here but it implied the whole panel was clickable, which is
         inaccessible for keyboard users — see C-2 in AUDIT.md. */
      .cc-header { display: flex; flex-direction: column; gap: 4px; }
      .cc-kicker {
        font-size: 10px; font-weight: 700; text-transform: uppercase;
        letter-spacing: 0.08em; color: var(--app-muted);
      }
      .cc-wrap h1 {
        margin: 0;
        /* Fluid clamp scales with the container, smoothing the 18→22 step
           that used to live in a @container override. cqi resolves against
           the nearest container-query container (.mcp-shell). */
        font-size: clamp(18px, 3.5cqi, 22px);
        font-weight: 700;
        letter-spacing: -0.01em; line-height: 1.18;
      }
      .cc-list { display: flex; flex-direction: column; gap: 10px; }
      .cc-footer {
        border-top: 1px solid var(--app-border);
        padding-top: 14px;
      }
      .cc-cta {
        appearance: none;
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 6px;
        width: 100%;
        min-height: var(--tap-target);
        padding: 10px 16px;
        border-radius: var(--app-pill);
        border: 1.5px solid var(--app-accent-fg);
        background: transparent;
        color: var(--app-accent-fg);
        font-family: inherit;
        font-size: 13px;
        font-weight: 600;
        line-height: 1;
        cursor: pointer;
        transition: background var(--motion-fast, 160ms);
      }
      .cc-cta:hover { background: color-mix(in srgb, var(--app-accent-fg) 18%, transparent); }
      .cc-cta:focus-visible { outline: 2px solid var(--app-accent-fg); outline-offset: 2px; }
      @container (max-width: 480px) {
        .cc-wrap { padding: 16px; border-radius: 16px; }
        /* `.cc-wrap h1` no longer needs an explicit override here — it uses
           a fluid clamp that already scales down on narrow containers. The
           shared `.fic-card-*` rules below carry the tile padding + KPI
           sizing now that this surface uses the unified card component. */
      }

      .pill-btn {
        appearance: none;
        display: inline-flex;
        align-items: center;
        gap: 6px;
        padding: 7px 14px;
        border-radius: var(--app-pill);
        border: 1px solid var(--app-border);
        background: var(--app-bg);
        font-family: inherit;
        font-size: 12px;
        font-weight: 600;
        line-height: 1;
        color: var(--app-text);
        cursor: pointer;
        /* Without this the inner <span> with the label is "selectable text",
           and the browser draws the I-beam cursor over it instead of the
           button's pointer — making the text half look like it isn't part of
           the button. user-select: none keeps the pointer cursor uniform
           across the whole pill without touching event flow. */
        user-select: none;
        -webkit-user-select: none;
        /* Removes the 300ms tap delay and disables double-tap-zoom on the
           button itself — important on iOS Safari where the host iframe sits
           on a touch surface. */
        touch-action: manipulation;
        transition: background var(--motion-fast), border-color var(--motion-fast);
        white-space: nowrap;
      }
      .pill-btn:hover { background: color-mix(in srgb, CanvasText 8%, transparent); }
      .pill-btn.ghost { color: var(--app-text-soft); }
      .pill-btn.ghost:hover { color: var(--app-text); }
      .pill-btn.primary {
        background: var(--app-text);
        color: var(--app-bg);
        border-color: var(--app-text);
        font-weight: 700;
        padding: 8px 18px;
      }

      /* ----- Full-screen ficha ----- */
      /* No `min-height: 100vh` here — the iframe should match content height
         via autoResize so sparse views (RF ficha, 2-fund comparison) don't
         leave a dark gap below the last card / CTA. */
      .fs-overlay {
        background: var(--app-bg);
        color: var(--app-text);
      }

      .fs-panel {
        background: var(--app-bg);
        container-type: inline-size;
      }

      .fs-body {
        max-width: 1240px;
        margin: 0 auto;
        padding: 4px max(20px, var(--safe-right)) 8px max(20px, var(--safe-left));
        display: flex;
        flex-direction: column;
        gap: 14px;
        width: 100%;
        box-sizing: border-box;
      }

      .fs-card {
        background: var(--app-bg-soft);
        border-radius: var(--app-radius-2xl);
        border: 1px solid var(--app-border);
        padding: 20px 22px;
      }
      .card-head {
        display: flex;
        align-items: flex-start;
        justify-content: space-between;
        gap: 12px;
        margin-bottom: 14px;
      }
      .fs-card h3 {
        margin: 0;
        font-size: 15px;
        font-weight: 700;
        color: var(--app-text);
        letter-spacing: -0.01em;
      }
      .card-sub {
        margin: 2px 0 0;
        font-size: 11px;
        color: var(--app-text-soft);
      }
      .card-sub-inline {
        font-size: 11px;
        color: var(--app-text-soft);
        font-weight: 500;
      }

      .tile {
        border-radius: var(--app-radius-xl);
        padding: 16px 18px;
        display: flex;
        flex-direction: column;
        gap: 4px;
        border: 1px solid transparent;
      }
      .tile .t-lbl {
        font-size: 10px;
        font-weight: 800;
        text-transform: uppercase;
        letter-spacing: 0.05em;
        opacity: 0.8;
      }
      .tile .t-v {
        font-size: 20px;
        font-weight: 800;
        letter-spacing: -0.02em;
        font-variant-numeric: tabular-nums;
        line-height: 1.1;
      }
      @container (max-width: 720px) {
        .fs-body {
          padding: 4px max(16px, var(--safe-right)) 8px max(16px, var(--safe-left));
        }
      }

      /* Operativa / generic key-value list */
      .kv-list { display: flex; flex-direction: column; margin: 0; padding: 0; }
      .kv-list .kv-row {
        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: 12px;
        padding: 10px 0;
      }
      .kv-list .kv-row + .kv-row {
        border-top: 1px solid var(--app-border);
      }
      /* Description block */
      .fs-desc {
        font-size: 13px;
        line-height: 1.6;
        color: var(--app-text);
      }
      .fs-desc .desc-toggle {
        background: none;
        border: none;
        color: var(--app-accent-fg);
        font-family: inherit;
        font-size: 13px;
        font-weight: 700;
        line-height: 1;
        cursor: pointer;
        padding: 0;
        margin-left: 4px;
      }

      /* Sticky CTA bar — uses --cmp-surface (light blue in light mode, navy in
         dark mode). Self-contained at the bottom of the panel; rounded corners,
         accent buy button. */
      .fs-cta {
        position: sticky;
        bottom: var(--safe-bottom);
        z-index: 4;
        display: flex;
        align-items: center;
        gap: 14px;
        padding: 14px 20px;
        margin: 4px auto 0;
        width: calc(100% - max(20px, var(--safe-left)) - max(20px, var(--safe-right)));
        max-width: 960px;
        box-sizing: border-box;
        background: var(--cmp-surface);
        color: var(--cmp-surface-text);
        border-radius: 999px;
        box-shadow: 0 10px 28px var(--app-shadow-c-cta);
      }
      .fs-cta > * { pointer-events: auto; }
      .fs-cta .pill-btn,
      .fs-cta button {
        min-height: var(--tap-target);
      }
      .fs-cta .grow { flex: 1; }
      .fs-cta .cta-meta {
        font-size: 12px;
        color: color-mix(in srgb, var(--cmp-surface-text) 55%, transparent);
        white-space: nowrap;
        flex-shrink: 0;
        letter-spacing: 0.01em;
      }
      .fs-cta .cta-meta strong {
        color: color-mix(in srgb, var(--cmp-surface-text) 90%, transparent);
        font-weight: 600;
      }
      .fs-cta .actions {
        display: flex;
        gap: 8px;
        align-items: center;
        flex-wrap: wrap;
        justify-content: flex-end;
      }
      .fs-cta .pill-btn { padding: 9px 16px; }
      /* Volver chip inside the CTA. Colors adapt via --cmp-surface-text so the
         chip reads correctly on both the light-blue light-mode surface and the
         deep-navy dark-mode surface. */
      .fs-cta .fs-back {
        flex-shrink: 0;
        padding: 9px 14px 9px 10px;
        border: 1px solid color-mix(in srgb, var(--cmp-surface-text) 18%, transparent);
        border-radius: var(--app-pill);
        background: color-mix(in srgb, var(--cmp-surface-text) 5%, transparent);
        color: var(--cmp-surface-text);
        font-weight: 600;
      }
      .fs-cta .fs-back:hover {
        background: color-mix(in srgb, var(--cmp-surface-text) 10%, transparent);
      }
      @container (max-width: 480px) {
        .fs-cta { padding: 12px 14px; gap: 10px; }
        .fs-cta .pill-btn { padding: 8px 12px; font-size: 11px; }
        .fs-cta .pill-btn.primary { padding: 9px 14px; font-size: 12px; }
        .fs-cta .fs-back { padding: 8px 12px 8px 8px; }
        /* When there's no Back (carousel/direct origins), the Sticky CTA is
           reduced to just the buy button on narrow screens — let it span the
           full width instead of being parked to one side. */
        .fs-cta:not(:has(.fs-back)) .grow { display: none; }
        .fs-cta:not(:has(.fs-back)) .actions { flex: 1; }
        .fs-cta:not(:has(.fs-back)) .actions .pill-btn.primary {
          width: 100%;
          justify-content: center;
        }
        /* Hide the meta info chip on narrow viewports so the CTA fits — mirrors
           how the fund ficha hides `.cta-summary`. Applies whether or not the
           Volver chip is present (`hideBack: true` when the host owns the
           back gesture in fullscreen). */
        .fs-cta .cta-meta { display: none; }
      }
      .fs-cta .pill-btn.primary {
        padding: 10px 22px;
        font-size: 13px;
        gap: 8px;
        background: var(--brand-accent);
        color: var(--app-accent-on);
        border-color: var(--brand-accent);
        transition: transform var(--motion-fast) ease, filter var(--motion-fast) ease;
      }
      .fs-cta .pill-btn.primary:hover {
        transform: translateY(-1px);
        filter: brightness(1.1);
      }
      .btn-icon-circle {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 26px;
        height: 26px;
        border-radius: 50%;
        background: color-mix(in srgb, var(--app-accent-on) 20%, transparent);
        flex-shrink: 0;
      }

      /* Warning banner */
      .fs-warning {
        background: color-mix(in srgb, var(--app-warning) 14%, var(--app-bg) 86%);
        border: 1px solid color-mix(in srgb, var(--app-warning) 50%, transparent);
        border-radius: var(--app-radius-lg);
        padding: 12px 14px;
        display: flex;
        gap: 10px;
        align-items: flex-start;
        color: var(--app-warning);
      }
      .fs-warning .ico { font-size: 14px; line-height: 1.55; flex-shrink: 0; }
      .fs-warning .txt { font-size: 12px; line-height: 1.55; }


      /* ── Tool error state ───────────────────────────────────────────────── */
      .tool-error {
        padding: 32px;
        text-align: center;
        color: var(--app-danger-text);
        font-size: 13px;
        font-weight: 500;
      }

      /* ── Diagnostic banner overlay (non-destructive) ─────────────────────── */
      .diag-banner {
        position: fixed;
        top: var(--safe-top, 0);
        left: 0;
        right: 0;
        z-index: 9999;
        padding: 8px 36px 8px 16px;
        background: color-mix(in srgb, Canvas 88%, CanvasText 12%);
        color: var(--app-text, CanvasText);
        font-size: 13px;
        border-bottom: 1px solid var(--app-border, color-mix(in srgb, CanvasText 14%, Canvas 86%));
        box-shadow: var(--app-shadow-banner);
        display: flex;
        align-items: center;
        gap: 8px;
      }
      .diag-banner-text { flex: 1; }
      .diag-banner-close {
        border: 0;
        background: transparent;
        color: inherit;
        cursor: pointer;
        padding: 4px 6px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        border-radius: var(--app-radius-xs);
        line-height: 1;
      }
      .diag-banner-close:hover {
        background: color-mix(in srgb, CanvasText 8%, transparent);
      }

      /* ── Stale-state overlay (preserves prior data while new search loads) ── */
      .stale-overlay {
        position: fixed;
        inset: var(--safe-top, 0) 0 auto 0;
        padding: 8px 16px;
        z-index: 9998;
        background: color-mix(in srgb, Canvas 75%, CanvasText 25%);
        color: var(--app-bg, Canvas);
        font-size: 12px;
        text-align: center;
      }

      /* ----- Primitives: fund-mark / returnTile / hbar / donut / SRRI / badge / KPI tile ----- */
      .fund-mark {
        display: grid; place-items: center;
        color: white;
        font-weight: 700; letter-spacing: -0.02em;
        flex-shrink: 0;
        position: relative;
        box-shadow: var(--app-shadow-sm);
      }
      .fund-mark .fm-logo {
        position: absolute; inset: 0;
        width: 100%; height: 100%;
        background: white;
        object-fit: contain;
        border-radius: inherit;
      }

      .rt { display: flex; flex-direction: column; align-items: stretch; gap: 6px; min-width: 0; }
      .rt-val {
        font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums;
        text-align: center; line-height: 1.1;
        white-space: nowrap;
        /* Labels are wider than the column on narrow viewports — let them
           bleed into the adjacent gap rather than wrap or clip. */
        overflow: visible;
      }
      .rt.pos .rt-val { color: var(--brand-pos); }
      .rt.neg .rt-val { color: var(--brand-neg); }
      .rt.zero .rt-val { color: var(--brand-text-soft); }
      /* Zero-baseline bar with asymmetric scaling. The parent row sets
         `--pos-frac` / `--neg-frac` (summing to 100%) so the positive zone
         is sized to fit the tallest positive value and the negative zone
         the deepest negative — never wasting space on a side that doesn't
         exist. The value label lives INSIDE each zone, anchored at the
         fill's outer edge so labels track the bar tops. */
      .rt-bar {
        background: transparent;
        position: relative;
        display: grid;
        grid-template-rows: var(--pos-frac, 50%) var(--neg-frac, 50%);
        /* Reserve room at the top and bottom for the floating value labels.
           When a bar reaches the zone's posMax / negMax, the value label
           overflows its zone — the padding here is where it lands. */
        padding-block: 20px;
        height: 56px;
        box-sizing: content-box;
      }
      /* Baseline marker intentionally omitted — the pos/neg bars
         themselves visually define the zero line. */
      .rt-zone {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: 2px;
        min-height: 0;
        /* No overflow clipping — the value label sits at the fill edge and
           can extend into the rt-bar's padding when the bar fills its zone. */
      }
      .rt-zone-pos { justify-content: flex-end; }
      .rt-zone-neg { justify-content: flex-start; }
      .rt-fill {
        background: currentColor;
        min-height: 2px;
        flex-shrink: 0;
      }
      .rt.pos .rt-fill,
      .rt.zero .rt-fill {
        color: var(--brand-pos);
        border-radius: 4px 4px 0 0;
      }
      .rt.neg .rt-fill {
        color: var(--brand-neg);
        border-radius: 0 0 4px 4px;
      }
      .rt.zero .rt-fill { color: var(--brand-text-mute); }
      .rt-sub { font-size: 11px; color: var(--brand-text-soft); text-align: center; font-weight: 500; }
      /* Ficha year-bars: tall bars (mock proportion). The content height
         (180px) plus the 20px+20px label padding adds up to the 220px
         visual block. */
      .fs-year-bars .rt-bar { height: 180px; }

      .hbar { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(80px, 1fr) auto; gap: 10px; align-items: center; padding: 6px 0; }
      .hbar-label { font-size: 12px; font-weight: 500; color: var(--brand-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
      .hbar-track { height: 8px; background: var(--brand-bg-soft); border-radius: 999px; overflow: hidden; }
      .hbar-fill { height: 100%; background: var(--brand-accent); border-radius: inherit; }
      .hbar-pct { font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--brand-text); min-width: 48px; text-align: right; }

      .donut-wrap { position: relative; width: 140px; height: 140px; flex: 0 0 auto; }
      .donut { width: 100%; height: 100%; }
      .donut-center {
        position: absolute;
        /* Constrain to the donut's inner hole so the value never bleeds onto
           the stroke ring. stroke-width is 22 on r=59, so the usable
           diameter is ≈92px. */
        top: 50%; left: 50%; transform: translate(-50%, -50%);
        width: 88px;
        display: flex; flex-direction: column; align-items: center; justify-content: center;
        gap: 2px; text-align: center;
      }
      .donut-center-label { font-size: 11px; font-weight: 700; color: var(--brand-text-soft); letter-spacing: 0.04em; text-transform: uppercase; line-height: 1; }
      .donut-center-value { font-size: 16px; font-weight: 700; color: var(--brand-text); font-variant-numeric: tabular-nums; line-height: 1; letter-spacing: -0.02em; }

      /* SRRI gauge: 7 thin segments, filled up to the level with a
         green→amber→orange→red ramp (set inline in srriScaleHtml). The
         active (current-level) segment grows taller to stand out; the rest
         keep the compact baseline height. */
      .srri-scale { display: flex; flex-direction: column; gap: 10px; }
      .srri-track {
        display: grid;
        grid-template-columns: repeat(7, 1fr);
        gap: 4px;
        height: 14px;
        align-items: center;
      }
      .srri-seg {
        height: 10px;
        background: var(--brand-bg-soft);
        border-radius: 3px;
      }
      .srri-seg[data-active="1"] {
        height: 14px;
        border-radius: 4px;
      }
      .srri-labels { display: flex; justify-content: space-between; font-size: 11px; color: var(--brand-text-soft); font-weight: 500; }

      .kpi-tile {
        display: flex; flex-direction: column; gap: 4px;
        padding: 16px 18px;
        background: var(--brand-bg-cream);
        border: 1px solid var(--brand-border);
        border-radius: var(--app-radius-lg, 12px);
      }
      .kpi-tile.primary {
        background: var(--brand-accent);
        border-color: var(--brand-accent);
        color: var(--app-accent-on);
      }
      .kpi-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--brand-text-soft); }
      .kpi-value { font-size: 22px; font-weight: 700; color: var(--brand-text); font-variant-numeric: tabular-nums; display: inline-flex; align-items: baseline; gap: 4px; letter-spacing: -0.01em; }
      .kpi-unit { font-size: 13px; font-weight: 600; color: var(--brand-text-soft); }
      .kpi-subtext { font-size: 11px; color: var(--brand-text-mute); font-weight: 500; }
      .kpi-tile.primary .kpi-label { color: color-mix(in srgb, var(--app-accent-on) 78%, transparent); }
      .kpi-tile.primary .kpi-value { color: var(--app-accent-on); }
      .kpi-tile.primary .kpi-unit { color: color-mix(in srgb, var(--app-accent-on) 78%, transparent); }
      .kpi-tile.primary .kpi-subtext { color: color-mix(in srgb, var(--app-accent-on) 72%, transparent); }

      /* ----- Ficha layout ----- */
      /* The hero hugs the top + sides of the viewport (full-bleed) and rounds
         only at the bottom corners. The body sits below it with its own
         max-width and side padding. */
      .fs-panel { display: flex; flex-direction: column; gap: 18px; padding-bottom: max(12px, var(--safe-bottom)); }

      /* Hero surface is shared with the comparator (`--cmp-surface`): light
         blue in light mode, navy in dark. Text color (`--cmp-surface-text`)
         flips accordingly so the same component reads correctly under both
         themes without per-category gradient backgrounds. */
      .hero {
        position: relative;
        background: var(--cmp-surface);
        color: var(--cmp-surface-text);
        padding-top: max(0px, var(--safe-top));
        border-radius: 0 0 var(--app-radius-hero) var(--app-radius-hero);
        border-bottom: 1px solid color-mix(in srgb, var(--cmp-surface-text) 14%, transparent);
        overflow: hidden;
      }
      .hero-inner {
        position: relative;
        display: flex;
        align-items: flex-end;
        justify-content: space-between;
        gap: 28px;
        flex-wrap: wrap;
        padding: 22px max(20px, var(--safe-right)) 24px max(20px, var(--safe-left));
        max-width: 1240px;
        margin: 0 auto;
      }
      /* Vertical stack: identity strip → title → category sub-line → pills. */
      .hero-meta {
        flex: 1;
        min-width: 280px;
        display: flex;
        flex-direction: column;
        gap: 12px;
      }
      .hero-top {
        display: flex;
        align-items: center;
        gap: 12px;
        min-width: 0;
      }
      .hero-top .fund-mark {
        flex-shrink: 0;
        box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);
      }
      .hero-ident {
        display: flex;
        flex-direction: column;
        gap: 2px;
        min-width: 0;
      }
      .hero-manager {
        font-size: 13px;
        font-weight: 500;
        color: inherit;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
      .hero-subtitle {
        font-size: 13px;
        font-weight: 500;
        color: var(--color-text-secondary, color-mix(in srgb, CanvasText 60%, transparent));
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
      .hero-title {
        font-size: 28px;
        font-weight: 800;
        line-height: 1.15;
        margin: 0;
        letter-spacing: -0.02em;
        color: inherit;
      }
      .hero-sub {
        font-size: 13px;
        color: color-mix(in srgb, var(--cmp-surface-text) 82%, transparent);
        display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
      }
      .hero-sub .mono { font-variant-numeric: tabular-nums; }
      .hero-pills {
        display: flex;
        flex-wrap: wrap;
        gap: 6px;
      }
      .hero-pill {
        display: inline-flex; align-items: center;
        padding: 4px 11px;
        border-radius: 999px;
        background: color-mix(in srgb, var(--cmp-surface-text) 10%, transparent);
        border: 1px solid color-mix(in srgb, var(--cmp-surface-text) 16%, transparent);
        font-size: 11px;
        font-weight: 600;
        letter-spacing: 0.01em;
        color: color-mix(in srgb, var(--cmp-surface-text) 92%, transparent);
      }

      .isin-pill {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        font-size: 11px; font-weight: 600; letter-spacing: 0.02em;
      }
      .isin-copy-btn {
        display: inline-flex; align-items: center; justify-content: center;
        /* Visible chip stays 22×22 (content-box). Hit area is 44×44 to meet
           WCAG 2.5.5 / 2.5.8 (44pt minimum). Padding 11px expands border-box
           to 44×44; negative vertical margin -11px collapses layout back to
           22px so the manager + ISIN row still matches the 44px logo height. */
        width: 44px; height: 44px; padding: 11px;
        margin: -11px 0;
        background: color-mix(in srgb, var(--cmp-surface-text) 12%, transparent);
        background-clip: content-box;
        background-origin: content-box;
        border: 0;
        border-radius: 17px; /* content-box visual radius = 17 − 11 = 6px (same soft-pill aesthetic as before the 44×44 hit-area bump) */
        color: color-mix(in srgb, var(--cmp-surface-text) 85%, transparent);
        cursor: pointer;
        transition: background var(--motion-fast, 150ms) ease, color var(--motion-fast, 150ms) ease;
      }
      .isin-copy-btn:hover {
        background: color-mix(in srgb, var(--cmp-surface-text) 22%, transparent);
        color: var(--cmp-surface-text);
      }
      .isin-copy-btn .check-icon { display: none; }
      .isin-copy-btn.copied {
        background: color-mix(in srgb, var(--cmp-surface-text) 95%, transparent);
        color: var(--brand-pos);
      }
      .isin-copy-btn.copied .copy-icon { display: none; }
      .isin-copy-btn.copied .check-icon { display: inline-block; }

      .hero-perf {
        display: flex;
        align-items: stretch;
        flex-wrap: wrap;
        gap: 14px 18px;
        background: color-mix(in srgb, Canvas 96%, transparent);
        border-radius: 14px;
        padding: 14px 18px;
      }
      .perf-block { display: flex; flex-direction: column; gap: 2px; flex-shrink: 0; }
      .perf-big {
        font-size: 28px; font-weight: 800;
        letter-spacing: -0.02em;
        font-variant-numeric: tabular-nums;
        line-height: 1.1;
        color: var(--brand-text);
      }
      .perf-big.pos { color: var(--brand-pos); }
      .perf-big.neg { color: var(--brand-neg); }
      .perf-big.muted { color: var(--brand-text-soft); }
      .perf-lbl {
        font-size: 10px;
        font-weight: 700;
        color: var(--brand-text-soft);
        text-transform: uppercase;
        letter-spacing: 0.05em;
      }
      .perf-divider { width: 1px; background: var(--brand-border, rgba(0, 0, 0, 0.12)); }
      .perf-strip {
        flex: 1 1 auto; min-width: 0;
        display: flex; gap: 16px;
        align-items: center;
      }
      .perf-strip > div { display: flex; flex-direction: column; gap: 2px; }
      .perf-strip .lbl {
        font-size: 9px;
        font-weight: 800;
        color: var(--brand-text-soft);
        text-transform: uppercase;
        letter-spacing: 0.06em;
      }
      .perf-strip .v {
        font-size: 14px; font-weight: 700;
        font-variant-numeric: tabular-nums;
        letter-spacing: -0.01em;
        color: var(--brand-text);
      }
      .perf-strip .v.pos { color: var(--brand-pos); }
      .perf-strip .v.neg { color: var(--brand-neg); }
      .perf-strip .v.muted { color: var(--brand-text-soft); }
      @container (max-width: 480px) {
        .hero-inner { padding: 18px 18px; gap: 18px; }
        .hero-title { font-size: 22px; }
        .hero-perf { width: 100%; }
        .perf-divider { display: none; }
        .perf-strip {
          width: 100%;
          flex-basis: 100%;
          justify-content: space-between;
          gap: 12px;
        }
        .perf-big { font-size: 24px; }
      }

      .fs-desc p { margin: 0; font-size: 13px; line-height: 1.55; color: var(--brand-text); }
      .link-btn { background: none; border: 0; padding: 6px 0; font: inherit; font-weight: 600; font-size: 12px; color: var(--app-accent-fg); cursor: pointer; }

      .section-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
      .section-head h2 { margin: 0; font-size: 15px; font-weight: 700; color: var(--brand-text); letter-spacing: -0.01em; }
      .section-meta { font-size: 11px; color: var(--brand-text-soft); font-weight: 600; }

      /* Columns size to the number of present years — funds missing the
         oldest years still fill the container evenly instead of being
         flushed to one side. */
      .year-bars-row {
        display: grid;
        grid-auto-flow: column;
        grid-auto-columns: minmax(0, 1fr);
        gap: 8px;
      }

      .kpi-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }

      /* Year-bars + KPI grid live in a flow column under 880px, then split
         into a 2-col layout above that: chart fills the left, KPI tiles
         stack on the right. Mirrors the artifact's wide-screen mock. */
      .fs-stats-row { display: contents; }
      .fs-stats-row > .fs-year-bars,
      .fs-stats-row > .fs-kpis { min-width: 0; }
      @container (min-width: 880px) {
        .fs-stats-row {
          display: grid;
          grid-template-columns: minmax(0, 2fr) minmax(260px, 1fr);
          gap: 16px;
          align-items: stretch;
        }
        .fs-stats-row > .fs-year-bars,
        .fs-stats-row > .fs-kpis {
          margin: 0;
        }
        .fs-stats-row > .fs-kpis .kpi-grid {
          grid-template-columns: 1fr;
          gap: 10px;
          height: 100%;
        }
      }

      /* Side-by-side composite row used by ficha to put two cards
         next to each other (donut + sectors, SRRI + volatility).
         `align-items: stretch` (grid default) keeps both cards the same
         height; the taller one sets the row. */
      .fs-row-2 {
        display: grid;
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        gap: 16px;
      }
      .fs-row-2 > section { padding: 0; display: flex; flex-direction: column; min-width: 0; }
      .fs-row-2 > section > .alloc-row,
      .fs-row-2 > section > .hbar-list { flex: 1; }
      @container (max-width: 720px) {
        .fs-row-2 { grid-template-columns: minmax(0, 1fr); }
      }

      .alloc-row { display: flex; align-items: center; gap: 24px; }
      .alloc-legend { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; flex: 1; min-width: 0; }
      .alloc-legend li { display: grid; grid-template-columns: 14px minmax(0, 1fr) auto; gap: 8px; align-items: center; font-size: 12px; }
      .legend-swatch { width: 12px; height: 12px; border-radius: 3px; display: inline-block; }
      .legend-label { color: var(--brand-text); font-weight: 500; }
      .legend-pct { color: var(--brand-text-soft); font-variant-numeric: tabular-nums; font-weight: 600; }

      .hbar-list { display: flex; flex-direction: column; gap: 4px; }

      .risk-explainer { margin: 12px 0 0; font-size: 12px; line-height: 1.5; color: var(--brand-text-soft); }

      .vol-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
      .vol-tracking { display: flex; justify-content: space-between; align-items: center; padding: 12px 0 0; font-size: 12px; color: var(--brand-text-soft); border-top: 1px solid var(--brand-border); margin-top: 12px; }
      .vol-tracking strong { color: var(--brand-text); font-weight: 700; font-variant-numeric: tabular-nums; }

      .kv-list { display: flex; flex-direction: column; gap: 6px; }
      .kv-row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--brand-border); font-size: 12px; }
      .kv-row:last-child { border-bottom: 0; }
      .kv-label { color: var(--brand-text-soft); font-weight: 500; }
      .kv-value { color: var(--brand-text); font-weight: 600; font-variant-numeric: tabular-nums; margin: 0; }

      .fs-footer { padding: 16px 0; font-size: 11px; color: var(--brand-text-mute); text-align: center; }

      /* Section cards: cream surface, hairline border, generous radius.
         Hero, description, and footer opt out (.hero has its own dark surface;
         description + footer are inline blocks). */
      .fs-body > section:not(.hero):not(.fs-desc):not(.fs-footer):not(.fs-warning),
      .fs-row-2 > section,
      .fs-stats-row > section {
        background: var(--brand-bg-cream);
        border: 1px solid var(--brand-border);
        border-radius: var(--app-radius-2xl, 18px);
        padding: 18px 20px;
      }

      /* Fees + Operativa: 2-column grid. Row borders sit BELOW each cell so
         siblings on the same row align cleanly. Collapses to 1-col under 720px. */
      .fs-fees .kv-list,
      .fs-operativa .kv-list {
        display: grid;
        grid-template-columns: 1fr 1fr;
        column-gap: 28px;
        row-gap: 0;
      }
      .fs-fees .kv-row,
      .fs-operativa .kv-row {
        border-bottom: 1px solid var(--brand-border);
      }
      .fs-fees .kv-row:nth-last-child(-n+2),
      .fs-operativa .kv-row:nth-last-child(-n+2) { border-bottom: 0; }
      @container (max-width: 720px) {
        .fs-fees .kv-list,
        .fs-operativa .kv-list { grid-template-columns: 1fr; }
        .fs-fees .kv-row,
        .fs-operativa .kv-row { border-bottom: 1px solid var(--brand-border); }
        .fs-fees .kv-row:last-child,
        .fs-operativa .kv-row:last-child { border-bottom: 0; }
      }

      /* Regiones: when 2 or fewer, render as side-by-side big numbers with
         a thin bar beneath. Hidden when there are >2 regions (the hbar
         list fallback handles those). */
      .regions-grid {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 32px;
        align-items: end;
      }
      .region-block { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
      .region-name { font-size: 12px; color: var(--brand-text-soft); font-weight: 500; }
      .region-pct {
        font-size: 22px; font-weight: 700;
        color: var(--brand-text);
        font-variant-numeric: tabular-nums;
        letter-spacing: -0.01em;
      }
      .region-pct .unit { font-size: 14px; font-weight: 600; color: var(--brand-text-soft); margin-left: 4px; }
      .region-bar { height: 4px; background: var(--brand-bg-soft); border-radius: var(--app-pill); overflow: hidden; }
      .region-fill { height: 100%; background: var(--brand-accent); border-radius: inherit; }

      /* ----- Comparator layout ----- */
      /* Full-bleed dark hero at the top (rounds only at the bottom, mirrors
         the ficha hero). Sections below are centered with their own max-width
         and side padding. */
      .cmp-overlay { padding: 0; }
      /* `padding-bottom` matches the ficha (`.fs-panel`): the sticky CTA sits
         inside the panel and its own `margin-bottom: 8px + safe-bottom`
         already gives breathing room. Earlier 120px floor was legacy from a
         floating-CTA layout and caused a huge empty area at the bottom of
         the page. */
      .cmp-panel { display: flex; flex-direction: column; gap: 14px; padding-bottom: max(16px, calc(8px + var(--safe-bottom))); container-type: inline-size; }

      /* Hero shares --cmp-surface with the floating CTA so the comparator
         opens and closes on the same panel treatment. Light = brand light
         blue (#ECF5FF); dark = deep navy (#001f3d). Fund cards inside
         (.fic-card) keep their canvas-bg, so they pop as tinted tiles on the
         surface in either theme. */
      .cmp-hero {
        background: var(--cmp-surface);
        color: var(--cmp-surface-text);
        border-bottom: 1px solid color-mix(in srgb, var(--cmp-surface-text) 14%, transparent);
        border-radius: 0 0 var(--app-radius-hero) var(--app-radius-hero);
        padding-top: max(0px, var(--safe-top));
      }
      .cmp-hero-inner {
        max-width: 1080px;
        margin: 0 auto;
        padding: 20px max(20px, var(--safe-right)) 20px max(20px, var(--safe-left));
        display: flex;
        flex-direction: column;
        gap: 14px;
      }
      .cmp-hero .cmp-header { padding: 0; gap: 4px; }
      .cmp-hero .cmp-header h1 {
        /* Same clamp pattern as `.cc-wrap h1`, scaled larger for the
           full-hero context (20→26 instead of 18→22). The previous explicit
           20px override at 480px is now absorbed by the clamp. */
        font-size: clamp(20px, 4.5cqi, 26px);
        letter-spacing: -0.02em; line-height: 1.18;
        color: var(--cmp-surface-text);
      }
      .cmp-hero .cmp-kicker { color: color-mix(in srgb, var(--cmp-surface-text) 70%, transparent); }
      .cmp-hero .cmp-missing {
        background: color-mix(in srgb, var(--cmp-surface-text) 10%, transparent);
        color: color-mix(in srgb, var(--cmp-surface-text) 86%, transparent);
      }
      @container (max-width: 480px) {
        .cmp-hero-inner { padding: 14px 16px 16px; gap: 12px; }
        /* `.cmp-hero .cmp-header h1` size is governed by its clamp above. */
      }

      .cmp-body {
        max-width: 1080px;
        margin: 0 auto;
        width: 100%;
        box-sizing: border-box;
        padding: 4px max(20px, var(--safe-right)) 8px max(20px, var(--safe-left));
        display: flex;
        flex-direction: column;
        gap: 14px;
      }

      .cmp-header { display: flex; flex-direction: column; gap: 4px; padding: 8px 0; }
      .cmp-kicker { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--brand-text-soft); }
      .cmp-header h1 { margin: 0; font-size: 20px; font-weight: 700; color: var(--brand-text); letter-spacing: -0.01em; }
      .cmp-missing { margin-top: 6px; padding: 8px 12px; border-radius: 8px; background: var(--brand-bg-soft); font-size: 12px; color: var(--brand-text-soft); }

      /* `--cmp-fund-count` is set inline on `.cmp-overlay` to `funds.length`.
         Hero cards, history columns and flat-row cells all scale to that
         count so 2-fund comparisons don't leave an empty third slot. */
      .cmp-fund-cards { display: grid; grid-template-columns: repeat(var(--cmp-fund-count, 3), 1fr); gap: 12px; }

      /* Fund identity card — single component shared by:
         · the comparator hero (`.fic-card--interactive`, opens the ficha)
         · the collapsed-comparator tile (static, with row-in stagger).
         One grid layout drives both surfaces. Previously two near-identical
         `.cmp-fc-*` and `.cc-tile-*` blocks lived side by side and had to be
         hand-synced; see AUDIT.md M-3. */
      .fic-card {
        display: grid;
        grid-template-columns: auto auto 1fr;
        gap: 4px 10px;
        padding: 16px;
        background: var(--app-bg);
        border: 1px solid var(--app-border);
        border-radius: var(--app-radius-lg, 12px);
      }
      .fic-card--interactive {
        cursor: pointer;
        transition: background var(--motion-fast);
      }
      .fic-card--interactive:hover { background: color-mix(in srgb, var(--app-text) 4%, var(--app-bg) 96%); }
      .fic-card-letter {
        grid-row: 1;
        font-size: 13px; font-weight: 700;
        color: var(--fund-color, var(--app-text-soft));
        align-self: start;
      }
      .fic-card-mark { grid-row: 1; align-self: start; }
      .fic-card-meta { grid-row: 1; min-width: 0; }
      .fic-card-name { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
      .fic-card-sub { font-size: 11px; color: var(--app-text-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
      /* Morningstar category line — mirrors the ficha hero sub-line and the
         carousel card. Spans the full card so the longer Spanish category
         names (e.g. "RV Tecnología y Comunicaciones") have room to ellipse. */
      .fic-card-category {
        grid-column: 1 / -1;
        font-size: 11px; font-weight: 500;
        color: var(--app-text-soft);
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
        margin-top: 8px;
      }
      .fic-card-pills {
        grid-column: 1 / -1;
        display: flex; flex-wrap: wrap;
        gap: 4px;
        margin-top: 2px;
      }
      .fic-card-pill {
        display: inline-flex; align-items: center;
        padding: 2px 8px;
        border-radius: var(--app-pill);
        background: var(--app-bg-soft);
        border: 1px solid var(--app-border);
        font-size: 10px; font-weight: 600;
        letter-spacing: 0.01em;
        color: var(--app-text-soft);
      }
      .fic-card-kpi {
        grid-column: 1 / -1;
        display: flex; align-items: center; justify-content: space-between;
        gap: 8px; padding-top: 10px;
        border-top: 1px solid var(--app-border);
        margin-top: 6px;
      }
      .fic-card-kpi-label { font-size: 10px; font-weight: 700; text-transform: uppercase; color: var(--app-muted); letter-spacing: 0.08em; }
      .fic-card-kpi-value { font-size: 22px; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
      .fic-card-detail {
        grid-column: 1 / -1;
        display: flex; align-items: center; justify-content: center; gap: 4px;
        padding: 6px 12px;
        border-radius: var(--app-pill);
        border: 1px solid var(--app-accent-fg);
        color: var(--app-accent-fg);
        font-family: inherit;
        font-size: 13px; font-weight: 600;
        line-height: 1;
        letter-spacing: 0.02em;
        pointer-events: none;
        transition: background var(--motion-fast);
        margin-top: 2px;
      }
      .fic-card--interactive:hover .fic-card-detail { background: color-mix(in srgb, var(--app-accent-fg) 18%, transparent); }
      /* Portfolio identity card variant: tint the surface with the per-portfolio
         identity color (set inline via `--fund-color`). Funds keep the flat
         `--app-bg` surface; portfolios pick up an A/B/C-coded pastel so the
         identity is reinforced beyond just the letter glyph. */
      .fic-card.is-portfolio {
        background: color-mix(in srgb, var(--fund-color, var(--app-accent)) 8%, var(--app-bg));
      }
      .fic-card.is-portfolio.fic-card--interactive:hover {
        background: color-mix(in srgb, var(--fund-color, var(--app-accent)) 14%, var(--app-bg));
      }

      /* Comparator content sections: light cards matching the ficha. */
      .cmp-section {
        background: var(--brand-bg-cream);
        border: 1px solid var(--brand-border);
        border-radius: var(--app-radius-2xl, 18px);
        padding: 20px 22px;
      }
      /* ── Flat-row tables (Rentabilidad / Coste / Operativa / Cartera) ── */
      .cmp-flat { display: flex; flex-direction: column; }
      .cmp-frow {
        display: grid;
        grid-template-columns: minmax(140px, 200px) repeat(var(--cmp-fund-count, 3), 1fr);
        align-items: center;
        gap: 12px;
        padding: 14px 0;
        border-top: 1px solid var(--brand-border);
        min-height: 56px;
      }
      .cmp-frow:first-child { border-top: 0; padding-top: 4px; }
      .cmp-frow-label { font-size: 13px; font-weight: 500; color: var(--brand-text); line-height: 1.3; }
      .cmp-frow-sub { display: block; font-size: 11px; color: var(--brand-text-soft); font-weight: 400; margin-top: 2px; }
      .cmp-frow-cell {
        display: flex; align-items: center; gap: 8px;
        font-size: 14px; font-weight: 700;
        font-variant-numeric: tabular-nums;
        color: var(--brand-text);
        min-width: 0;
      }
      .cmp-frow-val { display: inline-flex; align-items: center; }
      .cmp-frow-val-wrap { display: flex; flex-direction: column; gap: 1px; }
      .cmp-frow-cell-sub { font-size: 11px; color: var(--brand-text-soft); font-weight: 400; }
      /* Fund-letter chip per cell. Hidden on desktop (the column position
         already identifies the fund); revealed on narrow viewports where
         cells collapse into a single column. */
      .cmp-frow-letter {
        display: none;
        place-items: center;
        flex-shrink: 0;
        width: 20px; height: 20px;
        border-radius: 5px;
        color: #fff;
        font-weight: 800; font-size: 11px;
      }

      /* Table header row: maps each value column to its fund (letter chip +
         manager / name). The row uses the same `cmp-frow` grid so columns
         line up exactly. Borderless and tighter than data rows. Hidden on
         narrow viewports — the per-cell letter chip takes over there. */
      .cmp-frow-head {
        border-top: 0;
        padding: 4px 0 10px;
        min-height: 0;
      }
      .cmp-frow-head + .cmp-frow { border-top: 1px solid var(--brand-border); padding-top: 14px; }
      .cmp-frow-head-cell {
        display: flex; align-items: center; gap: 8px;
        font-size: 12px; font-weight: 600;
        color: var(--brand-text-soft);
        min-width: 0;
      }
      .cmp-frow-head-letter {
        display: inline-grid; place-items: center;
        flex-shrink: 0;
        width: 22px; height: 22px;
        border-radius: 6px;
        color: #fff;
        font-weight: 800; font-size: 11px;
      }
      .cmp-frow-head-name {
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
      }

      /* Distribución + Top sectores: per-fund stacked bar + dot-labelled items. */
      .cmp-frow-sectors { align-items: start; }
      .cmp-frow-sectors-cell {
        flex-direction: column;
        align-items: stretch;
        gap: 10px;
        padding: 12px 14px;
        background: var(--brand-bg-soft);
        border-radius: var(--app-radius, 10px);
        font-size: 12px; font-weight: 500;
      }
      .cmp-frow-sectors-head { display: flex; align-items: center; gap: 8px; }
      .cmp-frow-sectors-letter {
        display: inline-grid; place-items: center;
        flex-shrink: 0;
        width: 22px; height: 22px;
        border-radius: 6px;
        background: var(--brand-accent);
        color: #fff;
        font-weight: 800; font-size: 11px;
      }
      .cmp-frow-sectors-name {
        font-size: 12px; font-weight: 600;
        color: var(--brand-text-soft);
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
        min-width: 0;
      }
      .cmp-sec-bar {
        display: flex;
        height: 8px;
        border-radius: 999px;
        overflow: hidden;
        background: var(--app-bg);
      }
      .cmp-sec-seg { min-width: 2px; height: 100%; }
      .cmp-sec-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
      .cmp-sec-list li { display: flex; align-items: center; gap: 8px; color: var(--brand-text); font-size: 12px; }
      .cmp-sec-dot { flex-shrink: 0; width: 8px; height: 8px; border-radius: 2px; display: inline-block; }
      .cmp-sec-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
      .cmp-sec-pct { color: var(--brand-text-soft); font-variant-numeric: tabular-nums; font-weight: 600; flex-shrink: 0; }
      .cmp-sec-empty { color: var(--brand-text-mute); text-align: center; font-size: 12px; }

      /* Comparator sticky CTA: shares --cmp-surface with the hero so they
         bookend the comparison view in the same brand colour (light blue in
         light mode, navy in dark). The 3 fund-coloured pill buttons inside
         stay on the brand-navy --app-accent regardless of theme so the
         "Comprar" affordance is unmistakable. */
      .cmp-cta {
        position: sticky;
        bottom: var(--safe-bottom);
        z-index: 4;
        display: flex; align-items: center; gap: 14px;
        padding: 14px 20px;
        margin: 4px auto calc(8px + var(--safe-bottom));
        width: calc(100% - max(20px, var(--safe-left)) - max(20px, var(--safe-right)));
        max-width: 1040px;
        box-sizing: border-box;
        background: var(--cmp-surface);
        color: var(--cmp-surface-text);
        border-radius: 999px;
        box-shadow: 0 10px 28px var(--app-shadow-c-cta);
      }
      .cmp-cta .grow { flex: 1; }
      .cmp-cta .cta-label {
        font-size: 11px; font-weight: 700;
        letter-spacing: 0.08em; text-transform: uppercase;
        color: color-mix(in srgb, var(--cmp-surface-text) 65%, transparent);
      }
      .cmp-buy-actions { display: flex; gap: 8px; flex-wrap: wrap; }
      .cmp-buy-btn {
        display: inline-flex; align-items: center; gap: 8px;
        min-height: var(--tap-target);
        padding: 6px 14px 6px 6px;
        border: 0;
        border-radius: 999px;
        /* Light mode = saturated brand blue + white text; dark mode swaps to
           the lifted #80a8ff on dark navy text so the pill blends with the
           dark comparator palette while keeping AA contrast. */
        background: var(--app-accent);
        color: var(--app-accent-on);
        font-size: 13px; font-weight: 700;
        cursor: pointer;
        /* See .pill-btn note — kills text I-beam over the inner name <span>
           so the whole pill reads as one button, without disabling pointer
           events on the children. */
        user-select: none;
        -webkit-user-select: none;
        touch-action: manipulation;
        transition: filter var(--motion-fast, 160ms) ease, transform var(--motion-fast, 160ms) ease;
      }
      .cmp-buy-btn:hover { filter: brightness(1.08); }
      .cmp-buy-btn:active { transform: translateY(1px); }
      .cmp-buy-letter {
        display: inline-grid; place-items: center;
        width: 24px; height: 24px;
        border-radius: 8px;
        color: #fff;
        font-weight: 800; font-size: 11px;
      }
      .cmp-buy-name {
        line-height: 1;
        max-width: 28ch;
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
      }
      .cmp-buy-btn svg { opacity: 0.9; }
      @container (max-width: 480px) {
        .cmp-cta { padding: 12px 14px; gap: 10px; }
        .cmp-buy-btn { padding: 5px 12px 5px 5px; font-size: 12px; }
        .cmp-buy-letter { width: 22px; height: 22px; }
      }

      @container (max-width: 700px) {
        .cmp-fund-cards { grid-template-columns: 1fr; gap: 10px; }
        .fic-card { padding: 14px; }
        .fic-card-kpi { padding-top: 8px; margin-top: 4px; }
        .cmp-frow { grid-template-columns: 1fr; gap: 4px; min-height: 0; padding: 10px 0; }
        .cmp-frow-head { display: none; }
        .cmp-frow-sectors-cell { width: 100%; }
        .cmp-frow-letter { display: inline-grid; }
        .cmp-section { padding: 16px 18px; }
        /* Stack label above buttons so "Comprar en MyInvestor" stays visible
           on phones (the wide-screen single-row pill is too tight at <700px
           once 3 buy-pills are in play). Pill shape becomes a soft rounded
           rectangle when stacked — `border-radius: 999px` looks awkward on a
           two-row CTA. */
        .cmp-cta {
          flex-direction: column;
          align-items: stretch;
          gap: 10px;
          border-radius: 18px;
          padding: 12px 16px 14px;
        }
        .cmp-cta .grow { display: none; }
        .cmp-cta .cta-label { text-align: left; }
        /* Names stay visible on mobile too (per user feedback); pills wrap to
           a second row if needed. Tighter cap on mobile so two pills fit per
           row; the `title` attribute on .cmp-buy-name lets users tap-and-hold
           to see the full fund name. */
        .cmp-buy-actions { justify-content: flex-start; }
        .cmp-buy-name { max-width: 18ch; }
      }

      /* ----- Sticky CTA additions — colors adapt via --cmp-surface-text ----- */
      .cta-summary { display: flex; gap: 24px; align-items: center; }
      .cta-nav, .cta-min { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
      .cta-nav-label, .cta-min-label { font-size: 10px; font-weight: 700; text-transform: uppercase; color: color-mix(in srgb, var(--cmp-surface-text) 55%, transparent); letter-spacing: 0.08em; }
      .cta-nav-value, .cta-min-value { font-size: 13px; font-weight: 700; color: var(--cmp-surface-text); font-variant-numeric: tabular-nums; }

      /* ----- Narrow viewports ----- */
      @container (max-width: 480px) {
        .kpi-grid, .vol-grid { grid-template-columns: 1fr; }
        .year-bars-row { gap: 4px; }
        .fs-year-bars .rt-bar { height: 150px; }
        .fs-year-bars .rt-val { font-size: 11px; }
        .fs-year-bars .rt-sub { font-size: 10px; }
        .alloc-row { flex-direction: column; align-items: center; gap: 16px; }
        .cta-summary { display: none; }
      }
      @container (max-width: 360px) {
        .fs-year-bars .rt-val { font-size: 10px; }
        .fs-year-bars .rt-sub { font-size: 9px; }
      }

      /* ─── Portfolio Mark ────────────────────────────────────────────────────── */
      .portfolio-mark {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        color: #fff;
        font-weight: 700;
        letter-spacing: 0.02em;
        overflow: hidden;
        position: relative;
        flex-shrink: 0;
      }
      .portfolio-mark img {
        width: 100%;
        height: 100%;
        object-fit: contain;
        padding: 6px;
        box-sizing: border-box;
      }

      /* ─── Risk Scale 1..5 ───────────────────────────────────────────────────── */
      .risk5-scale { display: flex; flex-direction: column; gap: 8px; }
      .risk5-track { display: grid; grid-template-columns: repeat(5, 1fr); gap: 4px; }
      .risk5-seg {
        height: 12px;
        border-radius: 4px;
        background: color-mix(in srgb, CanvasText 10%, transparent);
        transition: transform 120ms ease;
      }
      .risk5-seg[data-active="1"] { transform: scaleY(1.4); }
      .risk5-labels {
        display: flex;
        justify-content: space-between;
        font-size: 11px;
        opacity: 0.65;
      }

      /* ─── Portfolio tile overrides (`.ic-card.is-portfolio`) ──────────────────
         Carteras reuse the fund tile (.ic-card / .ic-card-* / .ic-tile-*) so
         both surfaces share the same tokens, shadow, hover lift, pill CTA
         radius, tap target and dark-mode behavior. The only divergence is the
         `.ic-card-category` slot: funds put a single-line Morningstar category
         there, portfolios put a multi-line marketing description, so override
         the single-line ellipsis with a 2-line clamp on the portfolio variant. */
      .ic-card.is-portfolio .ic-card-category {
        white-space: normal;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
      }

      /* ─── Ficha sections ────────────────────────────────────────────────────── */
      /* `.pf-allocation .alloc-row` inherits the shared `.alloc-row` flex layout
         (donut left, legend right) so the `@container (max-width: 480px) .alloc-row
         { flex-direction: column }` mobile rule used by the fund ficha applies
         here too — at narrow widths the donut stacks above the legend. */
      .pf-funds-list { display: flex; flex-direction: column; max-height: 320px; overflow-y: auto; }
      .pf-fund-row {
        display: flex; gap: 12px; align-items: center;
        padding: 10px 0;
        border-bottom: 1px solid color-mix(in srgb, CanvasText 8%, transparent);
      }
      .pf-fund-row:last-child { border-bottom: 0; }
      .pf-fund-name { flex: 1; min-width: 0; }
      .pf-fund-text .n { font-size: 13px; font-weight: 600; line-height: 1.35; display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
      .pf-fund-text .isin { font-size: 11px; line-height: 1.35; opacity: 0.65; }
      .pf-fund-pct { font-weight: 700; color: var(--app-accent); font-size: 13px; }
      .pf-fund-overflow { font-size: 12px; opacity: 0.65; padding: 8px 0; }
      .pf-composition .hbar-list { display: flex; flex-direction: column; gap: 8px; }
      /* Cancel the generic border-top rule so pf-fees uses only border-bottom (single separator). */
      .pf-fees .kv-list .kv-row + .kv-row { border-top: none; }
      .pf-fees-tiers { width: 100%; font-size: 12px; border-collapse: collapse; }
      .pf-fees-tiers th, .pf-fees-tiers td { text-align: left; padding: 6px 4px; border-bottom: 1px solid color-mix(in srgb, CanvasText 8%, transparent); }
      .pf-fees-tiers thead th { font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em; opacity: 0.7; }
      .pf-risk { display: flex; flex-direction: column; gap: 12px; }
      .pf-risk .risk-explainer { font-size: 12.5px; opacity: 0.75; line-height: 1.5; }
    

  

/* ── Wealth MCP overrides ─────────────────────────────────── */
:root {
  --app-accent: #6E59E0;
  --app-accent-fg: #6E59E0;
  --app-accent-on: #ffffff;
  --cmp-surface: #F1EEFB;
  --app-bg-card: #F6F4FD;
  --app-bg-cream: #F7F6FB;
}
.mim-live { --app-accent: #6E59E0; --app-accent-fg: #6E59E0; }
