/* IPO dashboard (/ipo/, IPO_TRACKER.md). Built on market.css tokens (--ff-*). */

.ipo-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); gap: 14px; margin-bottom: 14px; }
.ipo-card { background: var(--ff-card); border: 1px solid var(--ff-border); border-radius: var(--ff-radius);
  box-shadow: var(--ff-shadow); padding: 14px 16px; min-width: 0; display: flex; flex-direction: column; gap: 10px; }
.ipo-card:hover { box-shadow: var(--ff-shadow-hover); }
.ipo-card-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; }
.ipo-card-head h3 { margin: 0; font-size: 1.02rem; line-height: 1.3; }
.ipo-card-head h3 a { color: var(--ff-primary); text-decoration: none; }
.ipo-card-head h3 a:hover { text-decoration: underline; }
.ipo-meta { font-size: .78rem; color: var(--ff-text-soft); line-height: 1.5; }
.ipo-facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
.ipo-facts div { background: var(--ff-bg); border: 1px solid var(--ff-border-soft); border-radius: var(--ff-radius-sm);
  padding: 6px 8px; min-width: 0; }
.ipo-facts .k { display: block; font-size: .64rem; text-transform: uppercase; letter-spacing: .04em; color: var(--ff-text-soft); font-weight: 600; }
.ipo-facts .v { display: block; font-size: .9rem; font-weight: 700; color: var(--ff-text); overflow-wrap: anywhere; }

/* subscription bars: log-scaled so 1x and 200x both read */
.ipo-subs { display: grid; gap: 5px; }
.ipo-sub { display: grid; grid-template-columns: 64px 1fr 62px; gap: 8px; align-items: center; font-size: .8rem; }
.ipo-sub .lab { color: var(--ff-text-soft); font-weight: 600; }
.ipo-sub .bar { height: 8px; background: var(--ff-neutral-soft); border-radius: 99px; overflow: hidden; }
.ipo-sub .bar i { display: block; height: 100%; border-radius: 99px; background: var(--ff-accent); }
.ipo-sub .bar i.under { background: var(--ff-warning); }
.ipo-sub .val { text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; }
.ipo-sub.total .lab, .ipo-sub.total .val { color: var(--ff-primary); }
.ipo-sub.total .bar i { background: var(--ff-primary-2); }

/* the estimate box */
.ipo-est { border-radius: var(--ff-radius-sm); padding: 10px 12px; border: 1px solid var(--ff-border);
  background: var(--ff-bg); }
