
:root{
  --brand:#0e9f6e; --brand-dark:#0b7a57; --brand-light:#e9f7f0;
  --ink:#171c24; --muted:#5a6472; --muted-2:#6b7280;
  --line:#e7e9ee; --line-strong:#d7dbe2;
  --surface:#fff; --surface-2:#fafbfc; --bg:#fff; --wash:#e9f7f0;
  --inset:#f3f6f9; /* subtle panel — recessed in light, elevated (lighter than the card) in dark */
  --warn:#c2603e; --warn-bg:#fbf1ec; --exempt:#4c7fb8;
  --sme:#7c5cbf; --sme-fg:#5b3fa0; --sme-bg:#f0ebfa; --mb-fg:#0b7a57; /* segment accents */
  --r:12px; --r-sm:8px;
}
html.dark{
  --ink:#eef1f5; --muted:#a3adba; --muted-2:#8791a0;
  --line:#1e2530; --line-strong:#2a3340;
  --surface:#10151f; --surface-2:#0d121b; --bg:#0a0e16; --wash:#062b1d;
  --inset:#1a2230; /* elevated panel, a step lighter than the #10151f card (mockup surface-container) */
  --brand-light:rgba(14,159,110,.13); --warn:#e08a68; --warn-bg:#241612; --exempt:#6fa0d6;
  --sme:#b59cf0; --sme-fg:#c9b6ff; --sme-bg:rgba(124,92,191,.18); --mb-fg:#6ee7b7;
}
body{transition:background-color .35s ease,color .35s ease}
*{box-sizing:border-box}
/* Background: a very slow gradient wash between the base colour and a barely-there accent
   tint (PR #12 §Background) — pure CSS, no JS. Opaque header/cards sit above it; it only
   breathes through the page margins and grid gaps, never competing with the data. Frozen
   under prefers-reduced-motion (see the a11y block below).
   NOTE: this wash is now the FALLBACK layer — an animated WebGL backdrop (#ipobg / the BACKDROP
   const) renders over it; see that const's comment before changing the background. */
body{margin:0;color:var(--ink);min-height:100vh;background:var(--bg);
  font-family:Inter,system-ui,'Segoe UI',sans-serif;letter-spacing:-.011em;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
  font-optical-sizing:auto;line-height:1.5}
/* The wash lives on a FIXED ::before layer (not background-attachment:fixed, which is flaky on
   mobile Safari/Chrome), z-index -1 so it sits under all content. Tint lifted and the primary blob
   pulled into view so it actually reads; opaque header/cards still sit above it. Solid var(--bg)
   fallback for engines without color-mix. */
body::before{content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;background:var(--bg);
  background:
    radial-gradient(1150px 680px at 14% -4%, color-mix(in oklab, var(--brand) 10%, transparent), transparent 60%),
    radial-gradient(1000px 620px at 98% 6%, color-mix(in oklab, var(--brand) 16%, transparent), transparent 56%),
    radial-gradient(820px 820px at 58% 108%, color-mix(in oklab, var(--brand) 12%, transparent), transparent 60%),
    var(--bg)}
@keyframes gradientWash{0%{background-position:0% 50%}50%{background-position:100% 50%}100%{background-position:0% 50%}}
/* Living backdrop (added 2026-08-22): an animated WebGL simplex-noise field on a FIXED canvas
   (#ipobg), the flowing companion to the static ::before wash. It sits ABOVE that wash (which we
   push to z-index:-2 here, without touching its own rule) but below all content, at low opacity so
   it only breathes through the margins and grid gaps — never competing with the data. If WebGL is
   unavailable the canvas hides itself and the ::before wash shows through unchanged; under
   prefers-reduced-motion it is hidden too (see the a11y block below). Styled for the BACKDROP const. */
body::before{z-index:-2}
#ipobg{position:fixed;inset:0;z-index:-1;pointer-events:none;width:100%;height:100%;opacity:.45;transition:opacity .4s ease}  /* .8 until 2026-10-10: the owner found the green too dense at the top */
html.dark #ipobg{opacity:.65}
.wrap{max-width:1180px;margin:0 auto;padding:0 22px}
a{color:var(--brand-dark)}
/* Tracking is size-specific (Apple §15): tighten as type grows, ease off for small text.
   Leading rides inversely — tight on headings, comfortable on body. */
h1,h2,h3,h4{margin:0;letter-spacing:-.02em;line-height:1.15}
.muted{color:var(--muted)} .small{font-size:.82rem} .num{font-variant-numeric:tabular-nums}

/* header */
.brand{display:flex;align-items:center;gap:12px}
/* The masthead wordmark. No drop-shadow: that green glow existed to lift a saturated green tile
   off the header, and under black letterforms it just reads as a smudge. Colour comes from
   currentColor, so the mark flips to near-white in the dark theme with no second asset. */
