
  .mq-curve-hero {
    width: min(100%, 1440px);
    margin: 18px auto 0;
    padding: 18px 20px 16px;
    background: var(--mq-surface);
    border: 1px solid var(--mq-line);
    border-radius: var(--r-card);
    box-shadow: var(--mq-shadow);
    color: var(--mq-ink);
  }
  .mq-curve-hero h2 {
    margin: 0;
    font-size: clamp(20px, 2.4vw, 28px);
    letter-spacing: -0.03em;
  }
  .mq-curve-sub { margin: 6px 0 0; color: var(--mq-muted); font-size: 13px; }
  .mq-curve-asof { margin: 4px 0 0; color: var(--mq-muted); font-size: 12px; }
  .mq-curve-chart { margin: 14px 0 8px; }
  .mq-curve-plot { position: relative; max-width: 640px; }
  .mq-curve-plot svg { display: block; width: 100%; height: auto; }
  .mq-curve-line-today { fill: none; stroke: var(--mq-ink); stroke-width: 2.2; }
  .mq-curve-line-close { fill: none; stroke: var(--mq-accent); stroke-width: 1.6; }
  .mq-curve-line-month { fill: none; stroke: var(--mq-muted); stroke-width: 1.4; stroke-dasharray: 4 3; }
  .mq-curve-axis { stroke: var(--mq-line-strong); stroke-width: 1; }
  .mq-curve-xlabels,
  .mq-curve-ylabels {
    position: absolute; inset: 0; margin: 0; padding: 0; list-style: none;
    pointer-events: none;
  }
  .mq-curve-xlabels li,
  .mq-curve-ylabels li {
    position: absolute;
    color: var(--mq-muted);
    font-size: 10px; /* CSS px — does not scale with the SVG viewBox */
    line-height: 1;
    white-space: nowrap;
  }
  .mq-curve-xlabels li {
    top: auto;
    bottom: 2px;
    transform: translateX(-50%);
  }
  .mq-curve-xlabels li.is-last { transform: translateX(-100%); }
  .mq-curve-xlabel-short { display: none; }
  .mq-curve-ylabels li {
    left: 0;
    /* Exactly pad_l/width from lib.macro_suite_view._chart_payload (72/640).
       There is deliberately no media-query override of this width: a wider box
       would overhang the plot and the lowest tick would sit under the data. */
    width: 11.25%;
    text-align: right;
    transform: translateY(-50%);
    box-sizing: border-box;
    padding-right: 4px;
  }
  .mq-curve-legend {
    display: flex; flex-wrap: wrap; gap: 12px 18px;
    margin: 0 0 12px; padding: 0; list-style: none;
    color: var(--mq-muted); font-size: 12px;
  }
  .mq-curve-legend i {
    display: inline-block; width: 16px; height: 2px; margin-right: 6px;
    vertical-align: middle; background: currentColor;
  }
  .mq-curve-legend .is-today { color: var(--mq-ink); }
  .mq-curve-legend .is-close { color: var(--mq-accent); }
  .mq-curve-legend .is-month { color: var(--mq-muted); }
  .mq-curve-legend .is-month i { border-top: 2px dashed currentColor; height: 0; background: none; }
  .mq-curve-legend .is-null { color: var(--mq-muted); }
  .mq-curve-legend .is-null i { display: none; }
  .mq-curve-spreads {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 10px; margin: 0 0 12px;
  }
  .mq-curve-spread {
    padding: 10px 12px;
    background: var(--mq-raised);
    border: 1px solid var(--mq-line);
    border-radius: var(--r-ctl);
  }
  .mq-curve-spread dt { margin: 0; color: var(--mq-muted); font-size: 11px; }
  .mq-curve-spread dd { margin: 4px 0 0; font-size: 20px; letter-spacing: -0.03em; }
  .mq-curve-deltas { margin: 6px 0 0; color: var(--mq-muted); font-size: 11px; }
  .mq-curve-shape { margin: 0; max-width: 62ch; font-size: 14px; }
  .mq-curve-null { margin: 12px 0 0; color: var(--mq-muted); font-size: 14px; }
  .mq-curve-missing { margin: 8px 0 0; color: var(--mq-muted); font-size: 12px; }
  @media (max-width: 640px) {
    .mq-curve-hero { margin: 12px 0 0; padding: 14px 12px 12px; }
    .mq-curve-spread dd { font-size: 18px; }
    .mq-curve-xlabels li,
    .mq-curve-ylabels li { font-size: 10px; }
    .mq-curve-xlabel-long { display: none; }
    .mq-curve-xlabel-short { display: inline; }
    /* Ten tenor labels cannot clear each other at 390. The five the builder
       does not mark `mobile` keep their <li> and are hidden here only. */
    .mq-curve-xlabels li.is-mobile-hidden { visibility: hidden; }
  }
