/* ──────────────────────────────────────────────────────────────────────────
 * Tian Qi popup — every rule the modal needs, in a file EVERY page can link.
 *
 * 🚨 WHY THIS FILE EXISTS. These rules used to live at the tail of shared.css,
 * which only the 2,558 Astro-rendered pages link. The 5,240 frozen pages that
 * carry the popup markup link four hashed chunks instead, none of which held a
 * single `tqp-` rule — so on those pages `.tqp-overlay` had NO `display:none`
 * and rendered as a 1280x626 unstyled block of promo copy below the footer, in
 * all 40 locales, from #54 (2026-09-16) until this change. Verified live in a
 * browser, not inferred: computed `display:block; position:static`.
 *
 * ⚠️ The guard that was meant to prevent exactly that tested
 * `html.includes('shared.css')` — and passed 4,978 times on the string as it
 * appears inside a CSS COMMENT in an inline <style> block. A substring test
 * cannot tell a stylesheet link from a comment. bin/add-tianqi-popup.mjs now
 * parses <link> elements instead.
 *
 * Keep this file small. It ships on ~11,000 pages.
 * ────────────────────────────────────────────────────────────────────────── */
/* block fcd55ccc6a */
 .tqp-overlay{
 --tq-deep:#3B2F26; --tq-brown-med:#5C4A3A; --tq-brown-light:#7D6B59;
 --tq-gold:#D6AD60; --tq-gold-light:#E4C580; --tq-gold-faint:rgba(214,173,96,0.14);
 --tq-copper:#B26E3C; --tq-cream:#EFE4C8; --tq-cream-white:#FAF6ED;
 --tq-warm-white:#FDFAF3; --tq-taupe:#A8957A;
 font-family:'Public Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
 color:var(--tq-deep);
 position:fixed; inset:0; z-index:999999;
 display:none; align-items:center; justify-content:center; padding:26px;
 background:rgba(28,22,16,.52);
 -webkit-backdrop-filter:blur(4px); backdrop-filter:blur(4px);
 opacity:0; transition:opacity .34s ease;
}
.tqp-overlay.is-open{ display:flex; opacity:1; }
.tqp-overlay *{ box-sizing:border-box; }
.tqp-sheet{
 position:relative; width:100%; max-width:430px;
 max-height:calc(100dvh - 52px); overflow-y:auto;
 background:linear-gradient(158deg,#FDFAF3 0%,#F4EAD3 100%);
 border:1px solid rgba(255,255,255,.7);
 border-radius:16px; padding:24px 40px 30px; text-align:center;
 color:var(--tq-deep); overflow-x:hidden;
 box-shadow:0 34px 80px rgba(28,22,16,.5), inset 0 1px 0 rgba(255,255,255,.7);
 opacity:0; transform:translateY(16px) scale(.97);
}
.tqp-overlay.is-open .tqp-sheet{ animation:tqp-rise .6s cubic-bezier(.16,.84,.32,1) .05s forwards; }
.tqp-sheet::before{
 content:""; position:absolute; top:0; left:0; right:0; height:3px;
 background:linear-gradient(90deg,var(--tq-gold),var(--tq-gold-light) 30%,#fff6e2 50%,var(--tq-gold-light) 70%,var(--tq-gold));
 background-size:220% 100%; animation:tqp-shimmer 4s ease-in-out .35s 2;
}
.tqp-glow{ position:absolute; top:-70px; right:-70px; width:230px; height:230px; border-radius:50%;
 background:radial-gradient(circle,rgba(214,173,96,.34),transparent 65%); pointer-events:none; }
.tqp-sheet > *{ position:relative; z-index:1; }
.tqp-grabber{ display:none; }
.tqp-close{ position:absolute; top:14px; right:14px; width:30px; height:30px; border:0; background:transparent;
 color:var(--tq-brown-light); font-size:21px; line-height:1; cursor:pointer; border-radius:50%; z-index:5;
 transition:background .2s,color .2s,transform .3s; }
.tqp-close:hover{ background:rgba(59,47,38,.07); color:var(--tq-deep); transform:rotate(90deg); }
.tqp-seal{ position:relative; width:88px; height:88px; margin:0 auto 14px; }
.tqp-logo{ display:block; width:100%; height:100%; object-fit:contain; filter:drop-shadow(0 8px 18px rgba(59,47,38,.26)); }
.tqp-seal::after{ content:""; position:absolute; inset:-9px; border:1px dashed rgba(214,173,96,.5); border-radius:50%;
 animation:tqp-spin 26s linear infinite; }
.tqp-eyebrow{ display:inline-block; font-family:'Jost',-apple-system,sans-serif; font-size:.64rem; letter-spacing:.22em;
 text-transform:uppercase; color:var(--tq-copper); margin-bottom:13px; text-wrap:balance; }
.tqp-title{ font-family:'Playfair Display',Georgia,serif; font-weight:400; font-size:2rem; line-height:1.14; margin:0 0 12px;
 letter-spacing:-.01em; color:var(--tq-deep); }
.tqp-cn{ font-family:'Noto Serif SC','Playfair Display',serif; font-weight:500; color:var(--tq-copper); margin-left:6px; }
.tqp-sub{ color:var(--tq-brown-med); line-height:1.6; font-size:.95rem; margin:0 auto 22px; max-width:38ch; }
.tqp-sub-m{ display:none; color:var(--tq-brown-med); line-height:1.6; font-size:.92rem; margin:0 auto 20px; max-width:34ch; }
.tqp-features{ list-style:none; margin:0 auto 26px; padding:0; display:inline-grid; gap:11px; text-align:left; }
.tqp-features li{ display:flex; gap:12px; align-items:baseline; font-size:.92rem; color:var(--tq-brown-med); line-height:1.5;
 opacity:0; transform:translateY(6px); animation:tqp-fu .5s cubic-bezier(.2,.7,.2,1) forwards; }
.tqp-features li:nth-child(1){ animation-delay:.26s; }
.tqp-features li:nth-child(2){ animation-delay:.34s; }
.tqp-features li:nth-child(3){ animation-delay:.42s; }
.tqp-features li::before{ content:""; flex:0 0 7px; height:7px; width:7px; border-radius:50%; background:var(--tq-gold);
 box-shadow:0 0 0 3px var(--tq-gold-faint); transform:translateY(-1px); }
.tqp-actions{ display:flex; align-items:center; justify-content:center; gap:10px; flex-wrap:wrap; }
.tqp-cta{ position:relative; display:inline-block; background:var(--tq-deep); color:var(--tq-cream-white); text-decoration:none;
 font-family:'Jost',sans-serif; font-size:.78rem; font-weight:600; letter-spacing:.16em; text-transform:uppercase;
 padding:14px 30px; border:1px solid var(--tq-deep); border-radius:3px; overflow:hidden; isolation:isolate; cursor:pointer;
 transition:color .35s,border-color .35s,transform .25s,box-shadow .35s; }
.tqp-cta::before{ content:""; position:absolute; inset:0; background:var(--tq-gold); transform:translateX(-101%);
 transition:transform .42s cubic-bezier(.2,.7,.2,1); z-index:-1; }
.tqp-cta:hover{ color:var(--tq-deep); border-color:var(--tq-gold); transform:translateY(-1px); box-shadow:0 10px 24px rgba(214,173,96,.34); }
.tqp-cta:hover::before{ transform:translateX(0); }
.tqp-cta:active{ transform:translateY(0); }
.tqp-ghost{ background:transparent; color:var(--tq-brown-light); border:0; padding:14px 8px; cursor:pointer;
 font-family:'Jost',sans-serif; font-size:.72rem; letter-spacing:.16em; text-transform:uppercase; transition:color .2s; }
.tqp-ghost:hover{ color:var(--tq-deep); }
.tqp-foot{ display:block; margin-top:18px; font-family:'Jost',sans-serif; font-size:.62rem; letter-spacing:.16em;
 text-transform:uppercase; color:var(--tq-taupe); }
/* ── Mobile: becomes a bottom sheet ── */
@media (max-width:640px){
 .tqp-overlay{ align-items:flex-end; padding:0; background:rgba(28,22,16,.5); }
 .tqp-sheet{ max-width:none; border-radius:22px 22px 0 0; padding:14px 26px 30px; border-bottom:0;
 box-shadow:0 -22px 60px rgba(28,22,16,.5); max-height:88dvh;
 transform:translateY(100%); }
 .tqp-overlay.is-open .tqp-sheet{ animation:tqp-slide .5s cubic-bezier(.16,.84,.32,1) forwards; }
 .tqp-grabber{ display:block; width:42px; height:5px; border-radius:99px; background:rgba(90,74,58,.28); margin:0 auto 16px; }
 .tqp-close{ top:16px; right:16px; }
 .tqp-seal{ width:70px; height:70px; margin-top:0; }
 .tqp-title{ font-size:1.7rem; }
 .tqp-sub{ display:none; }        /* keep the sheet compact — no full-page takeover */
 .tqp-features{ display:none; }
 .tqp-sub-m{ display:block; }
 .tqp-foot{ margin-top:16px; }
 .tqp-cta{ flex:1 1 auto; text-align:center; }
}
/* ── Keyframes ── */
@keyframes tqp-rise{ to{ opacity:1; transform:translateY(0) scale(1); } }
/* 🚨 `opacity:1` IS THE FIX FOR A LIVE MOBILE DEFECT, not a flourish. `.tqp-sheet` starts at
   opacity:0 and the desktop animation (tqp-rise) ends at 1 — but the mobile override swaps in
   tqp-slide, which animated ONLY transform, so below 640px the sheet finished its animation
   still fully transparent. Verified on production 2026-09-18 on a page where the popup works:
   at 390px wide the sheet computed `opacity: 0`, at 1280px it computed `1`.
   What the reader got instead of a dialog: the page dimmed, blurred (the overlay carries
   backdrop-filter) and scroll-locked by `body{overflow:hidden}`, with nothing on it — and the
   invisible sheet still covering the lower half, so a tap there hit the sheet and did nothing.
   ⚠️ Anyone with prefers-reduced-motion was FINE, because that block sets opacity:1 directly,
   which is why this never showed up in testing on a machine with motion reduced. */
@keyframes tqp-slide{ to{ transform:translateY(0); opacity:1; } }
@keyframes tqp-fu{ to{ opacity:1; transform:translateY(0); } }
@keyframes tqp-spin{ to{ transform:rotate(360deg); } }
@keyframes tqp-shimmer{ 0%{ background-position:-120% 0; } 100%{ background-position:220% 0; } }
@media (prefers-reduced-motion:reduce){
 .tqp-overlay, .tqp-overlay.is-open .tqp-sheet, .tqp-features li, .tqp-sheet::before, .tqp-seal::after{
 animation:none !important; transition:opacity .2s ease !important;
 }
 .tqp-overlay.is-open .tqp-sheet{ opacity:1; transform:none; }
 .tqp-features li{ opacity:1; transform:none; }
}

/* ──────────────────────────────────────────────────────────────────────────
 * The SCMP tearsheet, beside the pitch.
 *
 * The image is the one already published on /media-features/ and its alt text
 * is the one that page ships in all 8 of its locales — English everywhere,
 * because a masthead and a headline are proper nouns. So this adds ZERO new
 * translatable strings to the 40 locales the popup speaks.
 *
 * ⚠️ .tqp-body EXISTS TO PROTECT THE EXISTING LAYOUT. Making .tqp-sheet itself
 * the grid would blockify its inline children — .tqp-eyebrow (inline-block)
 * and .tqp-features (inline-grid, centred by margin:auto) would both stretch
 * to the full column and stop being centred. Wrapping the copy keeps every
 * rule below acting on a plain block box exactly as it did before.
 * ────────────────────────────────────────────────────────────────────────── */
/* ⚠️ .tqp-glow HAS NEVER RENDERED, and this keeps it that way rather than quietly switching on
   a decoration nobody asked for. Its own rule says `position:absolute; top:-70px; right:-70px`
   — a gold glow bleeding off the sheet's corner — but `.tqp-sheet > *{ position:relative }` on
   the VERY NEXT LINE has equal specificity and wins on source order, so it has always been a
   relatively-positioned inline <span>, and width/height do not apply to those. Zero size, zero
   pixels, on every page since it shipped.
   It stops being harmless the moment the sheet becomes a grid: grid items are blockified, so
   the span became a real 230x230 block and took a second grid row — 230px of empty sheet that
   pushed "Reveal My Chart" out of the viewport. Turning it on is a design change and therefore
   Sean's; hiding it preserves exactly what readers see today. */
.tqp-glow{ display:none; }

.tqp-press{ margin:0 0 16px; padding:0; }
.tqp-press img{
 display:block; width:100%; height:106px;
 object-fit:cover; object-position:top center;
 border:1px solid rgba(59,47,38,.16); border-radius:10px;
 background:#fff;
 box-shadow:0 6px 16px rgba(28,22,16,.14);
}

/* ── Desktop: the tearsheet stands beside the pitch, full page, uncropped ── */
@media (min-width:861px){
 .tqp-sheet{
  max-width:880px;
  display:grid; grid-template-columns:300px minmax(0,1fr);
  column-gap:38px; align-items:center;
  padding:30px 40px 34px;
 }
 /* 🪤 BOTH CELLS ARE NAMED EXPLICITLY. `grid-row: 1 / -1` looks like "span every row", but
    negative line numbers count back from the EXPLICIT grid, and this grid declares no rows —
    so it resolved to `1 / 1` and the copy was auto-placed into a second row UNDERNEATH the
    tearsheet: a 880px sheet with 540px of empty space and the CTA pushed out of the viewport.
    It measured as a working two-column grid; only a screenshot showed it stacked. */
 .tqp-press{ grid-area:1 / 1; margin:0; align-self:center; }
 .tqp-body{ grid-area:1 / 2; min-width:0; }
 .tqp-press img{
  height:auto; aspect-ratio:900 / 1527;
  object-fit:contain; border-radius:6px;
  box-shadow:0 10px 26px rgba(28,22,16,.22);
 }
 /* The glow sits top-right of the sheet; with the sheet twice as wide it was
    landing over the tearsheet rather than behind the copy. */
 .tqp-glow{ right:-70px; }
}

/* ── Below 861px the sheet is a bottom sheet, so the tearsheet becomes a
      masthead strip: the SCMP nameplate and the headline, nothing cropped
      out that carries the signal. A full 1:1.7 portrait here would push the
      CTA off the screen. ── */
@media (max-width:860px){
 .tqp-press{ margin:2px 0 14px; }
}