.brand-mark{flex:none;display:inline-flex;line-height:0}
.brand-mark img{display:block;height:22px;width:auto}  /* height only; width follows the aspect ratio */
.brand-mark .logo-drk{display:none}
/* The masthead (siteHeader): a light bar on every page, the original two-colour logo. */
.mast{background:var(--surface);border-bottom:1px solid var(--line);position:relative;z-index:21}
.mast-in{max-width:1180px;margin:0 auto;padding:8px 22px}
.mast-row{display:flex;align-items:center;gap:4px 18px;flex-wrap:wrap}
.mast-logo{display:inline-flex;align-items:center;flex:none;line-height:0;padding:6px 0}
.mast nav{flex:1 1 auto;min-width:0}
.mast .nav{margin:0;flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none}
.mast .nav::-webkit-scrollbar{display:none}
.mast .nav a{white-space:nowrap}
.mast .nav a[aria-current=page]{color:var(--brand-dark);background:var(--brand-light);border-color:transparent}
html.dark .mast .nav a[aria-current=page]{color:#6ee7b7}
.mast-act{display:flex;align-items:center;gap:6px;flex:none;margin-left:auto}
/* The home hero: the headline and the newsletter button on one row, then search. */
.home-hero{margin:14px 0 6px}
.home-hero-top{display:flex;align-items:center;justify-content:space-between;gap:10px 16px;flex-wrap:wrap}
.home-h1{margin:0;font-size:clamp(1.3rem,3.2vw,1.9rem);font-weight:800;line-height:1.12;letter-spacing:-.025em}
.home-cta{display:inline-block;padding:10px 16px;border-radius:10px;background:var(--brand);color:#fff;font-weight:700;font-size:.9rem;
  text-decoration:none;white-space:nowrap}
@media (hover:hover){.home-cta:hover{background:var(--brand-dark)}}
.home-live{margin:6px 0 10px;font-size:.78rem;color:var(--muted)}
.home-hero .fsearchrow{margin:0}
.home-hero .fsearch{max-width:640px}
.fbtn-zero{opacity:.5}
.dark .brand-mark .logo-lite{display:none}
.dark .brand-mark .logo-drk{display:block}
/* A rule between the parent brand and the product name, so "Kredfit" and "IPO agent" read as
   two things rather than one run-on phrase. */
.brand > div{padding-left:12px;border-left:1px solid var(--line-strong)}
.brand-sub{margin:3px 0 0;font-size:.78rem;font-weight:600;letter-spacing:.01em;color:var(--brand-dark)}
.tagline{max-width:64ch;margin:8px 0 0;color:var(--muted);font-size:.95rem}
.theme-btn{width:38px;height:38px;flex:none;padding:0;border-radius:var(--r-sm);border:1px solid var(--line);background:var(--surface);color:var(--ink);cursor:pointer;display:grid;place-items:center;transition:border-color .2s,transform .12s}
@media (hover:hover){.theme-btn:hover{background:var(--surface);border-color:var(--line-strong)}} .theme-btn:active{transform:scale(.94)}
.theme-btn svg{width:18px;height:18px;display:block}
.updated{margin:0;white-space:nowrap}

/* filter bar (below the header) — a translucent material that sticks as the list
   scrolls under it (Apple §12). Bleeds to the container edge so the blur reads as a strip. */
.filters{position:sticky;top:0;z-index:20;display:flex;flex-wrap:wrap;gap:10px 20px;align-items:center;
  margin:8px -22px 4px;padding:13px 22px 12px;
  background:rgba(255,255,255,.72);backdrop-filter:saturate(180%) blur(16px);
  -webkit-backdrop-filter:saturate(180%) blur(16px);box-shadow:0 8px 18px -16px rgba(15,23,32,.55)}
html.dark .filters{background:rgba(10,14,22,.72)}
/* Status and board read as ONE control. The border lives on this inner bar, never on .filters,
   which is a full-bleed sticky strip (negative margins) and would look like a stray pill. */
.fbar{display:inline-flex;align-items:stretch;gap:2px;background:var(--surface-2);
  border:1px solid var(--line);border-radius:999px;padding:3px;flex-wrap:wrap}
.fbar .fgroup{background:transparent;border:0;padding:0;border-radius:0}
.fgroup{display:inline-flex;background:var(--surface-2);border:1px solid var(--line);border-radius:999px;padding:3px}
.fgroup-board .fbtn{font-weight:500;font-size:.82rem}
/* BOARD FILTER: a dropdown at every width, not only on a phone.

   The status filter and the board filter look alike and are not alike. Status is the one a reader
   changes constantly while scanning, so it stays a row of pills that are all visible and one click
   apart. Board is set once, usually never, and spending three permanent pills on it costs more room
   than it earns. Collapsing it also lets the label carry the current state ("Mainboard") instead of
   making the reader read which pill is highlighted.

   Declared here rather than inside the 640px query so it applies everywhere; the query below still
   restyles both dropdowns for a phone, and those rules win by source order. The base
   .fdrop-status>summary{display:none} rule below continues to hide the STATUS summary on a laptop,
   which is what keeps that one a flat row. */
/* TWO FILTERS, ONE BAR, and they answer different questions: which market, then which stage. Side
   by side in identical grey they read as one row of six controls, so people worked the status pills
   and never noticed the board control at all -- which is how three SME issues sat on the mainboard
   list unremarked. The board control therefore carries a soft brand tint and the status pills stay
   neutral. A tint on ONE of the two is enough to separate them; tinting both would just be a
   second colour to decode, and the brand green is already the site's "this is a control" colour. */
.fdrop-board>summary{display:inline-flex;align-items:center;gap:6px;appearance:none;list-style:none;
  cursor:pointer;font:inherit;font-size:.85rem;font-weight:600;
  padding:6px 14px;border-radius:999px;white-space:nowrap;
  color:var(--brand-dark);background:color-mix(in srgb, var(--brand) 9%, var(--surface));
  border:1px solid color-mix(in srgb, var(--brand) 32%, var(--line-strong))}
@media (hover:hover){.fdrop-board>summary:hover{background:color-mix(in srgb, var(--brand) 15%, var(--surface));
  border-color:color-mix(in srgb, var(--brand) 48%, var(--line-strong))}}
.fdrop-board[open]>summary{border-color:var(--brand);color:var(--brand-dark);
  background:color-mix(in srgb, var(--brand) 15%, var(--surface))}
/* Dark mode needs its own mix: 9% of the brand over a near-black surface is invisible. */
html.dark .fdrop-board>summary{color:var(--mb-fg);
  background:color-mix(in srgb, var(--brand) 18%, var(--surface));
  border-color:color-mix(in srgb, var(--brand) 42%, var(--line-strong))}
html.dark .fdrop-board[open]>summary{background:color-mix(in srgb, var(--brand) 26%, var(--surface))}
.fdrop-board>summary::after{content:"";flex:none;width:6px;height:6px;margin-top:-3px;
  border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(45deg)}
.fdrop-board[open]>summary::after{margin-top:3px;transform:rotate(-135deg)}
/* The panel floats rather than pushing the grid down: the filter bar is sticky, so growing it would
   shove every card on the page. Nothing paintable is declared on the CLOSED state, for the reason
   given in the phone block below. LEFT-aligned, because the board trigger now leads the bar; while
   it trailed, this was right:0, and leaving it that way would hang a 170px panel off the left edge
   of the leftmost control and out of the viewport on a narrow phone. */
.fdrop-board .fgroup{position:absolute;top:calc(100% + 6px);left:0;right:auto;z-index:30}
.fdrop-board[open] .fgroup{flex-direction:column;align-items:stretch;gap:2px;min-width:170px;
  background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:6px;
  box-shadow:0 10px 28px -10px rgba(15,23,32,.35)}
.fdrop-board .fgroup .fbtn{justify-content:flex-start;width:100%}
/* Board filter as a <details> dropdown, same pattern as .baserate-note: marked open in the markup
   (so it just works with no JS, e.g. with JS disabled) and the JS above drops the [open] attribute
   on phones before paint. Desktop: hide the summary trigger, so an always-open <details> reads as
   the plain inline pill group it always was. This must come BEFORE the phone media query below —
   equal-specificity rules resolve by source order, not by which one sits inside a matching @media,
   so the unconditional display:none here would otherwise beat the phone override that follows it. */
/* padding/margin:0 resets the browser's own default details-element spacing — confirmed via a
   bare, unstyled details/summary/div in devtools with no author CSS at all that it, not any rule
   here, was the source of an ~11px gap between the details box and its (hidden-on-desktop)
   summary child, which read as a stray seam between .fbar's and .fdrop's different background
   shades. (Written this way, not as literal tags, so this comment cannot false-positive-match the
   "every FAQ question is visible" test's naive summary-tag regex scan over the raw page HTML.) */
.fdrop{position:relative;padding:0;margin:0}
/* STATUS only, and NOT the bare .fdrop>summary.
 *
 * That is what this was, and it hid the board filter completely. The bare selector and
 * the board rule have IDENTICAL specificity, one class and one type
 * each, so the cascade falls back to source order and this rule sits 30 lines LATER. It won, the
 * board trigger was display:none on every viewport, and the All / Mainboard / SME control was
 * invisible on the site while being perfectly present in the HTML.
 *
 * The comment above the board rule even asserts this one is "above" it. It is below. A rule whose
 * correctness depends on its line number, described by a comment that gets the line number wrong, is
 * the shape of bug that survives being fixed once already.
 *
 * Naming the status dropdown removes the ordering question entirely: only two .fdrop elements exist,
 * status and board, so this is exactly equivalent in effect and cannot be broken by moving code.
 */
.fdrop-status>summary{display:none}
.fdrop>summary::-webkit-details-marker{display:none}
.fdrop>summary::before{content:none}   /* suppress the global summary::before ▸ marker; .fdrop uses its own ::after chevron */
/* On a phone BOTH filters collapse into small dropdown triggers side by side ("Open ▾" and "All
   boards ▾") instead of the desktop's inline pill groups — that is what actually keeps this
   compact; the earlier attempt (status as a wrapped multi-row pill strip) still ate two full
   rows above the fold. Nothing is ever hidden behind a scroll: a dropdown's full option list is
   one tap away, not scrolled past. */
@media (max-width:640px){
  .fbar{width:100%;justify-content:flex-start;gap:8px;border-radius:14px;padding:8px}
  .fdiv{display:none}   /* the two triggers read as separate controls without needing a divider */
  .fdrop{flex:0 0 auto;min-width:0}
  .fdrop>summary{display:flex;align-items:center;gap:5px;appearance:none;list-style:none;
    cursor:pointer;color:var(--ink);font:inherit;font-size:.85rem;font-weight:600;
    padding:10px 14px;min-height:44px;border-radius:12px;background:var(--surface);
    border:1px solid var(--line);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .fdrop[open]>summary{border-color:var(--brand)}
  .fdrop-status>summary{max-width:60vw}
  .fdrop>summary::after{content:"";flex:none;width:6px;height:6px;margin-top:-3px;
    border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(45deg)}
  .fdrop[open]>summary::after{margin-top:3px;transform:rotate(-135deg)}
  /* The opened panel: floats below its trigger rather than pushing page content down. Generalised
     from .fgroup-board to plain .fgroup so the status list gets the same treatment. Scoped to
     .fdrop[open] specifically, not just .fdrop, — some engines still paint a hairline sliver of a
     closed <details> panel's own border/background even though checkVisibility() correctly
     reports it as hidden, so nothing paintable (border, background, shadow, padding) is declared
     on the CLOSED state at all; only positioning (harmless off-flow, paints nothing by itself). */
  /* max-width is the backstop, not the fix. A panel anchored to the correct edge still overflows if
     the option labels grow, and there is no JS here to reposition it, so it is capped to the
     viewport minus the bar's own padding on both sides. */
  .fdrop .fgroup{position:absolute;top:calc(100% + 6px);left:0;z-index:30;
    max-width:calc(100vw - 28px)}
  /* ANCHOR THE TRAILING CONTROL, WHICHEVER IT IS, and that is the whole bug.
     This override was scoped to .fdrop-board and dated from when the board filter TRAILED the status
     filter. The board filter now LEADS (see the markup: .fdrop-board is the first <details>), so
     right-anchoring pinned a 170px panel to the right edge of the LEFTMOST control and hung it off
     the left of the screen. On a phone it opened partly out of the viewport.
     The desktop rule above was corrected when the order changed and its comment predicted this
     exact symptom, "out of the viewport on a narrow phone". This media query, being later and
     narrower, quietly won on the one device the comment was about. */
  .fdrop-status .fgroup{left:auto;right:0}
  .fdrop[open] .fgroup{flex-direction:column;align-items:stretch;gap:2px;min-width:170px;
    background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:6px;
    box-shadow:0 10px 28px -10px rgba(15,23,32,.35)}
  .fdrop .fgroup .fbtn{justify-content:flex-start;width:100%}
}
.fbtn{appearance:none;border:0;background:transparent;color:var(--muted);font:inherit;font-size:.85rem;font-weight:600;
  padding:6px 14px;border-radius:999px;cursor:pointer;display:inline-flex;align-items:center;gap:6px;
  transition:color .15s,background .15s,transform .18s cubic-bezier(.2,.9,.3,1.2)}
@media (hover:hover){.fbtn:hover{color:var(--ink)}}
.fbtn:active{transform:scale(.95)}
.fbtn.is-on{background:var(--surface);color:var(--ink);box-shadow:0 1px 2px rgba(0,0,0,.06)}
.dark .fbtn.is-on{box-shadow:0 1px 2px rgba(0,0,0,.4)}
.fbtn.is-on .fct{background:var(--brand-light);color:var(--brand-dark)}
.fbtn-quiet{color:var(--muted-2)}
.fct{font-size:.72rem;font-weight:700;background:var(--line);color:var(--muted);border-radius:999px;padding:1px 7px;font-variant-numeric:tabular-nums}
.fbtn:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
/* SEARCH IS HIDDEN UNTIL SCRIPTING ANSWERS FOR IT. A box that swallows what you type and does
   nothing is worse than no box, and this page renders every card without JavaScript, so the
   no-JavaScript reader loses nothing by not seeing it. html.js is set in the head, before the
   first paint, so the control does not jump in later. */
.fsearchrow{display:none;width:100%}
html.js .fsearchrow{display:block}
.fsearch{position:relative;display:flex;align-items:center;width:100%;max-width:420px}
.fsearch-ic{position:absolute;left:11px;width:15px;height:15px;color:var(--muted-2);pointer-events:none}
.fsearch-in{width:100%;font:inherit;font-size:.88rem;color:var(--ink);background:var(--surface);
  border:1px solid var(--line);border-radius:999px;padding:8px 32px 8px 33px;appearance:none}
.fsearch-in::placeholder{color:var(--muted-2)}
.fsearch-in:focus{outline:none;border-color:var(--brand);
  box-shadow:0 0 0 3px color-mix(in srgb, var(--brand) 18%, transparent)}
/* The browser's own clear affordance is inconsistent across engines and invisible on some; ours
   is always there, always the same size, and always a real button for a keyboard. */
.fsearch-in::-webkit-search-cancel-button{display:none}
.fsearch-x{position:absolute;right:4px;display:flex;align-items:center;justify-content:center;
  width:26px;height:26px;border:0;border-radius:999px;background:transparent;color:var(--muted);
  font-size:1.15rem;line-height:1;cursor:pointer}
@media (hover:hover){.fsearch-x:hover{background:var(--surface-2);color:var(--ink)}}
.fsearch-x:focus-visible{outline:2px solid var(--brand);outline-offset:1px}
.fresult{margin:10px 0 0;font-size:.84rem;color:var(--muted)}
.fresult b{color:var(--ink);font-weight:600}
/* "Did you mean" is a button, not a link: it changes the page you are on rather than taking you
   to another one, and a screen reader should be told which of those is about to happen. */
.fsug{appearance:none;border:0;background:transparent;padding:0;font:inherit;font-weight:600;
  color:var(--brand-dark);text-decoration:underline;text-underline-offset:2px;cursor:pointer}
html.dark .fsug{color:var(--brand)}
.fsug:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
/* ADD TO HOME SCREEN. A card that floats above the bottom edge rather than a bar welded to it,
   so it reads as an offer and not as part of the page, and so it clears the iPhone home
   indicator via the safe-area inset. Bottom, not top: the top of a phone screen is already
   383px of header and filters before the first IPO card, and this must not add to that. */
.a2hs{position:fixed;left:12px;right:12px;bottom:calc(12px + env(safe-area-inset-bottom, 0px));z-index:60;
  display:flex;align-items:center;gap:10px;max-width:520px;margin:0 auto;padding:12px 10px 12px 12px;
  background:var(--surface);color:var(--ink);border:1px solid var(--line);border-radius:16px;
  box-shadow:0 12px 32px rgba(15,23,42,.16),0 2px 6px rgba(15,23,42,.06)}
html.dark .a2hs{box-shadow:0 12px 32px rgba(0,0,0,.55)}
.a2hs-icon{flex:none;width:42px;height:42px;border-radius:10px;border:1px solid var(--line);background:#fff}
.a2hs-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px;font-size:.84rem;line-height:1.35}
.a2hs-text>b{font-weight:700;font-size:.86rem}
.a2hs-sub{color:var(--muted)}
.a2hs-sub b{color:var(--ink);font-weight:600}
.a2hs-share{display:inline-block;vertical-align:-2px;margin:0 1px;color:var(--brand-dark)}
html.dark .a2hs-share{color:var(--brand)}
/* One platform's copy at a time. All are in the markup so nothing is built from strings later.
   "menu" is Android without Chrome's install prompt: instructions, like iOS, and no button. */
.a2hs-menu{display:none}
.a2hs[data-p="ios"] .a2hs-android,.a2hs[data-p="android"] .a2hs-ios,
.a2hs[data-p="menu"] .a2hs-android,.a2hs[data-p="menu"] .a2hs-ios{display:none}
.a2hs[data-p="menu"] .a2hs-menu{display:inline}
.a2hs-go{flex:none;appearance:none;border:0;cursor:pointer;min-height:44px;padding:0 16px;border-radius:11px;
  background:var(--brand);color:#fff;font:700 .86rem Inter,sans-serif}
.a2hs-go:active{transform:scale(.97)}
/* A 44px target for a small glyph. The negative margin pulls it into the card's padding, so the
   full touch area costs the text column almost nothing. */
.a2hs-x{flex:none;appearance:none;border:0;background:transparent;cursor:pointer;width:44px;height:44px;
  margin:-4px -6px -4px -8px;border-radius:999px;color:var(--muted);font-size:1.35rem;line-height:1}
@media (hover:hover){.a2hs-x:hover{background:var(--surface-2);color:var(--ink)}}
.a2hs-go:focus-visible,.a2hs-x:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
/* It slides up into place once, and only for people who have not asked for less motion. */
@media (prefers-reduced-motion:no-preference){.a2hs.show{animation:a2hsIn .32s cubic-bezier(.2,.8,.2,1)}}
@keyframes a2hsIn{from{transform:translateY(18px);opacity:0}to{transform:none;opacity:1}}
/* Printing a page should not print an offer to install it. */
@media print{.a2hs{display:none!important}}
/* PUSH OPT-IN, under the email form and separated from it, because it is a different offer: no
   email, nothing stored about the reader beyond a device address. One line of copy and one button;
   the note under it carries every state, so the layout never jumps between them. */
/* The signup box is a grid, so its row gap already separates this from the form: no extra margin,
   which doubled the space. Full width, because on a laptop the grid has two columns and a third child
   would otherwise land under the bullet points instead of under both. */
.push-opt{grid-column:1 / -1;display:flex;flex-wrap:wrap;align-items:center;gap:10px 16px;margin-top:0;padding-top:16px;
  border-top:1px dashed var(--line)}
.push-opt-text{flex:1 1 260px;min-width:0;display:flex;flex-direction:column;gap:3px;font-size:.88rem;line-height:1.4}
.push-opt-text>b{font-weight:700;color:var(--ink)}
.push-opt-sub{color:var(--muted)}
.push-opt-ios{display:none;color:var(--muted)}
.push-opt-ios b{color:var(--ink);font-weight:600}
.push-opt-btn{flex:none;appearance:none;cursor:pointer;min-height:44px;padding:0 18px;border-radius:10px;
  border:1px solid var(--brand);background:transparent;color:var(--brand-dark);font:700 .86rem Inter,sans-serif}
html.dark .push-opt-btn{color:var(--brand)}
@media (hover:hover){.push-opt-btn:hover{background:color-mix(in srgb, var(--brand) 10%, transparent)}}
.push-opt-btn:disabled{opacity:.6;cursor:default}
.push-opt-btn:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
.push-opt-note{flex-basis:100%;margin:0;font-size:.8rem;color:var(--muted);min-height:0}
.push-opt-note:empty{display:none}
/* Once on, the button becomes the quiet way off; it should not keep asking to be pressed. */
.push-opt[data-state="on"] .push-opt-btn{border-color:var(--line);color:var(--muted)}
/* iPhone in a Safari tab: explain the one route there is, and offer no button that cannot work. */
.push-opt[data-state="ios-install"] .push-opt-ios{display:block}
.push-opt[data-state="ios-install"] .push-opt-sub,
.push-opt[data-state="ios-install"] .push-opt-btn,
.push-opt[data-state="blocked"] .push-opt-btn{display:none}
[hidden]{display:none!important}

/* sections */
main{padding-bottom:20px}
section{margin:34px 0}
/* The first section butts against the sticky filter strip, which is already a strong divider —
   a full 34px on top of it just spends fold on nothing. Later sections keep the full gap. */
main > section:first-of-type{margin-top:12px}
.sechd{display:flex;align-items:baseline;gap:12px;margin-bottom:10px;
  padding-bottom:9px;border-bottom:1px solid var(--line)}
.sechd h2{font-size:1.15rem;font-weight:700}
.sechd h2::before{content:"";display:inline-block;width:4px;height:.85em;border-radius:2px;background:var(--muted-2);margin-right:9px;vertical-align:-1px}
[data-status="OPEN"] .sechd h2::before{background:var(--brand)}
[data-status="UPCOMING"] .sechd h2::before{background:var(--exempt)}
[data-status="CLOSED"] .sechd h2::before{background:var(--warn)}
.sechsub{color:var(--muted);font-size:.85rem}
.empty{color:var(--muted);padding:26px;border:1px dashed var(--line);border-radius:var(--r);text-align:center}

/* the density win: a responsive grid, not one tall column */
/* Density: narrower minimum and tighter gap, so a desktop fits four columns where it fit three.
   More cards on screen is the whole point of a card — a reader compares issues, and they cannot
   compare what they have to scroll between. */
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(288px,1fr));gap:12px}

/* card */
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  padding:13px 14px;display:flex;flex-direction:column;
  transition:border-color .2s ease,transform .22s cubic-bezier(.2,.8,.2,1),box-shadow .22s ease}
