/* ──────────────────────────────────────────────────────────────────────────
 * 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-inline-start: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:start; }
.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); }
/* The academy link is the secondary ask, so it must read as one: outlined at rest (transparent
   fill, gold border, deep-brown text) while the hover gold-fill stays the primary's own
   .tqp-cta::before slide and .tqp-cta:hover — nothing here duplicates them. */
.tqp-cta-alt{ background:transparent; border-color:var(--tq-gold); color:var(--tq-deep); }
.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; }
 /* Two CTAs now: each takes the whole row so the academy link stacks under Tian Qi instead of
    squeezing both translated labels into half a sheet at 390px (nothing gets clipped — the
    sheet keeps its 88dvh cap and scrolls). */
 .tqp-cta{ flex:1 1 100%; 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; }
}

/* ──────────────────────────────────────────────────────────────────────────
 * Chinese New Year 2027 campaign skin (CAMPAIGN = 'cny2027' in tq-popup.js).
 *
 * ⚠️ EVERY RULE IS SCOPED UNDER `.tqp-cny`, which the controller adds to the
 * overlay only after it has rewritten the sheet. The Tian Qi popup is PAUSED,
 * not removed: flipping the switch back must render exactly what shipped on
 * 2026-09-18, so nothing here may hang off `.tqp-sheet` alone.
 *
 * The art panel REPLACES the SCMP tearsheet. It is CSS, not an image: sharp at
 * any density, no new asset to upload, and the 130 KB tearsheet is removed from
 * the DOM rather than downloaded and hidden behind a modal.
 * ────────────────────────────────────────────────────────────────────────── */
.tqp-cny .tqp-sheet{
 background:linear-gradient(160deg,#FEFBF3 0%,#F8EEDA 58%,#F2E3C6 100%);
}
.tqp-cny .tqp-eyebrow{ color:#8C2F26; letter-spacing:.2em; }
.tqp-cny .tqp-title{ font-size:1.9rem; text-wrap:balance; }
.tqp-cny .tqp-seal{ width:56px; height:56px; margin-bottom:8px; }
.tqp-cny .tqp-seal::after{ inset:-6px; border-color:rgba(140,47,38,.35); }

/* The price, directly above the buttons: a reader who clicks is qualified, and the
   landing page's own promise is not "free". */
.tqp-price{ display:block; text-align:center; margin:0 0 18px; }
.tqp-price b{ display:block; font-family:'Playfair Display',Georgia,serif; font-weight:500; font-size:1.85rem;
 line-height:1; color:var(--tq-deep); letter-spacing:-.01em; margin-bottom:7px; }
.tqp-price-note{ display:block; font-family:'Jost',sans-serif; font-size:.6rem; letter-spacing:.13em;
 text-transform:uppercase; color:#8C2F26; line-height:1.5; }

.tqp-cny .tqp-press{ align-self:center; }
.tqp-cny .tqp-press.tqp-press-cny{ margin:0; }
.tqp-cny-art{
 position:relative; overflow:hidden;
 display:flex; flex-direction:column; align-items:center; justify-content:center; gap:14px;
 width:100%; aspect-ratio:3/4; padding:26px 18px;
 border-radius:8px; color:#F7E8C9; text-align:center;
 background:radial-gradient(120% 82% at 50% 0%,#96302A 0%,#7A1D18 46%,#57100C 100%);
 box-shadow:0 10px 26px rgba(28,22,16,.24), inset 0 0 0 1px rgba(228,197,128,.34);
}
.tqp-cny-art::after{ content:""; position:absolute; inset:9px; border:1px solid rgba(228,197,128,.42);
 border-radius:5px; pointer-events:none; }
.tqp-cny-ring{ position:absolute; top:50%; left:50%; width:236px; height:236px;
 margin:-118px 0 0 -118px; border:1px dashed rgba(228,197,128,.34); border-radius:50%;
 animation:tqp-spin 60s linear infinite; pointer-events:none; }
.tqp-cny-stamp{ position:relative; display:flex; align-items:center; justify-content:center;
 width:98px; height:98px; border-radius:3px; background:#F7E9C9; color:#7A1D18;
 font-family:'Noto Serif SC','Playfair Display',Georgia,serif; font-weight:600; font-size:2.15rem;
 letter-spacing:.04em; line-height:1; transform:rotate(-2deg);
 box-shadow:0 7px 20px rgba(0,0,0,.3), inset 0 0 0 2px rgba(122,29,24,.22);
}
.tqp-cny-words{ position:relative; display:flex; flex-direction:column; align-items:center; gap:7px; }
.tqp-cny-year{ font-family:'Playfair Display',Georgia,serif; font-size:3.3rem; line-height:1; letter-spacing:.02em; }
.tqp-cny-goat{ font-family:'Jost',sans-serif; font-size:.58rem; letter-spacing:.28em; text-transform:uppercase;
 color:#E4C580; }
.tqp-cny-date{ font-family:'Jost',sans-serif; font-size:.54rem; letter-spacing:.2em; text-transform:uppercase;
 color:rgba(247,232,201,.68); }

/* The campaign makes ONE ask (Sean, 2026-11-08): the academy anchor is not in the sheet at all,
   so "Maybe later" gets a row of its own instead of sitting beside a second button. */
@media (min-width:641px){
 .tqp-cny .tqp-ghost{ flex:0 0 100%; }
}

/* ── ≤860px: the panel becomes the sheet's masthead strip ── */
@media (max-width:860px){
 .tqp-cny .tqp-press{ margin:0 0 12px; }
 .tqp-cny-art{ width:auto; aspect-ratio:auto; height:110px; flex-direction:row; justify-content:flex-start;
  gap:16px; padding:12px 18px; text-align:start; }
 .tqp-cny-art::after{ inset:6px; }
 .tqp-cny-ring{ display:none; }
 .tqp-cny-stamp{ flex:0 0 auto; width:64px; height:64px; font-size:1.42rem; }
 .tqp-cny-words{ align-items:flex-start; gap:5px; }
 .tqp-cny-year{ font-size:2rem; }
 .tqp-cny-goat{ font-size:.52rem; letter-spacing:.22em; }
 .tqp-cny-date{ font-size:.5rem; letter-spacing:.16em; }
}

/* ── ≤640px: the bottom sheet. The strip already names the year, so the Tian Qi
      seal goes: every pixel here is height the CTA needs on a 320x568 phone. ── */
@media (max-width:640px){
 .tqp-cny .tqp-seal{ display:none; }
 .tqp-cny .tqp-title{ font-size:1.5rem; }
 .tqp-cny-art{ height:106px; }
 .tqp-cny-stamp{ width:56px; height:56px; font-size:1.24rem; }
 .tqp-cny-year{ font-size:1.72rem; }
 .tqp-cny-goat, .tqp-cny-date{ font-size:.48rem; letter-spacing:.14em; }
 .tqp-price{ margin:0 0 14px; }
 .tqp-price b{ font-size:1.5rem; }
 .tqp-price-note{ font-size:.55rem; letter-spacing:.1em; }
}

/* ── ≤380px: the smallest phones. The strip's date line is the one element that can go —
      the price note carries the same date — and it buys the CTA the ~15px it needs to stay
      on screen at 320x568 (measured: CTA ended 8px below the fold with it). ── */
@media (max-width:380px){
 .tqp-cny-art{ height:92px; }
 .tqp-cny-date{ display:none; }
 .tqp-cny-year{ font-size:1.62rem; }
 .tqp-cny .tqp-sub-m{ margin-bottom:14px; }
 .tqp-price{ margin-bottom:10px; }
}