.ipo-est.b-strong, .ipo-est.b-positive { background: var(--ff-success-soft); border-color: #bbf7d0; }
.ipo-est.b-modest { background: var(--ff-accent-soft); border-color: #c7dcf7; }
.ipo-est.b-flat { background: var(--ff-warning-soft); border-color: #fde68a; }
.ipo-est.b-weak { background: var(--ff-danger-soft); border-color: #fecaca; }
.ipo-est-top { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.ipo-est-label { font-size: .7rem; text-transform: uppercase; letter-spacing: .05em; font-weight: 700; color: var(--ff-text-soft); }
.ipo-est-band { font-weight: 700; font-size: .86rem; color: var(--ff-text); }
.ipo-est-nums { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-top: 6px; }
.ipo-est-nums .k { display: block; font-size: .66rem; color: var(--ff-text-soft); text-transform: uppercase; letter-spacing: .03em; font-weight: 600; }
.ipo-est-nums .v { display: block; font-size: 1.12rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.ipo-est-nums .s { display: block; font-size: .7rem; color: var(--ff-text-soft); }
.ipo-est-note { font-size: .7rem; color: var(--ff-text-soft); margin-top: 6px; line-height: 1.4; }

/* big estimate on the detail page */
.ipo-big { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; }
.ipo-big > div { background: var(--ff-card); border: 1px solid var(--ff-border); border-radius: var(--ff-radius-sm);
  padding: 10px 12px; min-width: 0; }
.ipo-big .k { font-size: .68rem; text-transform: uppercase; letter-spacing: .04em; color: var(--ff-text-soft); font-weight: 700; }
.ipo-big .v { font-size: 1.5rem; font-weight: 800; font-variant-numeric: tabular-nums; line-height: 1.2; }
.ipo-big .s { font-size: .74rem; color: var(--ff-text-soft); }
@media (max-width: 760px) { .ipo-big { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* probability meter */
.ipo-prob { height: 10px; border-radius: 99px; background: var(--ff-danger-soft); overflow: hidden; margin-top: 4px; }
.ipo-prob i { display: block; height: 100%; background: var(--ff-success); border-radius: 99px; }

.ipo-timeline { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 8px; }
.ipo-timeline li { border-left: 3px solid var(--ff-border); padding: 4px 0 4px 10px; font-size: .82rem; }
.ipo-timeline li.done { border-left-color: var(--ff-success); }
.ipo-timeline li.now { border-left-color: var(--ff-accent); background: var(--ff-accent-soft); border-radius: 0 6px 6px 0; }
.ipo-timeline .k { display: block; color: var(--ff-text-soft); font-size: .7rem; text-transform: uppercase; font-weight: 700; letter-spacing: .04em; }
.ipo-timeline .v { font-weight: 700; }

.ipo-st { font-size: .7rem; }
.ipo-num { font-variant-numeric: tabular-nums; }
.ipo-disclaimer { font-size: .8rem; color: var(--ff-text-soft); line-height: 1.55; background: var(--ff-warning-soft);
  border: 1px solid #fde68a; border-radius: var(--ff-radius-sm); padding: 10px 12px; margin: 14px 0; }
.ipo-disclaimer b { color: var(--ff-warning-deep); }

.ipo-form { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; align-items: end; }
.ipo-form label { display: flex; flex-direction: column; gap: 4px; font-size: .78rem; font-weight: 600; color: var(--ff-text-soft); }
.ipo-form input, .ipo-form select { font: inherit; font-size: .95rem; padding: 8px 10px; border: 1px solid var(--ff-border);
  border-radius: var(--ff-radius-sm); background: var(--ff-card); color: var(--ff-text); min-width: 0; }
.ipo-form input:focus, .ipo-form select:focus { outline: 2px solid var(--ff-accent); outline-offset: 1px; }
.ipo-form button { font: inherit; font-weight: 700; padding: 9px 14px; border-radius: var(--ff-radius-sm); border: 0;
  background: var(--ff-primary); color: #fff; cursor: pointer; }
.ipo-form button:hover { background: var(--ff-primary-2); }
.ipo-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 0; }
.ipo-chips button { font: inherit; font-size: .76rem; padding: 4px 10px; border-radius: 99px; border: 1px solid var(--ff-border);
  background: var(--ff-card); cursor: pointer; color: var(--ff-text); }
.ipo-chips button:hover { border-color: var(--ff-accent); color: var(--ff-accent); }
@media (max-width: 560px) {
  .ipo-grid { grid-template-columns: minmax(0, 1fr); }
  .ipo-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* "simulated" beside an AI estimate made by a back-test (was a superscript "bt" until 25 Oct 2026) */
.ipo-sim { display: inline-block; font-size: .64rem; font-weight: 600; letter-spacing: .02em; line-height: 1.5;
  color: var(--ff-neutral-deep); background: var(--ff-neutral-soft); border: 1px solid var(--ff-border);
  border-radius: 99px; padding: 0 6px; vertical-align: 1px; white-space: nowrap; font-variant-numeric: normal; }
td .ipo-sim { display: table; margin: 3px 0 0 auto; }

/* ==================================================================================
   /ipo/ additions (IPO_HUB_CHARTS.md, 25 Oct 2026): hero quick facts, calendar, timetable
   and the charts drawn on the server (ipo_charts.py). Colours: three event families checked
   for colour-blind separation (blue bidding, orange allotment and credit, green listing; the
   green is under 3:1 on white, so it always comes with a text label), gains green and losses
   red as in the tables, plain magnitudes blue.
   ================================================================================== */
:root {
  --ipo-bid: #2a78d6; --ipo-allot: #eb6834; --ipo-list: #1baf7a;
  --ipo-c1: #2a78d6; --ipo-track: #cde2fb;
  --ipo-grid: #edf0f5; --ipo-axis: #b8c0cc; --ipo-today: rgba(31, 107, 204, .1);
}

/* ---- hero: intro left, quick facts right; until 25 Oct the intro's 860px cap left the right
   third of the banner empty on wide screens ---- */
.ipo-hero { display: grid; grid-template-columns: minmax(0, 1fr) minmax(320px, 440px); column-gap: 28px; align-items: center; }
.ipo-hero > .ff-hero-status { grid-column: 1 / -1; }
.ipo-glance { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.ipo-glance > div { display: flex; flex-direction: column; gap: 1px; min-width: 0; padding: 8px 11px 9px;
  background: rgba(255, 255, 255, .1); border: 1px solid rgba(255, 255, 255, .18); border-radius: 10px; }
.ipo-glance .k { font-size: .64rem; font-weight: 600; text-transform: uppercase; letter-spacing: .06em; opacity: .8; }
.ipo-glance .v { font-size: .95rem; font-weight: 700; line-height: 1.3; }
.ipo-glance .s { font-size: .76rem; line-height: 1.4; opacity: .92; overflow-wrap: anywhere; }
.ipo-glance a { color: #fff; text-decoration: underline; text-decoration-color: rgba(255, 255, 255, .45); text-underline-offset: 2px; }
.ipo-glance a:hover { text-decoration-color: #fff; }
@media (max-width: 1099px) {
  .ipo-hero { grid-template-columns: minmax(0, 1fr); }
  .ipo-glance { grid-template-columns: repeat(4, minmax(0, 1fr)); margin-top: 14px; }
}
@media (max-width: 760px) { .ipo-glance { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* ---- a table and its chart side by side on wide screens (1366px laptops and up); the table
   keeps 60% so its columns do not wrap or scroll ---- */
.ipo-pair { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; align-items: start; margin-bottom: 14px; }
.ipo-pair > * { min-width: 0; margin-bottom: 0; }
.ipo-pair .ta-small { margin-bottom: 0; }
@media (min-width: 1360px) { .ipo-pair { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); } }

/* ---- chart card, caption, legend ---- */
.ipo-chart { margin: 0 0 14px; padding: 12px 16px; min-width: 0; background: var(--ff-card);
  border: 1px solid var(--ff-border); border-radius: var(--ff-radius); box-shadow: var(--ff-shadow); }
.ff-tablewrap + .ipo-chart { margin-top: 14px; }
.ipo-pair > .ipo-chart { margin-top: 0; }
.ipo-chart-cap { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 12px; margin: 0 0 8px; }
.ipo-chart-cap b { font-size: .95rem; font-weight: 650; color: var(--ff-primary); }
.ipo-chart-cap span { font-size: .76rem; color: var(--ff-text-soft); }
.ipo-legend { display: flex; flex-wrap: wrap; gap: 4px 16px; margin: 0 0 8px; font-size: .74rem; color: var(--ff-text-soft); }
.ipo-legend span { display: inline-flex; align-items: center; gap: 6px; }
.ipo-legend i { display: inline-block; flex: none; }
.ipo-legend .sw { width: 14px; height: 10px; border-radius: 2px; background: var(--ipo-c1); }
.ipo-legend .dot { width: 10px; height: 10px; border-radius: 50%; }
.ipo-legend .mk { width: 9px; height: 9px; margin: 0 2px; transform: rotate(45deg); background: var(--ff-primary); }
.ipo-legend .mk.sim { background: var(--ff-card); box-shadow: inset 0 0 0 2px var(--ff-primary); }
.ipo-legend .pos { background: var(--ff-success); }
.ipo-legend .neg { background: var(--ff-danger); }
.ipo-legend .k-bid { background: var(--ipo-bid); }
.ipo-legend .k-allot { background: var(--ipo-allot); }
.ipo-legend .k-list { background: var(--ipo-list); }
.ipo-legend .k-today { background: var(--ipo-today); box-shadow: inset 0 0 0 1px var(--ff-accent); }
.ipo-legend .k-today.line { width: 2px; height: 14px; margin: 0 6px; border-radius: 0; background: var(--ff-accent); box-shadow: none; }
.ipo-legend .dot.ring { background: var(--ff-card); box-shadow: inset 0 0 0 2.5px var(--ipo-allot); }

/* ---- row chart: a row per item, a panel per measure, the value at the bar's end.
   Rows touch, so each plot's gridlines (background) join into one rule down the chart.
   Layout follows the chart's own width (container queries), not the screen's: the same chart
   sits full width or beside a table. ---- */
.ipo-rc { --lab: 180px; --val: 62px; font-size: .8rem; container: rc / inline-size; }
.ipo-rc-row { display: grid; grid-template-columns: var(--lab) minmax(0, 1fr); column-gap: 14px; }
.ipo-rc-2 .ipo-rc-row { grid-template-columns: var(--lab) repeat(2, minmax(0, 1fr)); }
.ipo-rc-3 .ipo-rc-row { grid-template-columns: var(--lab) repeat(3, minmax(0, 1fr)); }
.ipo-rc-row[data-tip]:hover { background: #f8fafc; }
.ipo-rc-lab { display: flex; flex-direction: column; justify-content: center; min-width: 0; padding: 5px 0; line-height: 1.3; }
.ipo-rc-lab a, .ipo-rc-lab b { font-weight: 600; color: var(--ff-text); overflow-wrap: anywhere; }
.ipo-rc-lab a { text-decoration: none; }
.ipo-rc-lab a:hover { color: var(--ff-accent); text-decoration: underline; }
.ipo-rc-lab small { font-size: .7rem; color: var(--ff-text-soft); }
.ipo-rc-cell { display: grid; grid-template-columns: minmax(0, 1fr) var(--val); column-gap: 8px; min-width: 0; container: cell / inline-size; }
.ipo-rc-plot { position: relative; min-height: 30px; box-shadow: inset -1px 0 0 var(--ipo-grid);
  background-image:
    linear-gradient(to right, transparent calc(var(--z) - .5px), var(--ipo-axis) calc(var(--z) - .5px),
                    var(--ipo-axis) calc(var(--z) + .5px), transparent calc(var(--z) + .5px)),
    repeating-linear-gradient(to right, var(--ipo-grid) 0 1px, transparent 1px var(--st)); }
.ipo-rc-plot.share { background: none; box-shadow: none; }
.ipo-rc-plot.share::before { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 12px; margin-top: -6px;
  border-radius: 4px; background: var(--ipo-track); }
.ipo-rc-bar { position: absolute; top: 50%; height: 12px; margin-top: -6px; min-width: 2px;
  border-radius: 0 4px 4px 0; background: var(--ipo-c1); }
.ipo-rc-bar.l { border-radius: 4px 0 0 4px; }
.ipo-rc-bar.pos { background: var(--ff-success); }
.ipo-rc-bar.neg { background: var(--ff-danger); }
.ipo-rc-bar.flat { background: var(--ff-neutral); }
.ipo-rc-bar.share { border-radius: 4px; }
.ipo-rc-mark { position: absolute; top: 50%; width: 10px; height: 10px; margin: -5px 0 0 -5px; transform: rotate(45deg);
  background: var(--ff-primary); box-shadow: 0 0 0 2px var(--ff-card); }
.ipo-rc-mark.sim { background: var(--ff-card); box-shadow: inset 0 0 0 2px var(--ff-primary), 0 0 0 2px var(--ff-card); }
.ipo-rc-val { align-self: center; text-align: right; white-space: nowrap; font-weight: 600; color: var(--ff-text);
  font-variant-numeric: tabular-nums; }
.ipo-rc-axisrow .ipo-rc-lab { padding: 0; }
.ipo-rc-title { grid-column: 1 / -1; padding-bottom: 2px; font-size: .68rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; color: var(--ff-text-soft); }
.ipo-rc-axis { position: relative; grid-column: 1; height: 16px; }
.ipo-rc-axis span { position: absolute; top: 0; transform: translateX(-50%); font-size: .66rem;
  color: var(--ff-text-soft); white-space: nowrap; font-variant-numeric: tabular-nums; }
.ipo-rc-axis span:first-child { transform: none; }
.ipo-rc-axis span:last-child { transform: translateX(-100%); }
/* a narrow panel keeps only zero and the top of its scale; every bar carries its value anyway */
@container cell (max-width: 340px) {
  .ipo-rc-axis span:not(:last-child):not(.z) { display: none; }
}
/* a narrow chart puts each name on its own line above the bars, which then get the full width.
   Rows no longer touch there, so the gridlines give way to the zero line alone. */
@container rc (max-width: 600px) {
  .ipo-rc-2.ipo-rc-stack .ipo-rc-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ipo-rc-2.ipo-rc-stack .ipo-rc-lab { grid-column: 1 / -1; flex-direction: row; flex-wrap: wrap; justify-content: flex-start;
    align-items: baseline; gap: 0 8px; padding: 6px 0 0; }
  .ipo-rc-2.ipo-rc-stack .ipo-rc-axisrow .ipo-rc-lab { display: none; }
  .ipo-rc-2.ipo-rc-stack .ipo-rc-plot:not(.share) { box-shadow: none; background-image: linear-gradient(to right, transparent calc(var(--z) - .5px),
    var(--ipo-axis) calc(var(--z) - .5px), var(--ipo-axis) calc(var(--z) + .5px), transparent calc(var(--z) + .5px)); }
}
/* short names (years, demand bands) stay beside their bars down to a phone's width */
@container rc (max-width: 400px) {
  .ipo-rc-2:not(.ipo-rc-stack) .ipo-rc-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ipo-rc-2:not(.ipo-rc-stack) .ipo-rc-lab { grid-column: 1 / -1; flex-direction: row; flex-wrap: wrap; justify-content: flex-start;
    align-items: baseline; gap: 0 8px; padding: 6px 0 0; }
  .ipo-rc-2:not(.ipo-rc-stack) .ipo-rc-axisrow .ipo-rc-lab { display: none; }
  .ipo-rc-2:not(.ipo-rc-stack) .ipo-rc-plot:not(.share) { box-shadow: none; background-image: linear-gradient(to right, transparent calc(var(--z) - .5px),
    var(--ipo-axis) calc(var(--z) - .5px), var(--ipo-axis) calc(var(--z) + .5px), transparent calc(var(--z) + .5px)); }
}
/* three measures: the name on its own line under 900px; on a phone each value sits above its bar,
   so the bar keeps the panel's whole width */
@container rc (max-width: 900px) {
  .ipo-rc-3 .ipo-rc-row { grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: 10px; }
  .ipo-rc-3 .ipo-rc-lab { grid-column: 1 / -1; flex-direction: row; flex-wrap: wrap; justify-content: flex-start;
    align-items: baseline; gap: 0 8px; padding: 6px 0 0; }
  .ipo-rc-3 .ipo-rc-axisrow .ipo-rc-lab { display: none; }
  .ipo-rc-3 .ipo-rc-plot:not(.share) { box-shadow: none; background-image: linear-gradient(to right, transparent calc(var(--z) - .5px),
    var(--ipo-axis) calc(var(--z) - .5px), var(--ipo-axis) calc(var(--z) + .5px), transparent calc(var(--z) + .5px)); }
}
@container rc (max-width: 520px) {
  .ipo-rc-3 .ipo-rc-cell { grid-template-columns: minmax(0, 1fr); }
  .ipo-rc-3 .ipo-rc-val { order: -1; text-align: left; font-size: .72rem; }
  .ipo-rc-3 .ipo-rc-plot { min-height: 18px; }
  .ipo-rc-3 .ipo-rc-title { font-size: .62rem; }
}
@container rc (max-width: 440px) {
  .ipo-rc-1:not(.ipo-rc-stack) .ipo-rc-row { grid-template-columns: 110px minmax(0, 1fr); column-gap: 10px; }
  .ipo-rc-1.ipo-rc-stack .ipo-rc-row { grid-template-columns: minmax(0, 1fr); }
  .ipo-rc-1.ipo-rc-stack .ipo-rc-lab { flex-direction: row; flex-wrap: wrap; justify-content: flex-start; align-items: baseline;
    gap: 0 8px; padding: 6px 0 0; }
  .ipo-rc-1.ipo-rc-stack .ipo-rc-axisrow .ipo-rc-lab { display: none; }
  .ipo-rc-1.ipo-rc-stack .ipo-rc-plot { box-shadow: none; background-image: linear-gradient(to right, transparent calc(var(--z) - .5px),
    var(--ipo-axis) calc(var(--z) - .5px), var(--ipo-axis) calc(var(--z) + .5px), transparent calc(var(--z) + .5px)); }
}
@media (max-width: 640px) {
  .ipo-chart { padding: 10px 12px; }
  .ipo-rc { --val: 54px; font-size: .76rem; }
}

/* ---- timetable: one row per IPO over trading days ---- */
.ipo-tl-grid { font-size: .8rem; }
.ipo-tl-row { display: grid; grid-template-columns: 260px minmax(0, 1fr); column-gap: 14px; }
.ipo-tl-row[data-tip]:hover { background: #f8fafc; }
.ipo-tl-lab { display: flex; flex-direction: column; justify-content: center; min-width: 0; padding: 6px 0; line-height: 1.3; }
.ipo-tl-lab a { font-weight: 600; color: var(--ff-text); text-decoration: none; overflow-wrap: anywhere; }
.ipo-tl-lab a:hover { color: var(--ff-accent); text-decoration: underline; }
.ipo-tl-lab small { font-size: .7rem; color: var(--ff-text-soft); }
.ipo-tl-track { display: grid; grid-template-columns: repeat(var(--n), minmax(0, 1fr)); align-items: center; min-height: 36px;
  background-image: repeating-linear-gradient(to right, var(--ipo-grid) 0 1px, transparent 1px calc(100% / var(--n))); }
.ipo-tl-track.t-band { background-image:
  linear-gradient(to right, transparent var(--t0), var(--ipo-today) var(--t0), var(--ipo-today) var(--t1), transparent var(--t1)),
  repeating-linear-gradient(to right, var(--ipo-grid) 0 1px, transparent 1px calc(100% / var(--n))); }
.ipo-tl-track.t-line { background-image:
  linear-gradient(to right, transparent calc(var(--t0) - 1px), var(--ff-accent) calc(var(--t0) - 1px), var(--ff-accent) calc(var(--t0) + 1px), transparent calc(var(--t0) + 1px)),
  repeating-linear-gradient(to right, var(--ipo-grid) 0 1px, transparent 1px calc(100% / var(--n))); }
.ipo-tl-track > i { grid-row: 1; }
.ipo-tl-bid { position: relative; z-index: 1; height: 12px; margin: 0 3px; border-radius: 4px; background: var(--ipo-bid); }
.ipo-tl-bid.past { background: #9ec5f4; }
.ipo-tl-link { height: 2px; margin: 0 calc(50% / var(--span)); background: var(--ipo-axis); }
.ipo-tl-dot { position: relative; z-index: 2; justify-self: center; width: 10px; height: 10px; border-radius: 50%;
  box-shadow: 0 0 0 2px var(--ff-card); }
.ipo-tl-dot.k-allot { background: var(--ipo-allot); }
.ipo-tl-dot.ring { background: var(--ff-card); box-shadow: inset 0 0 0 2.5px var(--ipo-allot), 0 0 0 2px var(--ff-card); }
.ipo-tl-dot.k-list { width: 12px; height: 12px; background: var(--ipo-list); }
.ipo-tl-head .ipo-tl-track { min-height: 0; align-items: end; background: none; }
.ipo-tl-day { padding-bottom: 4px; text-align: center; font-size: .66rem; line-height: 1.15; color: var(--ff-text-soft); }
.ipo-tl-day b { display: block; font-size: .8rem; color: var(--ff-text); }
.ipo-tl-day small { display: block; font-size: .6rem; font-weight: 600; text-transform: uppercase; }
.ipo-tl-day.past b { color: var(--ff-text-soft); font-weight: 600; }
.ipo-tl-day.today, .ipo-tl-day.today b { color: var(--ff-accent); }
.ipo-tl-day.wk { box-shadow: inset 1px 0 0 var(--ipo-axis); }
@media (max-width: 700px) {
  .ipo-tl-row { grid-template-columns: minmax(0, 1fr); }
  .ipo-tl-head .ipo-tl-lab { display: none; }
  .ipo-tl-lab { flex-direction: row; flex-wrap: wrap; justify-content: flex-start; align-items: baseline; gap: 0 8px; padding: 8px 0 2px; }
  .ipo-tl-day .dw { display: none; }
  .ipo-tl-track { min-height: 26px; }
}

/* ---- calendar: Monday to Friday, a box per day; on a phone, a list of the busy days ---- */
.ipo-cal-wrap { margin-bottom: 14px; }
.ipo-cal { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 1px; overflow: hidden;
  background: var(--ff-border); border: 1px solid var(--ff-border); border-radius: var(--ff-radius); box-shadow: var(--ff-shadow); }
.ipo-cal-dow { padding: 8px 10px; background: #f4f6fa; font-size: .72rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: .45px; color: #56607a; }
.ipo-cal-day { display: flex; flex-direction: column; gap: 5px; min-width: 0; min-height: 92px; padding: 8px 9px 10px; background: var(--ff-card); }
.ipo-cal-day.past { background: #fafbfc; }
.ipo-cal-day.past > * { opacity: .6; }
.ipo-cal-day.hol { background: var(--ff-bg); }
.ipo-cal-day.today { box-shadow: inset 0 0 0 2px var(--ff-accent); }
.ipo-cal-date { display: flex; justify-content: space-between; align-items: baseline; gap: 6px; font-size: .85rem; font-weight: 700; color: var(--ff-text); }
.ipo-cal-date .dow { display: none; }
.ipo-cal-now { padding: 1px 7px; border-radius: 99px; background: var(--ff-accent); color: #fff; font-size: .64rem;
  font-weight: 700; text-transform: uppercase; letter-spacing: .05em; }
.ipo-cal-hol { font-size: .74rem; color: var(--ff-text-soft); }
.ipo-cal-ev { --k: var(--ipo-bid); padding: 4px 7px 5px; border-left: 3px solid var(--k); border-radius: 0 6px 6px 0;
  background: #f3f7fd; background: color-mix(in srgb, var(--k) 9%, #fff); font-size: .78rem; line-height: 1.35; overflow-wrap: anywhere; }
.ipo-cal-ev.k-allot, .ipo-cal-ev.k-credit { --k: var(--ipo-allot); background: #fdf3ef; background: color-mix(in srgb, var(--k) 9%, #fff); }
.ipo-cal-ev.k-list { --k: var(--ipo-list); background: #effaf5; background: color-mix(in srgb, var(--k) 9%, #fff); }
.ipo-cal-ev.k-bid { background: var(--ff-card); }
.ipo-cal-ev .k { display: block; font-size: .64rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--ff-text-soft); }
.ipo-cal-ev a { font-weight: 600; color: var(--ff-text); text-decoration: none; }
.ipo-cal-ev a:hover { color: var(--ff-accent); text-decoration: underline; }
.ipo-cal-ev .n { font-size: .72rem; color: var(--ff-text-soft); }
@media (max-width: 760px) {
  .ipo-cal { grid-template-columns: minmax(0, 1fr); }
  .ipo-cal-dow, .ipo-cal-day.empty { display: none; }
  .ipo-cal-day { min-height: 0; }
  .ipo-cal-date .dow { display: inline; }
}