@media (hover:hover){.card:hover{border-color:color-mix(in oklab,var(--brand) 45%,var(--line-strong))}}
@media (hover:hover){/* Lift only where there's a real pointer — no sticky hover state on touch (Apple §5,§10). */
@media (hover:hover){.card:hover{transform:translateY(-2px);box-shadow:0 12px 26px -18px rgba(15,23,32,.5)}}}
/* Active-card highlight: when you land on a card via a deep link (#ipo-<id>) — the email's
   "View", a DRHP link — it flashes an emerald ring so you don't lose it in the grid.
   scroll-margin clears the sticky filter bar. */
.card{scroll-margin-top:84px}
/* #alerts gets the same clearance, and both get more on a phone, where the filter bar wraps to two
   rows (~128px). Clarity (Sep-Oct 2026) logged dead clicks on the hero's "Email me when an IPO opens":
   the jump worked, but it parked the form's heading UNDER the sticky bar, so it read as nothing
   happening. Same for an email's #ipo-<id> deep link landing a card's title under the bar. */
#alerts{scroll-margin-top:84px}
@media (max-width:640px){.card,#alerts{scroll-margin-top:140px}}
.card:target{border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-light);animation:cardflash 1.6s ease-out 1}
@keyframes cardflash{0%{box-shadow:0 0 0 4px var(--brand)}100%{box-shadow:0 0 0 3px var(--brand-light)}}
/* Phone: the card sizing below was tuned for a 288px+ laptop grid column, which on a phone is
   nearly the full screen width — so every card reads oversized. Tighten padding and type scale
   across the board; nothing here removes content, it just costs it fewer pixels. */
@media (max-width:640px){
  .grid{gap:8px}
  .card{padding:10px 12px}
  .chd-row h3{font-size:.94rem}
  .mono{width:20px;height:20px;font-size:.56rem}
  .chd-tags{margin-left:28px}
  .gmp-pill{padding:3px 7px}
  .gmp-l{font-size:.52rem}
  .gmp-v{font-size:.82rem}
  .corenums{gap:6px;padding:8px 0;margin-top:8px}
  .cn-l{font-size:.56rem}
  .cn-v{font-size:.82rem}
  .subbox{margin-top:9px;padding:7px 9px}
  .subgrid{gap:4px}
  .subcell{padding:4px 2px}
  .subcell .sc-v{font-size:.8rem}
}
/* concise-first card header: monogram + name + status dot, then tags + "when", GMP pill right */
.chd2{display:flex;justify-content:space-between;align-items:flex-start;gap:10px}
.chd-main{min-width:0;flex:1}
.chd-row{display:flex;align-items:center;gap:8px;min-width:0}
.mono{flex:none;width:24px;height:24px;border-radius:999px;display:grid;place-items:center;
  font-size:.62rem;font-weight:700;letter-spacing:.02em;background:var(--brand-light);color:var(--mb-fg);
  border:1px solid color-mix(in oklab,var(--brand) 22%,transparent);font-variant-numeric:tabular-nums}
[data-segment="SME"] .mono{background:var(--sme-bg);color:var(--sme-fg);border-color:color-mix(in oklab,var(--sme) 32%,transparent)}
/* Two lines, then an ellipsis. One line cut "R.K. Fashion Accessories" to "R.K. Fashion Acces..." once
   the stage label took its share of the header row, and a name is the one thing a card cannot lose. */
.chd-row h3{font-size:1rem;font-weight:700;line-height:1.2;min-width:0;overflow:hidden;
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow-wrap:anywhere}
.sdot{flex:none;width:8px;height:8px;border-radius:999px;border:1.5px solid var(--muted-2)}
.sdot-open{background:var(--brand);border-color:var(--brand);box-shadow:0 0 7px 1px rgba(14,159,110,.65)}
.sdot-up{background:transparent;border-color:var(--muted-2)}
.sdot-closed{background:var(--warn);border-color:var(--warn)}
/* tags align under the company name (past the 24px monogram + 8px gap), matching the mockup's ml-8 */
.chd-tags{display:flex;gap:5px;flex-wrap:wrap;align-items:center;margin-top:6px;margin-left:32px}
.chd-tags .when{margin-left:auto;padding-left:6px}
/* GMP band pill — a distinct tinted element, never blended into the exchange numbers (ethos #2) */
.gmp-pill{flex:none;text-align:center;border-radius:var(--r-sm);padding:4px 9px;border:1px solid transparent;line-height:1.15}
.gmp-l{display:block;font-size:.56rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;opacity:.85}
.gmp-v{display:block;font-size:.9rem;font-weight:800;font-variant-numeric:tabular-nums;white-space:nowrap}
.gmp-pill-pos{background:var(--brand-light);color:var(--brand-dark);border-color:rgba(14,159,110,.28)}
html.dark .gmp-pill-pos{color:#6ee7b7}
.gmp-pill-neg{background:var(--warn-bg);color:var(--warn);border-color:var(--warn)}
.gmp-pill-none{background:var(--surface-2);color:var(--muted-2);border-color:var(--line)}
/* core numbers row: issue size · price band · dates */
.corenums{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin-top:10px;
  padding:11px 0;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.cn{display:flex;flex-direction:column;gap:2px;min-width:0}
.cn-l{font-size:.6rem;text-transform:uppercase;letter-spacing:.05em;color:var(--muted-2);white-space:nowrap}
.cn-v{font-size:.9rem;font-weight:700;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
/* Per-IPO FAQ. Collapsed by default so it costs no scroll, and <details> keeps the answer text in
   the DOM either way — a crawler and an answer engine both read it, and the markup finally describes
   content that is actually on the page. */
.faq{display:grid;gap:6px}
.faq-i{border:1px solid var(--line);border-radius:var(--r-sm);background:var(--surface)}
.faq-i summary{cursor:pointer;padding:10px 12px;font-weight:600;font-size:.92rem;list-style:none}
.faq-i summary::-webkit-details-marker{display:none}
/* The question is a real h3 inside the summary, so search engines read the Q&A as headed
   sections; it keeps the summary's look exactly. */
.faq-q{margin:0;font:inherit;color:inherit;letter-spacing:inherit}
.faq-i summary::after{content:"+";float:right;color:var(--muted-2);font-weight:400}
.faq-i[open] summary::after{content:"−"}
@media (hover:hover){.faq-i summary:hover{color:var(--brand)}}
.faq-i p{margin:0;padding:0 12px 11px;font-size:.88rem;color:var(--muted)}

/* Lifecycle track: where this issue is now. Filled dot = passed, ringed = current, hollow = ahead.
   A rule runs behind the dots so the sequence reads as a track rather than four separate labels. */
.lifetrack{list-style:none;display:flex;gap:0;margin:12px 0 0;padding:0;position:relative}
.lifetrack::before{content:"";position:absolute;left:5px;right:5px;top:5px;height:1px;background:var(--line);z-index:0}
.lifetrack li{position:relative;z-index:1;flex:1 1 0;min-width:0;display:flex;flex-direction:column;gap:3px;padding-right:6px}
.lt-dot{width:11px;height:11px;border-radius:50%;background:var(--surface);border:2px solid var(--line-strong);box-sizing:border-box}
.lt-done .lt-dot{background:var(--line-strong);border-color:var(--line-strong)}
.lt-now .lt-dot{background:var(--accent);border-color:var(--accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 22%,transparent)}
.lt-l{font-size:.6rem;text-transform:uppercase;letter-spacing:.05em;color:var(--muted-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lt-d{font-size:.78rem;font-weight:600;font-variant-numeric:tabular-nums;white-space:nowrap}
.lt-now .lt-l{color:var(--accent)} .lt-now .lt-d{color:var(--ink)}
.lt-todo .lt-d{color:var(--muted-2);font-weight:500}
.lifetrack abbr{text-decoration:none;cursor:help}
.lt-note{margin:5px 0 0;font-size:.66rem;color:var(--muted-2)}

/* Section nav. The About and Learn pages existed and were reachable only from a footer link below
   the disclaimer, which for a reader is the same as not existing. */
.nav{display:flex;flex-wrap:wrap;gap:2px 4px;margin:14px 0 0;padding:0;list-style:none}
.nav a{display:inline-block;padding:6px 11px;border-radius:999px;font-size:.82rem;font-weight:600;
  color:var(--muted);text-decoration:none;border:1px solid transparent}
@media (hover:hover){.nav a:hover{color:var(--ink);border-color:var(--line);background:var(--surface)}}
.nav a[aria-current=page]{color:var(--ink);border-color:var(--line-strong);background:var(--surface)}

/* money timeline stepper: solid dot = confirmed, hollow = tentative T+3 */
.stepper{position:relative;display:flex;justify-content:space-between;margin-top:14px}
.stepper-track{position:absolute;top:5px;left:14%;right:14%;height:1px;background:var(--line);z-index:0}
.step{position:relative;z-index:1;flex:1;min-width:0;display:flex;flex-direction:column;align-items:center;text-align:center;gap:4px}
.step-dot{width:11px;height:11px;border-radius:999px;background:var(--line-strong);border:2px solid var(--surface)}
.step-dot-on{background:var(--brand);border-color:var(--surface);box-shadow:0 0 6px rgba(14,159,110,.55)}
.step-dot-past{background:var(--muted-2);border-color:var(--surface)}
.step-lbl{font-size:.62rem;text-transform:uppercase;letter-spacing:.04em;color:var(--muted-2)}
.step-date{font-size:.72rem;font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap}
.step-date-past{color:var(--muted-2);font-weight:400}
.step-exp{color:var(--muted-2);font-weight:400;font-style:italic}
/* subscription box: TOTAL headline + QIB / HNI(NII) / Retail breakdown */
.subbox{margin-top:12px;background:var(--inset);border:1px solid var(--line);border-radius:10px;padding:9px 11px}
.subbox-hd{display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin-bottom:8px}
.subbox-lbl{font-size:.66rem;text-transform:uppercase;letter-spacing:.05em;color:var(--muted-2);font-weight:700}
.subbox-split{margin-left:auto;font-size:.68rem;color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap}
.subbox-none{margin:2px 0 0;font-size:.8rem;color:var(--muted)}
.subgrid{display:grid;grid-template-columns:repeat(4,1fr);gap:6px}
.subcell{display:flex;flex-direction:column;align-items:center;gap:2px;text-align:center;padding:5px 2px;border-radius:6px}
.subcell .sc-l{font-size:.6rem;text-transform:uppercase;letter-spacing:.04em;color:var(--muted-2)}
.subcell .sc-v{font-size:.86rem;font-weight:700;font-variant-numeric:tabular-nums}
.subcell-total{background:var(--brand-light)}
.subcell-total .sc-l{color:var(--brand-dark)} html.dark .subcell-total .sc-l{color:#6ee7b7}
/* shareholder-quota badge */
.shq-badge{display:grid;grid-template-columns:auto 1fr;align-items:baseline;column-gap:6px;margin-top:10px;padding:8px 11px;font-size:.78rem;
  line-height:1.4;background:var(--brand-light);color:var(--brand-dark);border:1px solid rgba(14,159,110,.25);border-radius:10px}
html.dark .shq-badge{color:#6ee7b7}
.shq-badge b{font-weight:700} .shq-star{color:var(--brand)}
/* The deadline sits at the end of the badge, allowed to wrap onto its own line rather than
   squeeze the parent's name, because the name is what makes the date mean anything. Quieter
   than the name on purpose: the name is the instruction, the date is the condition on it. */
.shq-when{grid-column:2;font-weight:600;color:var(--muted);font-size:.74rem}
/* card footer: momentum toggle + one-pager link, pinned to the card bottom */
.cfoot{display:flex;justify-content:space-between;align-items:flex-start;gap:10px;
  margin-top:auto;padding-top:10px;border-top:1px solid var(--line)}
.cfoot .trend{margin-top:0}
.mom-d{margin:0;border:0;padding:0}
.mom-d>summary{font-size:.78rem;font-weight:600;color:var(--brand-dark);cursor:pointer;list-style:none;display:inline-flex;align-items:center;gap:5px}
.mom-d>summary::-webkit-details-marker{display:none}
.mom-d>summary::before{content:'▸';font-size:.7rem;color:var(--muted-2);transition:transform .15s}
.mom-d[open]>summary::before{transform:rotate(90deg)}
html.dark .mom-d>summary{color:#6ee7b7}
.mom-body{margin-top:8px}
.mom-empty{font-size:.76rem;color:var(--muted-2)}
.onepager-link{font-size:.78rem;font-weight:600;color:var(--muted);text-decoration:none;white-space:nowrap;display:inline-flex;align-items:center;gap:4px}
@media (hover:hover){.onepager-link:hover{color:var(--brand-dark)}}
@media (hover:hover){html.dark .onepager-link:hover{color:#6ee7b7}}
.cfoot-l{display:flex;flex-direction:column;gap:6px;align-items:flex-start;min-width:0}
.drhp-link{font-size:.74rem;font-weight:600;color:var(--muted);text-decoration:none;display:inline-flex;align-items:center;gap:3px}
@media (hover:hover){.drhp-link:hover{color:var(--brand-dark)}}
@media (hover:hover){html.dark .drhp-link:hover{color:#6ee7b7}}
.analysis-btn{display:inline-flex;align-items:center;gap:5px;padding:8px 14px;background:var(--brand);color:#fff;border-radius:8px;font:600 .8rem Inter,sans-serif;text-decoration:none;white-space:nowrap;flex:none;align-self:center}
@media (hover:hover){.analysis-btn:hover{background:var(--brand-dark)}}
.act-ic{width:15px;height:15px;flex:none}
/* The IPO calendar (ipoCalendarPage): one block per day, the event kind as a coloured tag. */
.calnav{margin:0 0 16px;font-size:.84rem}
.calday{margin:0 0 14px;border:1px solid var(--line);border-radius:var(--r);background:var(--surface);overflow:hidden}
.calpast{margin:0 0 14px}
.calpast>summary{font-size:.84rem;color:var(--muted)}
.calpast[open]>summary{margin-bottom:10px}
.calday-today{border-color:var(--brand)}
.calday-h{margin:0;padding:9px 14px;font-size:.9rem;font-weight:700;background:var(--surface-2);border-bottom:1px solid var(--line)}
.calday-rel{margin-left:6px;font-size:.72rem;font-weight:700;color:var(--brand-dark)}
.calev{list-style:none;margin:0;padding:0}
.calev li{display:flex;align-items:center;flex-wrap:wrap;gap:6px 10px;padding:9px 14px;border-top:1px solid var(--line)}
.calev li:first-child{border-top:0}
.calev a{font-weight:600;color:var(--ink);text-decoration:none}
@media (hover:hover){.calev a:hover{color:var(--brand-dark)}}
.calm{font-size:.74rem;color:var(--muted)}
.calk{flex:none;min-width:74px;text-align:center;font-size:.68rem;font-weight:700;letter-spacing:.03em;text-transform:uppercase;padding:3px 8px;border-radius:999px}
.calk-opens{background:#e8f0fb;color:#2f5f96} .calk-closes{background:#dcf5e9;color:#0b6b4c}
.calk-allotment{background:#fdf1dc;color:#8a5208} .calk-lists{background:#ecebfb;color:#4a3fa0}
html.dark .calk-opens{background:#14243a;color:#9cc2ee} html.dark .calk-closes{background:#0c2e22;color:#7fe0b6}
html.dark .calk-allotment{background:#33240c;color:#f3c37a} html.dark .calk-lists{background:#211e3d;color:#bdb6f5}
/* The allotment hub (allotmentHubPage): the issue on the left, its registrar's checker on the right. */
.alboard{list-style:none;margin:0 0 22px;padding:0;border:1px solid var(--line);border-radius:var(--r);background:var(--surface)}
.al{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:10px 14px;padding:12px 14px;border-top:1px solid var(--line)}
.al:first-child{border-top:0}
.al-l{display:flex;flex-direction:column;align-items:flex-start;gap:5px;min-width:0}
.al-l a{font-weight:700;color:var(--ink);text-decoration:none}
.al-m{font-size:.76rem;color:var(--muted)}
.al-btn{flex:none;display:inline-flex;align-items:center;gap:6px;padding:9px 14px;border-radius:10px;background:var(--brand);color:#fff;
  font-size:.82rem;font-weight:600;text-decoration:none}
@media (hover:hover){.al-btn:hover{background:var(--brand-dark)}}
.al-none{font-size:.76rem;color:var(--muted)}
/* The GMP board (gmpTodayPage): name and stage on the left, the figure on the right. */
.gmpboard{list-style:none;margin:0 0 22px;padding:0;border:1px solid var(--line);border-radius:var(--r);background:var(--surface)}
.gr{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:11px 14px;border-top:1px solid var(--line)}
.gr:first-child{border-top:0}
.gr-l{display:flex;flex-direction:column;align-items:flex-start;gap:5px;min-width:0}
.gr-l a{font-weight:700;color:var(--ink);text-decoration:none}
@media (hover:hover){.gr-l a:hover{color:var(--brand-dark)}}
.gr-r{display:flex;flex-direction:column;align-items:flex-end;gap:2px;flex:none;text-align:right}
.gr-v{font-size:1.05rem;font-weight:800;font-variant-numeric:tabular-nums}
.gr-pos{color:var(--brand-dark)} .gr-neg{color:#b45309} .gr-none{font-size:.78rem;font-weight:600;color:var(--muted)}
html.dark .gr-pos{color:#6ee7b7}
.gr-n{font-size:.74rem;color:var(--muted)}
/* The Trending strip (trending.ts): one row, scrolling sideways on a phone rather than wrapping. */
.trending{display:flex;align-items:center;gap:8px;overflow-x:auto;scrollbar-width:none;margin:12px 0 6px;padding:2px 0 4px;
  -webkit-mask-image:linear-gradient(to right,#000 88%,transparent);mask-image:linear-gradient(to right,#000 88%,transparent)}
.trending::-webkit-scrollbar{display:none}
.trending-l{flex:none;font-size:.66rem;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--muted-2)}
.trending a{flex:none;font-size:.78rem;font-weight:600;color:var(--brand-dark);background:var(--surface);border:1px solid var(--line);
  border-radius:999px;padding:6px 11px;text-decoration:none;white-space:nowrap}
@media (hover:hover){.trending a:hover{border-color:var(--brand)}}
html.dark .trending a{color:#7fe0b6}
.card-title{color:inherit;text-decoration:none}
@media (hover:hover){.card-title:hover{color:var(--brand-dark);text-decoration:underline;text-underline-offset:2px}}
/* The WHOLE card opens the one-pager (stretched link). Clarity recordings (Sep 2026) showed readers
   tapping the monogram, the GMP pill and the subscription figures and getting nothing — only the
   title text was a link, a small target on a phone. The title's ::after now covers the card; the
   card's own controls (More, DRHP, IPO analysis) sit above it and keep their own action.
   z-index 2 clears .lifetrack li (z 1), which would otherwise poke through as a dead zone. */
.card{position:relative}
.card-title::after{content:"";position:absolute;inset:0;z-index:2;border-radius:inherit}
.card .cmore,.card .cfoot a{position:relative;z-index:3}
@media (hover:hover){.card:hover .card-title{color:var(--brand-dark)}}
.when{font-size:.76rem;font-weight:600;white-space:nowrap;color:var(--muted)}
/* The stage label (stage.ts). Tinted by what the reader is waiting for, never by urgency: no red,
   no pulse. A fall on listing is the one muted-rose chip, because it is a fact about the past. */
.stage{display:inline-block;font-size:.72rem;font-weight:600;line-height:1.2;padding:4px 9px;border-radius:999px;white-space:nowrap}
.stage-upcoming{background:#e8f0fb;color:#2f5f96}
.stage-open,.stage-listed{background:#dcf5e9;color:#0b6b4c}
.stage-closing,.stage-allotment{background:#fdf1dc;color:#8a5208}
.stage-listing{background:#ecebfb;color:#4a3fa0}
.stage-down{background:#fbeaea;color:#9b2c2c}
.stage-quiet{background:var(--line);color:var(--muted)}
html.dark .stage-upcoming{background:#14243a;color:#9cc2ee}
html.dark .stage-open,html.dark .stage-listed{background:#0c2e22;color:#7fe0b6}
html.dark .stage-closing,html.dark .stage-allotment{background:#33240c;color:#f3c37a}
html.dark .stage-listing{background:#211e3d;color:#bdb6f5}
html.dark .stage-down{background:#3a1717;color:#f2a9a9}
.when-open{color:var(--brand-dark)} .when-up{color:var(--exempt)}
html.dark .when-open{color:#6ee7b7}
.tags{display:flex;gap:5px;flex-wrap:wrap;margin-top:8px}
.tag{font-size:.68rem;padding:2px 8px;border-radius:999px;background:var(--brand-light);
  color:var(--brand-dark);font-weight:600}
html.dark .tag{color:#6ee7b7}
.tag-soft{background:transparent;border:1px solid var(--line);color:var(--muted);font-weight:500}
.tag.tag-sme{background:var(--sme-bg);color:var(--sme-fg)}
html.dark .tag.tag-sme{color:var(--sme-fg)}
.dates{margin:8px 0 0;font-size:.76rem;color:var(--muted-2);font-variant-numeric:tabular-nums}
/* lifecycle timetable */
.tt{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 10px;margin:6px 0 0;font-size:.74rem;
  color:var(--muted);font-variant-numeric:tabular-nums}
.tt-lbl{font-size:.64rem;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--muted-2);
  border:1px solid var(--line);border-radius:999px;padding:1px 7px;cursor:help}
.tt-item b{color:var(--ink);font-weight:600}

/* shared "hot/cool" figure colour — used by the subscription box and the one-pager */
.stat-hot{color:var(--brand-dark)} .stat-cool{color:var(--muted)}
html.dark .stat-hot{color:#6ee7b7}

/* subscription — clean category breakdown, no bars */
.subs{margin-top:12px}
.subhd{display:flex;align-items:center;gap:7px;margin-bottom:6px;flex-wrap:wrap}
.blabel{font-size:.7rem;text-transform:uppercase;letter-spacing:.05em;color:var(--muted-2);font-weight:600}
.cats{display:grid;grid-template-columns:repeat(auto-fit,minmax(88px,1fr));gap:6px 14px}
.catrow{display:flex;justify-content:space-between;align-items:baseline;gap:8px;font-size:.82rem;border-top:1px solid var(--line);padding-top:5px}
.catlbl{color:var(--muted)}
.catval{font-variant-numeric:tabular-nums;font-weight:700}

/* pills */
.pill{font-size:.66rem;padding:2px 7px;border-radius:999px;border:1px solid var(--line);color:var(--muted);font-weight:600}
.pill-ok{background:var(--brand-light);color:var(--brand-dark);border-color:transparent}
.pill-warn,.pill-stale{background:var(--warn-bg);color:var(--warn);border-color:transparent}
html.dark .pill-ok{color:#6ee7b7}

/* collapsible detail (GMP caveat + DRHP) */
details{margin-top:10px;border-top:1px solid var(--line);padding-top:9px}
summary{cursor:pointer;font-size:.8rem;font-weight:600;color:var(--ink);list-style:none;
  display:flex;align-items:center;gap:6px;flex-wrap:wrap}
summary::-webkit-details-marker{display:none}
summary::before{content:'▸';color:var(--muted-2);font-size:.7rem;transition:transform .15s}
details[open] summary::before{transform:rotate(90deg)}
/* ONE marker per disclosure. The ▸ above is the default; a component that draws its own (the FAQ's
   +/−, the notice's triangle, the card's chevron) turns it off, or the reader sees two arrows. */
.faq-i summary::before,.notice>summary::before,.cmore>summary::before{content:none}
.faq-i summary{flex-wrap:nowrap;align-items:flex-start;gap:12px}
.faq-i summary::after{margin-left:auto;flex:none}
.op-more{margin-top:8px}
.op-more>summary{font-size:.8rem;color:var(--brand-dark)}
.drhp>summary{color:var(--brand-dark);font-size:.84rem}
.drhp{margin-top:8px}
.caveat-body,.drhp-body{padding:8px 0 2px}
.kv{display:flex;justify-content:space-between;gap:10px;padding:3px 0;font-size:.82rem}
.kv span{color:var(--muted)}
.srclist{margin:6px 0;padding-left:18px;font-size:.8rem;color:var(--muted)}
.warn{background:var(--warn-bg);border-left:3px solid var(--warn);padding:9px 11px;
  border-radius:8px;font-size:.78rem;margin:8px 0 0;line-height:1.5}
.pills{display:flex;flex-wrap:wrap;gap:5px;margin:8px 0}
.flags{list-style:none;padding:0;margin:8px 0;font-size:.8rem}
.flags li{padding:2px 0}
.fin{border-collapse:collapse;width:100%;font-size:.78rem;margin:8px 0}
.fin th,.fin td{text-align:right;padding:3px 6px;border-bottom:1px solid var(--line)}
.fin th:first-child,.fin td:first-child{text-align:left}
.risks{margin-top:6px}.risks ul{margin:4px 0;padding-left:18px;font-size:.8rem;color:var(--muted)}
.proscons{display:grid;grid-template-columns:1fr 1fr;gap:10px 16px;margin:10px 0}
@media (max-width:460px){.proscons{grid-template-columns:1fr}}
/* The GMP table. Four columns have to fit a 375px phone without sideways scrolling, because the
   third one is the reason the page exists. On a phone the source count moves inline under the
   premium and its own column goes away, which buys back roughly a quarter of the width. */
.gmptbl{width:100%;border-collapse:collapse;margin:14px 0 4px}
.gmptbl th{text-align:left;padding:8px 12px;font-size:.78rem;font-weight:600;color:var(--muted);
  border-bottom:2px solid var(--line)}
.gmptbl td{padding:9px 12px;border-bottom:1px solid var(--line);vertical-align:top}
.gmptbl th.src,.gmptbl td.src,.gmptbl th:nth-child(3),.gmptbl td.gmpv{text-align:right}
.gmptbl .gmpv{font-weight:700;font-variant-numeric:tabular-nums;white-space:nowrap}
.gmptbl .srcin{display:none}
@media (max-width:640px){
  .gmptbl th,.gmptbl td{padding:8px 4px}
  .gmptbl th:first-child,.gmptbl td:first-child{padding-left:0}
  .gmptbl th.src,.gmptbl td.src{display:none}
  .gmptbl .srcin{display:block;font-size:.7rem;font-weight:400}
  /* The GMP cell is the last VISIBLE one once .src is hidden, and :last-of-type would still aim at
     the hidden cell, so this targets the column by position. */
  .gmptbl th:nth-child(3),.gmptbl td:nth-child(3){padding-right:0}
}
.pc ul{margin:4px 0;padding-left:16px;font-size:.8rem;color:var(--muted)}
.pc li{padding:1px 0}
.pc-pro>b{color:var(--brand-dark)} .pc-con>b{color:var(--warn)}
.pc-pro li::marker{color:var(--brand)} .pc-con li::marker{color:var(--warn)}
.peers{margin-top:8px}
/* offer-doc link + analysis sections (one-pager) */
.dacts{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:12px}
.doclink{display:inline-flex;align-items:center;gap:4px;font-size:.78rem;font-weight:600;color:var(--brand-dark);
  text-decoration:none;background:var(--brand-light);border:1px solid transparent;border-radius:999px;padding:3px 11px}
@media (hover:hover){.doclink:hover{border-color:var(--brand)}}
.oa-sec{margin:10px 0 0;padding-top:9px;border-top:1px solid var(--line)}
.oa-sec:first-child{border-top:0;padding-top:0}
.oa-lbl{display:block;font-size:.64rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--muted-2);margin-bottom:5px}
.thin{margin:2px 0;padding-left:16px;font-size:.8rem;color:var(--muted)}
.thin li{padding:1px 0}
/* shareholder-quota callout */
.shq{margin-top:12px;padding:9px 12px;background:var(--brand-light);border-left:3px solid var(--brand);
  border-radius:8px;font-size:.82rem;line-height:1.5;color:var(--ink)}
.shq b{color:var(--brand-dark)}

/* top GMP notice — one calm disclaimer for the whole page */
.notice{margin:20px 0 4px;padding:10px 14px;border:1px solid var(--line);border-left:3px solid var(--muted-2);
  border-radius:var(--r-sm);background:var(--surface-2);color:var(--muted);font-size:.82rem;line-height:1.5}
.notice b{color:var(--ink)}
.notice>summary{cursor:pointer;list-style:none;color:var(--ink)}
.notice>summary::-webkit-details-marker{display:none}
.notice>summary::after{content:"";float:right;margin:5px 0 0 8px;border:5px solid transparent;border-top-color:var(--muted-2);transition:transform .2s}
.notice[open]>summary::after{transform:rotate(180deg)}
.notice>p{margin:8px 0 0}
/* nowrap because these labels read badly broken mid-phrase; the margin is the gutter for when two
   of them share a line, and each is short enough to fit a 375px phone on its own line. */
.notice-learn{display:inline-block;margin-top:2px;margin-right:14px;font-weight:600;white-space:nowrap}
/* ── Hero ────────────────────────────────────────────────────────────────────
   Short by design, because everything here is preamble to the list below it. One heading, four
   scannable points, the tracked-listing figures on ONE slim line, one call to action. The phone
   rules at the bottom compress it further so the first IPO card is on screen without scrolling. */
.brandname{margin:0;font-size:1rem;font-weight:700;letter-spacing:-.01em}
/* Lede left, CTA right: the hero costs the height of the taller column, not the sum of both. */
/* ONE flowing line of claims rather than four stacked bullets. Same words, a quarter of the
   height: this list alone used to cost ~110px directly above the first card. */
/* One line: label, then three figures separated by thin rules. Wraps rather than overflows. */
.stats{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 14px;margin:4px 0 22px;padding:9px 14px;
  border:1px solid var(--line);border-radius:999px;background:var(--surface);font-size:.82rem;color:var(--muted)}
.stats-hd{font-size:.7rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--brand-dark)}
.stat{display:inline-flex;align-items:baseline;gap:5px;padding-left:14px;border-left:1px solid var(--line)}
.stat:first-of-type{padding-left:0;border-left:0}
.stat b{font-size:.98rem;font-weight:700;color:var(--ink);letter-spacing:-.01em;font-variant-numeric:tabular-nums}
.stat b.stat-pos{color:var(--brand-dark)}
/* Phone: strip the hero to its job so the list starts high on the screen. */
@media (max-width:640px){
  /* One column again, but a SHORT one. The phone has no room for a second column, so the budget
     comes out of the copy instead: two claims, a compact button, and the note folded away. This
     is what puts a whole IPO card on screen at load instead of 22% of one. */
  /* Data-first on a phone: the hero collapses to one row — the promise on the left, a compact
     "get alerts" pill on the right — and the value-prop bullets step aside (they are restated at
     the signup form, where they are actionable). This is what lifts the first card near the top. */
  .stats{margin:2px 0 16px;padding:8px 12px;border-radius:var(--r);gap:4px 10px;font-size:.76rem}
  .stats-hd{width:100%;font-size:.62rem}
  .stat{padding-left:10px}
  .stat b{font-size:.9rem}
}
/* Signup: the benefit points that replaced the single vague line */
.signup-points li{position:relative;padding-left:18px;margin:4px 0;font-size:.84rem;color:var(--muted)}
.signup-points li::before{content:"";position:absolute;left:3px;top:.5em;width:5px;height:5px;border-radius:50%;background:var(--brand)}
/* Card header right side: the GMP pill sits above the timing chip */
.chd-right{display:flex;flex-direction:column;align-items:flex-end;gap:6px;flex:none}
/* Card meta line — replaces the row of competing tag pills */
.chd-meta{margin:3px 0 0;font-size:.76rem;color:var(--muted)}
.seg-sme{display:inline-block;margin-left:6px;padding:1px 7px;border-radius:999px;background:var(--sme-bg);
  color:var(--sme-fg);font-size:.66rem;font-weight:700}
.prov{border-bottom:1px dotted var(--line-strong)}
.cn-v.cn-pos{color:var(--brand-dark)}
/* Recently closed as a dense list, not twelve cards */
/* The column label for the listed section. Small and quiet, but it is the only thing separating an
   OUTCOME from the grey-market ESTIMATES in the section above, and both render as a percentage. */
/* The card disclosure. Shut by default and deliberately quiet: the card is the scan surface, and a
   chart plus a sentence on every one of eight cards turns a comparison into a wall. <details> so it
   works with no JavaScript, same pattern as the board filter. */
.cmore{margin:6px 0 0;border-top:1px solid var(--line);padding-top:6px}
.cmore>summary{display:inline-flex;align-items:center;gap:5px;cursor:pointer;list-style:none;
  appearance:none;font-size:.76rem;font-weight:600;color:var(--muted);padding:2px 0}
.cmore>summary::-webkit-details-marker{display:none}
@media (hover:hover){.cmore>summary:hover{color:var(--ink)}}
/* The chevron: down when shut, up when open. Drawn rather than an icon font, so it inherits colour
   and costs no request. */
.cmore>summary::after{content:"";flex:none;width:6px;height:6px;margin-top:-3px;
  border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(45deg)}
.cmore[open]>summary::after{margin-top:3px;transform:rotate(-135deg)}
.cmore-body{padding:4px 0 2px}
.cmore-odds{margin:6px 0 0;font-size:.82rem;line-height:1.5}
.cmore-odds .muted{display:block;margin-top:2px}
/* The GMP trend. Tinted by direction, and deliberately quiet: it sits under the exchange figures
   and must not compete with them, because it is the one number on the card nobody stands behind. */
.gmp-trend{display:flex;align-items:center;gap:8px;margin:6px 0 2px}
.spark{flex:none;display:block;opacity:.9}
.spark-up{color:var(--brand)}
.spark-dn{color:var(--warn)}
.spark-fl{color:var(--muted-2)}
.gmp-trend-t{white-space:nowrap}
@media (max-width:640px){.gmp-trend-t{white-space:normal}}
.closedlist-cap{margin:0 0 8px;font-size:.76rem;color:var(--muted);letter-spacing:.01em}
/* The listing price sits ahead of the percentage and reads as the primary fact: a reader checking
   how an issue opened wants the price first, the move second. */
.cl-price{font-variant-numeric:tabular-nums;font-weight:600}
.cl-sep{opacity:.5}
.closedlist{list-style:none;margin:0;padding:0;border:1px solid var(--line);border-radius:var(--r);
  background:var(--surface);overflow:hidden}
.closedlist li{display:flex;align-items:center;gap:8px;padding:11px 14px;border-top:1px solid var(--line);font-size:.9rem}
.closedlist li:first-child{border-top:0}
.closedlist li>a{flex:1;min-width:0;color:var(--ink);text-decoration:none;font-weight:500;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
@media (hover:hover){.closedlist li>a:hover{color:var(--brand-dark)}}
.cl-g{font-weight:700;font-variant-numeric:tabular-nums;white-space:nowrap}
.cl-pos{color:var(--brand-dark)} .cl-neg{color:var(--warn)} .cl-pend{color:var(--muted-2);font-weight:500;font-size:.8rem}
/* The premium a listed row settled. Muted and unfilled on purpose: it sits beside the real opening
   figure, and an estimate that reads as prominent as the outcome it was wrong about is worse than
   not showing it. Tabular so the column scans. */
.cl-gmp{font-size:.78rem;color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap}
@media(max-width:520px){.cl-gmp{display:none}}
/* One filter bar, not two floating groups */
.fdiv{width:1px;align-self:stretch;background:var(--line);margin:0 2px}
/* The one disclaimer line, at the foot of the content instead of above it */
.pagenote{margin:26px 0 0;padding-top:14px;border-top:1px solid var(--line);font-size:.78rem;
  color:var(--muted);line-height:1.6}
.pagenote b{color:var(--ink);font-weight:600}
.baserate-note>summary{font-size:.9rem}
.baserate{margin:8px 2px 4px;font-size:.84rem;color:var(--muted);line-height:1.5}
.baserate b{color:var(--ink);font-weight:700}
/* Phone: compact the masthead and let the GMP disclaimer collapse to its headline (JS drops the
   open attribute at ≤640px, tap to expand) so the first card sits near the top, not half a screen
   down. Desktop keeps it fully open. */
@media(max-width:640px){
  /* Logo, date and toggle share ONE row: the logo carries the brand, so the "IPO agent" text
     label is redundant on a phone and steps aside to reclaim the width. */
  .brand-mark img{height:20px;width:auto}
  /* Primary nav: one horizontally-scrollable row, not two wrapped thumb-height rows. */
  .nav{flex-wrap:nowrap;overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none;
    gap:2px;margin:6px 0 0;padding-bottom:2px}
  .nav::-webkit-scrollbar{display:none}
  .nav li{flex:0 0 auto} .nav a{font-size:.82rem}
  /* Four stages still fit a phone at this size; the labels ellipsis before the dates do. */
  .lifetrack li{padding-right:4px} .lt-l{font-size:.55rem} .lt-d{font-size:.72rem}
  .filters{margin-top:2px;padding:8px 22px 8px}
  .fbtn{min-height:44px;padding:10px 15px} /* comfortable thumb target */
  .notice{margin:10px 0 4px}
}
/* per-card data flag — highlights the one affected issue, not the whole page */
/* subscription momentum sparkline */
.trend{display:flex;align-items:center;gap:8px;margin-top:12px;flex-wrap:wrap}
.trend .spark{flex:none;color:var(--brand)}
.trend .spark polyline{fill:none;stroke:currentColor;stroke-width:2;vector-effect:non-scaling-stroke;stroke-linejoin:round;stroke-linecap:round}
.trend .spark .cap{fill:currentColor}
.spark-up{color:var(--brand)} .spark-down{color:var(--warn)} .spark-flat{color:var(--muted-2)}
.trend .tl{font-size:.72rem;color:var(--muted-2)} .trend .tl b{color:var(--ink);font-weight:700}
.mom{font-size:.7rem;font-weight:700;padding:2px 8px;border-radius:999px;display:inline-flex;align-items:center;gap:4px;white-space:nowrap}
.mom-up{color:var(--brand-dark);background:var(--brand-light)}
.mom-down{color:var(--warn);background:var(--warn-bg)}
.mom-flat{color:var(--muted);background:var(--surface-2);border:1px solid var(--line)}

/* signup */
.signup{position:relative;background:var(--brand-light);border:1px solid var(--brand);border-radius:var(--r);
  padding:22px;
  /* A glow rather than a louder colour. The block already sits on the brand tint, so recolouring it
     would fight the cards; this lifts it off the page in the brand's own colour, so the eye lands
     there first without anything shouting. */
  box-shadow:0 0 0 4px color-mix(in srgb, var(--brand) 12%, transparent),
             0 14px 40px -22px color-mix(in srgb, var(--brand) 65%, transparent);
  animation:signup-breathe 4.5s ease-in-out 1.5s infinite}
/* Slow, and it starts late, so it never pulls at somebody mid-sentence. The global reduced-motion
   block below switches every animation off for anyone who has asked for that. */
@keyframes signup-breathe{
  0%,100%{box-shadow:0 0 0 4px color-mix(in srgb, var(--brand) 12%, transparent),
                     0 14px 40px -22px color-mix(in srgb, var(--brand) 65%, transparent)}
  50%    {box-shadow:0 0 0 7px color-mix(in srgb, var(--brand) 20%, transparent),
                     0 18px 48px -22px color-mix(in srgb, var(--brand) 80%, transparent)}
}
.signup-in{display:grid;grid-template-columns:1fr 1.4fr;gap:22px;align-items:center}
@media(max-width:720px){.signup-in{grid-template-columns:1fr}}
.signup h2{font-size:1.15rem;font-weight:700}
.fields{display:grid;grid-template-columns:1fr 1fr auto;gap:8px}
@media(max-width:520px){.fields{grid-template-columns:1fr}}
.fields input{padding:10px 12px;border:1px solid var(--line-strong);border-radius:var(--r-sm);
  font:inherit;background:var(--surface);color:var(--ink);min-width:0}
input[name=name]{grid-column:1/-1}
button{background:var(--brand);color:#fff;border:0;border-radius:var(--r-sm);padding:10px 18px;
  font:inherit;font-weight:600;cursor:pointer;white-space:nowrap}
@media (hover:hover){button:hover{background:var(--brand-dark)}} button:disabled{opacity:.6;cursor:default}
.consent{display:flex;gap:8px;align-items:flex-start;font-size:.78rem;margin-top:10px;color:var(--muted)}
.formnote{margin:8px 0 0;min-height:1.1em}
.otp-step{display:none;flex-direction:column;align-items:flex-start;gap:8px;margin-top:10px}
.otp-step.show{display:flex}
.otp-step input{font:inherit;font-size:1.1rem;letter-spacing:.3em;text-align:center;width:140px;
  padding:8px 10px;border-radius:var(--r-sm);border:1px solid var(--line-strong);background:var(--surface);color:var(--ink)}
.otp-step .otp-actions{display:flex;gap:8px;align-items:center}
.otp-step .muted-btn{background:none;border:0;color:var(--muted-2);font-size:.76rem;text-decoration:underline;
  cursor:pointer;padding:4px;font:inherit}
@media (hover:hover){.otp-step .muted-btn:hover{color:var(--ink)}}
.already-joined{display:none;align-items:center;gap:10px;padding:12px 16px;border-radius:var(--r-sm);
  background:var(--brand-light);border:1px solid var(--line);font-size:.86rem;color:var(--ink)}
.already-joined.show{display:flex}

/* The kredfit wordmark. These live in the SHARED sheet, not OP_CSS: BRAND_ATTR is in every
   page's footer, and the one-pager is the only page that loads OP_CSS — so sizing the mark
   there would have shipped it at its intrinsic 1240x336 on the index, hub, learn and stories. */
.kredfit-mark{display:inline-flex;color:var(--brand-dark);line-height:0}
.kredfit-mark svg{height:1.05em;width:auto;display:block}  /* height only; width follows the viewBox */
html.dark .kredfit-mark{color:var(--mb-fg)}
/* Available to assistive tech and to text extraction, absent from the visual layout. */
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

/* gaps + footer */
.gaps{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);padding:20px}
.gaps h2{font-size:1rem;font-weight:700;margin-bottom:8px}
.gaps ul{margin:0;padding-left:18px;color:var(--muted);font-size:.86rem}
.gaps li{margin:5px 0}
footer{border-top:1px solid var(--line);margin-top:36px;padding:22px;font-size:.82rem;color:var(--muted)}
.sitefoot-social{display:flex;align-items:center;gap:10px;font-size:.82rem;font-weight:600;color:var(--muted)}
.sitefoot-social .social-attr{display:inline-grid;place-items:center;width:34px;height:34px;border-radius:50%;color:#fff;background:#111;text-decoration:none}
.sitefoot-social .social-attr:first-of-type{background:radial-gradient(circle at 30% 107%,#fdf497 0%,#fdf497 5%,#fd5949 45%,#d6249f 60%,#285aeb 90%)}
html.dark .sitefoot-social .social-th,html.dark .sitefoot-social .social-x{background:#2a2f36}
.op-updated{margin:18px 0 0;font-size:.76rem;color:var(--muted-2)}
.op-official{margin:22px 0 4px;font-size:.78rem;color:var(--muted);line-height:1.6}
.op-official a{color:var(--brand-dark);font-weight:600}
.sitefoot{display:flex;flex-direction:column;gap:12px}
.sitefoot p{margin:0}
.sitefoot-nav{display:flex;flex-wrap:wrap;gap:6px 20px}
.sitefoot-nav a{color:var(--ink);font-weight:600;font-size:.86rem;text-decoration:none;padding:4px 0}
@media (hover:hover){.sitefoot-nav a:hover{color:var(--brand-dark);text-decoration:underline;text-underline-offset:2px}}
.sitefoot-legal{font-size:.74rem;line-height:1.5;color:var(--muted);max-width:52ch}
.sitefoot-brand{display:flex;flex-wrap:wrap;align-items:center;gap:6px 18px}
.sitefoot-brand .kredfit-attr{margin-top:0}
.sitefoot-legal a{color:inherit;text-underline-offset:2px}

/* standalone one-pager page */
.op-page{max-width:840px;padding-bottom:32px}
.op-signup{margin:22px 0}
.related{margin:22px 0}
.related h2{font-size:1.05rem;font-weight:700;margin-bottom:8px}
.related-list{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:6px 16px}
.related-list li{font-size:.88rem;padding:5px 0;border-top:1px solid var(--line)}
.related-list a{color:var(--brand-dark);text-decoration:none;font-weight:600}
@media (hover:hover){.related-list a:hover{text-decoration:underline}}
/* /ipo/ hub directory */
.hub-list{list-style:none;margin:0 0 8px;padding:0}
.hub-list li{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:4px 14px;
  padding:9px 0;border-top:1px solid var(--line)}
.hub-list a{color:var(--ink);text-decoration:none;font-weight:600}
@media (hover:hover){.hub-list a:hover{color:var(--brand-dark);text-decoration:underline}}
.hub-filter{margin:0 0 12px}
.hub-filter input{width:100%;max-width:340px;padding:10px 12px;border:1px solid var(--line-strong);border-radius:var(--r-sm);
  font:inherit;font-size:.9rem;background:var(--surface);color:var(--ink)}
.hub-filter input:focus-visible{outline:2px solid var(--brand);outline-offset:1px;border-color:var(--brand)}
/* Learn / glossary */
.learn{margin:6px 0}
.learn-item{padding:14px 0;border-top:1px solid var(--line)}
.learn-item h2{font-size:1.02rem;font-weight:700;margin:0 0 5px;letter-spacing:-.01em}
.learn-item p{margin:0;color:var(--muted);font-size:.92rem;line-height:1.55}
.learn-cta{margin:14px 0 18px;padding:13px 15px;background:var(--brand-light);border:1px solid var(--line);border-radius:var(--r);font-size:.9rem;color:var(--ink)}
.learn-cta a{font-weight:600;white-space:nowrap}
/* per-term Learn pages */
.learn-item h2>a{color:inherit;text-decoration:none}
@media (hover:hover){.learn-item h2>a:hover{color:var(--brand-dark)}}
.learn-h1{margin:22px 0 10px;font-size:clamp(1.4rem,3.6vw,1.75rem);font-weight:700;letter-spacing:-.022em;line-height:1.18}
.learn-a{margin:0 0 18px;font-size:1.02rem;line-height:1.65;color:var(--ink);max-width:62ch}
.learn-rel{margin:22px 0 0;padding-top:16px;border-top:1px solid var(--line)}
.learn-rel h2{margin:0 0 8px;font-size:.86rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--muted)}
.learn-rel ul{margin:0;padding-left:18px;color:var(--muted)}
.learn-rel li{margin:5px 0;font-size:.94rem}
/* stories: long-form body copy, measured for reading rather than scanning */
.story-body{max-width:66ch}
.story-body p{margin:0 0 14px;font-size:1rem;line-height:1.72;color:var(--ink)}
.story-body .legal-list{margin:0 0 14px}
/* legal pages (privacy, terms) */
.legal-list{margin:8px 0 0;padding-left:20px;color:var(--muted);font-size:.92rem;line-height:1.6}
.legal-list li{margin:4px 0}
.notice-pending{border-left-color:var(--warn);margin-bottom:14px}
.hub-meta{font-size:.8rem;color:var(--muted);font-variant-numeric:tabular-nums}
.op-page .tags{margin-top:8px}
.op-page .drhp{border-top:1px solid var(--line);margin-top:14px}
.op-back{margin:0 0 6px;font-size:.82rem}
.op-back a{color:var(--brand-dark);text-decoration:none} @media (hover:hover){.op-back a:hover{text-decoration:underline}}
.op-pending{padding:14px;border:1px dashed var(--line);border-radius:var(--r);margin:14px 0}
@media print{
  .theme-btn,.op-back{display:none}
  .mast{background:none;color:#000;border-bottom:1px solid #ccc} .mast .brand-mark img{filter:none}
  a{color:inherit} body{background:#fff}
  .notice,.sources,.subs,.tt,.shq,.oa-sec,.fin,.proscons{break-inside:avoid}
}

/* Accessibility (Apple §14). Reduced motion → drop transforms, keep the change instant;
   reduced transparency → make the sticky filter bar solid, no blur. */
@media (prefers-reduced-motion: reduce){
  *{transition-duration:.01ms !important;animation-duration:.01ms !important}
  .card:hover{transform:none}
  .fbtn:active{transform:none}
  #ipobg{display:none}  /* freeze the living backdrop; the static ::before wash remains */
}
@media (prefers-reduced-transparency: reduce){
  .filters{background:var(--surface-2);backdrop-filter:none;-webkit-backdrop-filter:none}
  html.dark .filters{background:var(--surface-2)}
}
/* The masthead and home hero on a phone. Last in the sheet, after the filter bar's own phone block. */
@media (max-width:640px){
  .mast-in{padding:6px 16px}
  /* Logo and theme on the first row, the sections on a second row that scrolls sideways. */
  .mast nav{order:3;flex-basis:100%}
  .home-hero{margin:8px 0 4px}
  /* The first section heading sits close under the filter bar, so the first card comes up. */
  .statsec{margin-top:12px}
  .home-hero-top{flex-wrap:nowrap}
  .home-h1{font-size:1.25rem}
  .home-cta{padding:9px 11px;font-size:.78rem;white-space:normal;text-align:center;max-width:52%}
  .home-live{margin:6px 0 8px;font-size:.72rem}
  /* One slim sticky row: no box around the two dropdowns, which already have their own. */
  .filters{padding:6px 16px}
  .fbar{border:0;background:transparent;padding:0}
}

.sg{margin:20px 0 24px;padding:16px 18px;border:1px solid var(--line);border-radius:var(--r);background:var(--surface)}
.sg figcaption{margin-top:12px;font-size:.8rem;color:var(--muted);line-height:1.5}
.sg-check{list-style:none;margin:0;padding:0}
.sg-check li{display:flex;justify-content:space-between;align-items:center;gap:12px;padding:9px 0;border-top:1px solid var(--line);font-size:.88rem}
.sg-check li:first-child{border-top:0}
.sg-v{flex:none;font-weight:700;font-size:.8rem;padding:3px 10px;border-radius:999px}
.sg-no .sg-v{background:#fbeaea;color:#9b2c2c} .sg-ok .sg-v{background:#dcf5e9;color:#0b6b4c}
html.dark .sg-no .sg-v{background:#3a1717;color:#f2a9a9} html.dark .sg-ok .sg-v{background:#0c2e22;color:#7fe0b6}
.sg-steplist{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px}
.sg-steplist li{display:flex;flex-direction:column;gap:4px;padding:12px;border-radius:10px;background:var(--surface-2);font-size:.82rem;color:var(--muted)}
.sg-steplist b{color:var(--ink);font-size:.9rem}
.sg-n{display:grid;place-items:center;width:28px;height:28px;border-radius:50%;background:var(--brand);color:#fff;font-weight:800;font-size:.85rem}
.sg-bar{display:flex;height:30px;border-radius:8px;overflow:hidden}
.sg-seg{display:grid;place-items:center;color:#fff;font-size:.74rem;font-weight:700;white-space:nowrap}
.sg-ret{background:#0e9f6e} .sg-nii{background:#7c5cbf} .sg-qib{background:#4c7fb8}
.sg-note{margin:14px 0 8px;font-size:.88rem}
.sg-dots{display:grid;grid-template-columns:repeat(20,1fr);gap:4px;max-width:360px}
.sg-dot{aspect-ratio:1;border-radius:50%;background:var(--line)}
.sg-dot-on{background:var(--brand)}
.sg-timeline{list-style:none;margin:0;padding:0 0 0 18px;border-left:3px solid var(--line)}
.sg-timeline li{position:relative;display:flex;flex-direction:column;gap:2px;padding:6px 0 12px 14px;font-size:.84rem;color:var(--muted)}
.sg-timeline li::before{content:"";position:absolute;left:-27px;top:9px;width:14px;height:14px;border-radius:50%;background:var(--muted-2);border:3px solid var(--surface)}
.sg-timeline b{color:var(--ink)}
.sg-anc::before{background:#4c7fb8!important} .sg-pre::before{background:#7c5cbf!important} .sg-pro::before{background:#0e9f6e!important}

@media (pointer:coarse){
  /* Primary navigation: the worst offender, and the one a mis-tap costs the most. */
  .nav{gap:6px 8px}
  .nav a{padding:11px 14px;min-height:44px;display:inline-flex;align-items:center}
  /* Filter pills sit in a sticky bar and are tapped repeatedly while scanning the list. */
  .fbtn{padding:11px 16px;min-height:44px}
  /* Icon buttons have no text to enlarge their box, so they need it set. */
  .theme-btn{min-width:44px;min-height:44px}
  /* A disclosure the reader opens and closes; the whole row should be the target. */
  .faq-i summary{padding:13px 12px;min-height:44px}
  /* Form controls: a mistyped email is a lost subscriber. */
  .fields input,.fields button,.signup button{min-height:44px}
  /* Inline text links in prose stay text, but the tappable ones get breathing room. */
  .sitefoot-nav a,.related-list a,.hub-list a,.op-back-link{padding:4px 0;display:inline-block}
}

.freshbar{position:fixed;left:50%;transform:translateX(-50%);bottom:16px;z-index:60;
  display:flex;align-items:center;gap:12px;width:max-content;max-width:calc(100% - 24px);
  padding:8px 8px 8px 16px;border-radius:12px;
  background:var(--surface);border:1px solid var(--line-strong);
  box-shadow:0 10px 30px -12px rgba(0,0,0,.35);
  font-size:.86rem;line-height:1.3;color:var(--ink)}
.freshbar-t{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:500}
.freshbar-go{flex:none;appearance:none;cursor:pointer;font:inherit;font-weight:600;
  padding:7px 14px;border-radius:8px;border:0;background:var(--brand);color:#fff}
.freshbar-x{flex:none;appearance:none;cursor:pointer;background:none;border:0;
  width:32px;height:32px;font-size:1.2rem;line-height:1;color:var(--muted)}
/* Phone: a full-width bar pinned above the bottom edge, not a centred pill. The pill shrank to fit
   and wrapped its text one word per line into a blob (owner screenshot, 2026-10-08). */
@media (max-width:640px){.freshbar{left:12px;right:12px;transform:none;width:auto;max-width:none;bottom:12px}}

.op-brief{margin:14px 0}
.subs-note{margin-top:10px;padding:10px 12px;border-radius:10px;background:var(--warn-bg)}
.subs-note b{display:block;font-size:.88rem;color:var(--ink);margin:2px 0}
.subs-note span:last-child{display:block;font-size:.8rem;color:var(--muted);line-height:1.5}
.ob-h{font-size:.72rem;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);margin:16px 0 8px}
.ob-card{background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:2px 16px}
.ob-so{padding:12px 0;border-bottom:1px solid var(--line)}
.ob-so:last-child{border-bottom:0}
.ob-so b{display:block;font-size:.95rem;line-height:1.35;color:var(--ink)}
.ob-d{display:block;font-size:.84rem;color:var(--muted);margin-top:3px;line-height:1.5}
.ob-pg{font-size:.72rem;color:var(--muted-2);white-space:nowrap}
.ob-pill{display:inline-block;margin:0 0 4px;font-size:.62rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;border-radius:6px;padding:2px 6px}
.ob-c{color:var(--warn);background:var(--warn-bg)}
.ob-f{color:var(--brand-dark);background:var(--brand-light)}
.ob-qs{list-style:none;margin:0;padding:0;display:grid;gap:8px}
.ob-qs li{display:flex;gap:12px;background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:12px 16px}
.ob-qs b{font-size:.93rem;color:var(--ink)}
.ob-n{flex:none;width:24px;height:24px;border-radius:50%;background:var(--brand-light);color:var(--brand-dark);font-weight:700;font-size:.8rem;display:grid;place-items:center}
.ob-note{font-size:.75rem;color:var(--muted-2);margin:8px 2px 0}
.ob-qs .ob-pts{display:block;margin:6px 0 0;padding-left:16px;list-style:disc;font-size:.8rem;color:var(--muted)}
.ob-qs .ob-pts li{display:list-item;border:0;padding:0;margin:2px 0;background:none}
/* topbar */
.op-topbar{display:flex;justify-content:space-between;align-items:center;padding:10px 22px;
  border-bottom:1px solid var(--line);background:var(--surface);position:sticky;top:0;z-index:20}
.op-back-link{font-size:.82rem;font-weight:600;color:var(--brand-dark);text-decoration:none}
@media (hover:hover){.op-back-link:hover{text-decoration:underline}}
.op-wrap{max-width:860px;margin:0 auto;padding:0 22px 48px}
.op-updated{margin:4px 0 20px}
/* AEO answer strip: the one crawlable lifecycle line, high on the page */
.op-latest{margin:14px 0 20px;padding:12px 15px;border:1px solid var(--line);border-radius:11px;background:var(--brand-light)}
.op-latest-head{margin:0 0 5px;font-size:.7rem;text-transform:uppercase;letter-spacing:.05em;color:var(--muted-2);font-weight:700}
.op-latest-line{margin:0;font-size:.9rem;line-height:1.65;color:var(--ink)}
.op-latest-stance{margin:9px 0 0;font-size:.82rem;line-height:1.6;color:var(--muted-2)}
.learn-live{margin:22px 0 0;padding:16px 18px;border:1px solid var(--line);border-radius:12px;background:var(--surface)}
.learn-live h2{margin:0 0 10px;font-size:.95rem;letter-spacing:-.01em}
.learn-live p{margin:0 0 9px;line-height:1.65}
.learn-live-list{margin:0 0 9px;padding-left:20px}.learn-live-list li{margin:5px 0;line-height:1.6}
.op-latest-line b{font-weight:700}
/* How it actually listed. Sits directly under the latest line on a listed issue and is the one
   block on the page that reports an outcome rather than a state, so it is bordered and quiet
   rather than tinted: a settled fact does not need a highlight to earn attention. */
.lo{margin:0 0 20px;padding:16px 18px;border:1px solid var(--line);border-radius:12px;background:var(--surface)}
.lo h2{margin:0 0 10px;font-size:1rem;letter-spacing:-.01em}
.lo-line{margin:0 0 10px;display:flex;flex-wrap:wrap;align-items:baseline;gap:8px}
.lo-price{font-size:1.5rem;font-weight:800;font-variant-numeric:tabular-nums;letter-spacing:-.02em}
.lo-vs{font-size:.86rem;color:var(--muted)}
.lo-move{font-size:1.05rem;font-weight:700;font-variant-numeric:tabular-nums}
.lo-close{margin:0 0 8px;font-size:.88rem;line-height:1.6;color:var(--ink)}
.lo-gmp{margin:0;font-size:.88rem;line-height:1.6;color:var(--ink)}
.lo-gmp .muted{color:var(--muted)}
.lo-more{margin:8px 0 0;font-size:.84rem}
/* hero */
.op-hero{display:grid;grid-template-columns:1fr auto;gap:20px;align-items:start;
  background:var(--surface);border:1px solid var(--line);border-radius:14px;
  padding:22px;margin:20px 0 0}
@media(max-width:600px){.op-hero{grid-template-columns:1fr}}
.op-hero-name{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:8px}
.op-hero-name h1{font-size:1.4rem;font-weight:800;letter-spacing:-.025em;margin:0}
.op-status{font-size:.7rem;font-weight:700;padding:3px 10px;border-radius:999px;white-space:nowrap}
.op-status-open{background:#dcfce7;color:#15803d}
.op-status-up{background:#dbeafe;color:#1d4ed8}
.op-status-closed{background:var(--line);color:var(--muted)}
.op-stage{font-size:.74rem;padding:4px 11px}
.op-acts{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0 0}
.op-act-ghost{display:inline-flex;align-items:center;gap:6px;padding:9px 14px;border-radius:10px;border:1.5px solid var(--brand);
  color:var(--brand-dark);font:600 .84rem Inter,sans-serif;text-decoration:none;line-height:1.25;background:transparent}
@media (hover:hover){.op-act-ghost:hover{background:var(--brand-light)}}
html.dark .op-act-ghost{color:#6ee7b7}
.op-our{margin:18px 0 -2px;padding:6px 0 6px 12px;border-left:3px solid var(--brand);font-size:.72rem;font-weight:800;
  letter-spacing:.08em;text-transform:uppercase;color:var(--brand-dark);scroll-margin-top:12px}
html.dark .op-our{color:#6ee7b7}
.op-share{display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin:14px 0 0;font-size:.8rem;color:var(--muted)}
.op-share-lbl{font-weight:600}
.op-share-follow{margin-left:10px;padding-left:14px;border-left:1px solid var(--line)}
/* Phone: the word "Follow" goes and the divider stays, so share and the three profiles fit one row. */
@media (max-width:420px){.op-share-follow{font-size:0;margin-left:2px;padding-left:8px;height:24px}}
.op-share a,.op-share button{display:inline-grid;place-items:center;width:36px;height:36px;border-radius:50%;border:0;padding:0;cursor:pointer;color:#fff;text-decoration:none;transition:transform .12s}
@media (hover:hover){.op-share a:hover,.op-share button:hover{transform:translateY(-1px)}}
.op-share .op-share-wa{width:auto;display:inline-flex;gap:7px;padding:0 16px 0 12px;border-radius:999px;background:#25d366;font:700 .86rem Inter,sans-serif}
.op-share-ig{background:radial-gradient(circle at 30% 107%,#fdf497 0%,#fdf497 5%,#fd5949 45%,#d6249f 60%,#285aeb 90%)}
.op-share-th,.op-share-x{background:#111}
html.dark .op-share-th,html.dark .op-share-x{background:#2a2f36}
.op-share .op-share-copy{background:var(--surface-2);color:var(--ink);border:1px solid var(--line)}
.op-share .op-share-copy.is-done{background:var(--brand);color:#fff;border-color:var(--brand)}
.stat-none{font-size:.92rem;color:var(--muted)}
.op-act-btn{display:inline-flex;align-items:center;gap:7px;padding:10px 16px;border-radius:10px;background:var(--brand);color:#fff;font:600 .88rem Inter,sans-serif;text-decoration:none;line-height:1.25}
@media (hover:hover){.op-act-btn:hover{background:var(--brand-dark)}}
.op-hero-tags{display:flex;gap:5px;flex-wrap:wrap;margin-bottom:6px}
.op-dates{font-size:.82rem;color:var(--muted);margin:4px 0 0;font-variant-numeric:tabular-nums}
/* hero stats */
.op-hero-stats{display:flex;flex-direction:column;gap:10px;min-width:130px}
.op-stat{background:var(--surface-2);border:1px solid var(--line);border-radius:10px;padding:10px 14px}
.op-stat-label{display:block;font-size:.65rem;text-transform:uppercase;letter-spacing:.06em;
  color:var(--muted-2);margin-bottom:3px}
.op-stat-val{display:block;font-size:1.15rem;font-weight:800;font-variant-numeric:tabular-nums;
  letter-spacing:-.02em}
.op-stat-note{display:block;font-size:.7rem;color:var(--muted);margin-top:1px}
/* PDF download button */
.op-pdf-btn{white-space:nowrap}
/* section cards */
.op-section{background:var(--surface);border:1px solid var(--line);border-radius:12px;
  padding:18px 20px;margin:14px 0}
.op-section h2{font-size:.9rem;font-weight:700;margin:0 0 12px;display:flex;align-items:center;gap:8px}
.op-section h2 .op-sec-icon{font-size:1rem}
/* two-col grid for charts + text */
.op-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin:14px 0}
@media(max-width:600px){.op-grid{grid-template-columns:1fr}}
/* chart containers */
.op-chart-wrap{background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:16px 18px}
.op-chart-title{font-size:.75rem;font-weight:700;color:var(--muted);text-transform:uppercase;
  letter-spacing:.05em;margin-bottom:10px}
.op-chart-wrap svg{display:block;width:100%;height:auto}
/* footer bar */
.kredfit-attr{display:inline-flex;align-items:center;gap:.34em;margin-top:6px;color:var(--muted);font-size:.8rem;font-weight:600;text-decoration:none}
/* Same footer line as the kredfit attribution, so it matches it rather than competing. */
.social-attr{color:var(--muted);font-size:.8rem;font-weight:600;text-decoration:none}
@media (hover:hover){.kredfit-attr:hover{color:var(--brand-dark)}}
/* The wordmark is inline SVG filled with currentColor, so it takes the brand green here and
   flips with the theme on its own. Height only — the width follows the viewBox, and setting
   both would squash the glyphs. */
/* Phone: the four facts sit 2x2, not one per row. Last in the sheet so it wins. */
@media (max-width:640px){
  .op-hero-stats{display:grid;grid-template-columns:1fr 1fr;gap:8px;min-width:0}
  .op-stat{padding:10px 12px;min-width:0}
  .op-stat-val{font-size:1rem;overflow-wrap:anywhere}
}
