/* bulletin.css — OTHERWORLDS (2026-08-20)
 *
 * Two sources, deliberately kept separate:
 *   STRUCTURE  — news24.com.au: date bar → masthead → tab nav → trending strip →
 *                3-col mosaic (lead spans 2) + 312px sticky rail → full-width 4-up.
 *                Card anatomy is their .storyblock: image, meta, title, standfirst.
 *   SURFACE    — nowhere.news: the 165deg lavender-chrome gradient, .chrome-card,
 *                scanlines, drifting caustic blobs, SF Pro type, the conic glow on
 *                the featured card. Values read off their live stylesheet.
 *
 * Loaded by index.html and article.html. otherworlds.live is a standalone Pages
 * project — nothing here is shared with, or reachable from, the psychic.events repo.
 *
 * ⛔ IMAGE FRAMES ARE 16:9, not news24's 4:3. The source stills are all 16:9; a 75%
 * frame crops faces off. Deliberate deviation.
 */

/* ===== RESET & BASE ===== */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

:root {
  --ink:        rgb(28, 31, 43);
  --ink-2:      rgb(84, 86, 104);
  --ink-3:      rgb(138, 140, 156);
  --rule:       rgba(120, 122, 145, 0.28);
  --kicker:     #8e2f86;
  --section:    #3f4a7a;
  --wrap:       1248px;
  --gap:        24px;
}

html {
  scroll-behavior: smooth;
  -webkit-font-smoothing: antialiased;
  background-color: #ebe8e7;
  min-height: 100%;
  /* ⛔ The clip must be on the ROOT, not only on body. With html:visible the body's
     overflow-x is propagated to the viewport and body itself computes to visible — so
     body stops clipping and documentElement.scrollWidth measured 394 against a 390px
     phone viewport (and scrollTo(600) still moved the page). Measured 390/390 with this. */
  overflow-x: hidden;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'SF Pro Text', 'Segoe UI', system-ui, sans-serif;
  color: var(--ink);
  min-height: 100%;
  overflow-x: hidden;
  position: relative;
}

/* ⛔ The gradient lives on a FIXED pseudo-element, not on background-attachment:fixed —
   that property is broken/janky in iOS Safari and this page's whole traffic is phones. */
body::before {
  content: '';
  position: fixed;
  inset: -10%;
  z-index: -3;
  background: linear-gradient(165deg,
    #ebe8e7 0%, #e1e2ec 15%, #d7dcf1 25%, #c2c5d0 40%,
    #bfc3d4 55%, #c3c8dd 65%, #a4abc3 80%, #99a2ba 100%);
}
body::after {   /* bloom */
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(ellipse at 50% 12%, rgba(255,255,255,0.10) 0%, transparent 50%),
    radial-gradient(ellipse at 50% 50%, transparent 55%, rgba(158,153,191,0.16) 100%);
}

.scanlines {
  position: fixed; inset: 0; z-index: 9999; pointer-events: none;
  background: repeating-linear-gradient(to bottom,
    transparent 0px, transparent 3px, rgba(0,0,0,0.015) 3px, rgba(0,0,0,0.015) 4px);
}

.caustic { position: fixed; border-radius: 50%; pointer-events: none; z-index: -2; mix-blend-mode: screen; will-change: transform; }
.caustic-1 { width: 250px; height: 250px; background: rgba(224,150,255,0.15); filter: blur(40px); top: 8%;  right: 12%; animation: drift1 10s ease-in-out infinite alternate; }
.caustic-2 { width: 220px; height: 220px; background: rgba(69,209,255,0.12);  filter: blur(40px); top: 40%; left: 8%;   animation: drift2 13s ease-in-out infinite alternate; }
.caustic-3 { width: 200px; height: 200px; background: rgba(209,130,250,0.10); filter: blur(38px); bottom: 18%; right: 18%; animation: drift3 15s ease-in-out infinite alternate; }
.caustic-4 { width: 180px; height: 180px; background: rgba(61,209,250,0.09);  filter: blur(35px); bottom: 24%; left: 15%;  animation: drift4 11s ease-in-out infinite alternate; }
@keyframes drift1 { 0% { transform: translate(0,0) scale(1); } 100% { transform: translate(-5%,6%) scale(1.04); } }
@keyframes drift2 { 0% { transform: translate(0,0) scale(1); } 100% { transform: translate(6%,-5%) scale(0.96); } }
@keyframes drift3 { 0% { transform: translate(0,0) scale(1); } 100% { transform: translate(-7%,-4%) scale(1.05); } }
@keyframes drift4 { 0% { transform: translate(0,0) scale(1); } 100% { transform: translate(5%,7%) scale(0.97); } }

@media (prefers-reduced-motion: reduce) {
  .caustic { animation: none; }
  html { scroll-behavior: auto; }
}

a { text-decoration: none; color: inherit; }
img { display: block; max-width: 100%; }

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 24px; }

/* ===== CHROME CARD (nowhere.news .chrome-card) ===== */
.chrome {
  position: relative;
  border-radius: 20px;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.50) 0%, transparent 35%),
    linear-gradient(180deg, rgba(255,255,255,0.14) 0%, rgba(128,128,128,0.06) 100%),
    linear-gradient(165deg, #e8e8ed 0%, #e0e0e6 20%, #d1d2dd 40%, #c6c8e8 60%, #b2b7cb 80%, #8a94bb 100%);
  border: 1px solid rgba(255,255,255,0.35);
  box-shadow:
    inset 0 1px 2px rgba(0,0,0,0.28),
    inset 0 -1px 1.5px rgba(255,255,255,0.16),
    0 6px 10px rgba(128,128,128,0.25),
    0 -1px 2px rgba(255,255,255,0.7);
  outline: 1px solid rgba(0,0,0,0.22);
  outline-offset: -1px;
}

/* ===== 1. DATE BAR ===== */
.datebar {
  font-size: 11px;
  letter-spacing: 0.9px;
  text-transform: uppercase;
  color: var(--ink-2);
  border-bottom: 1px solid var(--rule);
}
.datebar .wrap { display: flex; align-items: center; justify-content: space-between; gap: 16px; height: 40px; }
.datebar_brand { font-weight: 600; color: var(--ink); white-space: nowrap; }
.datebar_now { font-variant-numeric: tabular-nums; white-space: nowrap; }
.datebar_links { display: flex; gap: 18px; white-space: nowrap; }
.datebar_links a:hover { color: var(--ink); }

/* ===== 2. MASTHEAD ===== */
.masthead .wrap {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 16px;
  padding-top: 26px;
  padding-bottom: 24px;
}
.masthead_mark { display: flex; align-items: center; gap: 10px; font-size: 11px; letter-spacing: 1.4px; text-transform: uppercase; color: var(--ink-2); }
.masthead_mark img { width: 34px; height: 34px; border-radius: 9px; filter: drop-shadow(0 1px 2px rgba(150,150,170,0.35)); }
.wordmark {
  justify-self: center;
  font-size: clamp(28px, 5.2vw, 54px);
  font-weight: 800;
  letter-spacing: clamp(2px, 0.9vw, 9px);
  line-height: 1;
  white-space: nowrap;
  background: linear-gradient(135deg, rgba(20,20,20,1) 0%, rgba(46,46,46,1) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 1px 1px rgba(255,255,255,0.7));
}
.masthead_cta { justify-self: end; display: flex; align-items: center; gap: 12px; }

.btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 11px 20px;
  border-radius: 22px;
  font-size: 12px; font-weight: 600; letter-spacing: 0.8px; text-transform: uppercase;
  color: var(--ink);
  background: linear-gradient(165deg, #e8e8ed 0%, #d1d2dd 50%, #b2b7cb 100%);
  box-shadow:
    inset 0 1px 2px rgba(0,0,0,0.22),
    inset 0 -1px 1.5px rgba(255,255,255,0.16),
    0 6px 10px rgba(128,128,128,0.25),
    0 -1px 2px rgba(255,255,255,0.7);
  outline: 1px solid rgba(0,0,0,0.18);
  transition: transform .25s, box-shadow .25s;
  white-space: nowrap;
}
.btn:hover { transform: translateY(-2px); box-shadow: inset 0 1px 2px rgba(0,0,0,0.22), 0 8px 16px rgba(128,128,128,0.30), 0 -1px 2px rgba(255,255,255,0.7); }
.btn--ghost { background: transparent; box-shadow: none; outline: 1px solid rgba(0,0,0,0.16); color: var(--ink-2); }

/* ===== 3. TAB NAV (sticky) ===== */
.tabnav {
  position: sticky; top: 0; z-index: 900;
  border-top: 1px solid rgba(255,255,255,0.45);
  border-bottom: 1px solid var(--rule);
  background: rgba(225,226,236,0.72);
  -webkit-backdrop-filter: blur(20px) saturate(1.4);
  backdrop-filter: blur(20px) saturate(1.4);
}
.tabnav .wrap { display: flex; align-items: center; gap: 4px; height: 52px; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; scroll-snap-type: x proximity; }
.tabnav .wrap::-webkit-scrollbar { display: none; }
.tab {
  flex: 0 0 auto;
  scroll-snap-align: start;
  padding: 9px 15px;
  border-radius: 14px;
  font-size: 12px; font-weight: 600; letter-spacing: 1.3px; text-transform: uppercase;
  color: var(--ink-2);
  border: 1px solid transparent;
  background: none; cursor: pointer;
  font-family: inherit;
  transition: color .2s, background .2s, border-color .2s;
}
.tab:hover { color: var(--ink); }
.tab[aria-selected="true"] {
  color: var(--ink);
  background: linear-gradient(165deg, #eeeef2 0%, #dcdde6 60%, #c6c9da 100%);
  border-color: rgba(255,255,255,0.5);
  box-shadow: inset 0 1px 2px rgba(0,0,0,0.16), 0 2px 5px rgba(128,128,128,0.22);
}
.tab::after {
  content: ''; display: block; height: 2px; margin-top: 6px; border-radius: 2px;
  background: transparent;   /* reserved on EVERY tab — selecting one must not reflow the bar */
}
.tab[aria-selected="true"]::after { background: linear-gradient(90deg, var(--kicker), rgb(102,217,224)); }

/* ===== 4. TRENDING STRIP ===== */
.trending { border-bottom: 1px solid var(--rule); }
.trending .wrap { display: flex; align-items: center; gap: 22px; height: 48px; overflow-x: auto; scrollbar-width: none; }
.trending .wrap::-webkit-scrollbar { display: none; }
.trending_label { flex: 0 0 auto; font-size: 11px; font-weight: 700; letter-spacing: 1.5px; text-transform: uppercase; color: var(--ink); }
#trending-links { display: contents; }
.trending a { flex: 0 0 auto; font-size: 13px; font-weight: 500; color: var(--ink-2); white-space: nowrap; }
.trending a:hover { color: var(--kicker); }

/* ===== 5. PAGE GRID ===== */
.page { padding: 28px 0 8px; }
.page_grid { display: grid; grid-template-columns: minmax(0,1fr) 312px; gap: 32px; align-items: start; }
.rail { position: sticky; top: 72px; display: flex; flex-direction: column; gap: 20px; }

.block { margin-bottom: 34px; }
.block_head {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 12px;
  padding-bottom: 12px; margin-bottom: 20px;
  border-bottom: 2px solid var(--ink);
}
.block_head h2 { font-size: 15px; font-weight: 800; letter-spacing: 2px; text-transform: uppercase; }
.block_head span { font-size: 11px; letter-spacing: 1px; text-transform: uppercase; color: var(--ink-2); }

.mosaic { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: var(--gap); }
.grid4  { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: var(--gap); }

/* ===== 6. STORYBLOCK (news24 anatomy) ===== */
.storyblock { position: relative; overflow: hidden; display: flex; flex-direction: column; transition: transform .25s, box-shadow .25s; min-width: 0; }
.storyblock:hover { transform: translateY(-3px); box-shadow: inset 0 1px 2px rgba(0,0,0,0.28), 0 12px 22px rgba(110,110,135,0.32), 0 -1px 2px rgba(255,255,255,0.7); }

.storyblock_image_link { display: block; }
.responsive-img { position: relative; width: 100%; padding-bottom: 56.25%; overflow: hidden; background: rgba(120,124,150,0.35); }
.responsive-img img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

.storyblock_body {
  padding: 15px 17px 18px;
  display: flex; flex-direction: column; gap: 8px; flex: 1 1 auto;
  /* ⛔ Legibility scrim. The .chrome gradient runs to #8a94bb at its far end, which is
     where a card's text sits — measured contrast for 13px secondary text there was 1.98:1.
     This lifts the plate to ~(206,209,222) and takes it back over 4.5:1. */
  background: linear-gradient(180deg, rgba(255,255,255,0.44) 0%, rgba(255,255,255,0.72) 100%);
}
.storyblock_meta { display: flex; align-items: center; gap: 9px; font-size: 10px; font-weight: 700; letter-spacing: 1.3px; text-transform: uppercase; }
.storyblock_label { color: var(--kicker); }
.storyblock_meta .dot { color: var(--ink-3); }
.storyblock_section { color: var(--section); }

/* ⛔ Solid ink + white text-shadow, NOT the gradient-clipped fill. On a chrome card the
   clipped fill drops legibility below 4.5:1 and vanishes entirely without background-clip. */
.storyblock_title { font-size: 17px; font-weight: 700; line-height: 1.28; color: var(--ink); text-shadow: 0 1px 1px rgba(255,255,255,0.7); }
.storyblock_standfirst { font-size: 13px; line-height: 1.55; color: var(--ink-2); }
.storyblock_time { margin-top: auto; padding-top: 4px; font-size: 10px; font-weight: 600; letter-spacing: 1.2px; text-transform: uppercase; color: var(--ink-2); }

/* — LEAD: spans 2 columns, bigger type, animated conic glow (nowhere .mock-card-featured) */
.storyblock--lead { grid-column: span 2; border-radius: 26px; }
.storyblock--lead .storyblock_body { padding: 20px 24px 24px; gap: 10px; }
.storyblock--lead .storyblock_title { font-size: 30px; line-height: 1.16; letter-spacing: -0.4px; }
.storyblock--lead .storyblock_standfirst { font-size: 15px; }
.glowwrap { position: relative; isolation: isolate; grid-column: span 2; display: flex; }
.glowwrap > .storyblock { flex: 1 1 auto; grid-column: auto; position: relative; z-index: 1; }
.glowwrap::before {
  content: ''; position: absolute; inset: -4px; border-radius: 30px; z-index: -1;
  background: conic-gradient(from 0deg, rgb(217,115,191), rgb(102,217,224), rgb(230,102,179), rgb(89,224,217), rgb(217,115,191));
  filter: blur(9px); opacity: .55; animation: glowRotate 4.5s linear infinite;
}
@keyframes glowRotate { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .glowwrap::before { animation: none; } }

/* — HERO: spans all 3, image left / text right */
.storyblock--hero { grid-column: span 3; flex-direction: row; border-radius: 26px; }
.storyblock--hero .storyblock_image_link { flex: 0 0 52%; }
.storyblock--hero .responsive-img { height: 100%; padding-bottom: 0; min-height: 260px; }
.storyblock--hero .storyblock_body { padding: 26px 28px; justify-content: center; gap: 12px; }
.storyblock--hero .storyblock_title { font-size: 27px; line-height: 1.18; }
.storyblock--hero .storyblock_standfirst { font-size: 14px; }

/* ===== 7. RAIL ===== */
.railcard { padding: 20px 20px 22px; background-image: linear-gradient(180deg, rgba(255,255,255,0.44) 0%, rgba(255,255,255,0.72) 100%), linear-gradient(180deg, rgba(255,255,255,0.50) 0%, transparent 35%), linear-gradient(180deg, rgba(255,255,255,0.14) 0%, rgba(128,128,128,0.06) 100%), linear-gradient(165deg, #e8e8ed 0%, #e0e0e6 20%, #d1d2dd 40%, #c6c8e8 60%, #b2b7cb 80%, #8a94bb 100%); }
.railcard h3 { font-size: 12px; font-weight: 800; letter-spacing: 1.8px; text-transform: uppercase; color: var(--ink); padding-bottom: 12px; margin-bottom: 4px; border-bottom: 2px solid var(--ink); }
.raillist { list-style: none; }
.raillist li { display: flex; gap: 12px; padding: 13px 0; border-bottom: 1px solid var(--rule); }
.raillist li:last-child { border-bottom: 0; padding-bottom: 0; }
.raillist .n { font-size: 22px; font-weight: 800; line-height: 1; color: rgba(97,99,117,0.42); min-width: 24px; }
.raillist a { font-size: 14px; font-weight: 600; line-height: 1.34; color: var(--ink); }
.raillist a:hover { color: var(--kicker); }

.promo { padding: 22px 20px 24px; text-align: center; }
.promo_kicker { font-size: 10px; font-weight: 700; letter-spacing: 1.6px; text-transform: uppercase; color: var(--kicker); }
.promo h3 { font-size: 20px; font-weight: 800; line-height: 1.2; margin: 8px 0 8px; }
.promo p { font-size: 13px; line-height: 1.55; color: var(--ink-2); margin-bottom: 16px; }

/* ===== 8. FOOTER ===== */
.foot { margin-top: 40px; border-top: 1px solid var(--rule); }
.foot .wrap { padding-top: 26px; padding-bottom: 40px; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px; }
.foot_note { font-size: 12px; line-height: 1.6; color: var(--ink-2); max-width: 560px; }
.foot_note strong { color: var(--ink); }
.foot_links { display: flex; flex-wrap: wrap; gap: 18px; font-size: 12px; letter-spacing: 0.6px; text-transform: uppercase; color: var(--ink-2); }
.foot_links a:hover { color: var(--ink); }

/* ===== 9. STATES ===== */
.state { padding: 60px 0; text-align: center; font-size: 15px; color: var(--ink-2); }
.state[hidden] { display: none !important; }

/* ===== 10. ARTICLE PAGE ===== */
.article { padding: 34px 0 0; }
.article_wrap { max-width: 760px; margin: 0 auto; }
.crumb { font-size: 11px; font-weight: 600; letter-spacing: 1.3px; text-transform: uppercase; color: var(--ink-2); margin-bottom: 18px; display: inline-block; }
.crumb:hover { color: var(--kicker); }
.article_meta { display: flex; align-items: center; gap: 10px; font-size: 11px; font-weight: 700; letter-spacing: 1.4px; text-transform: uppercase; margin-bottom: 14px; }
.article h1 {
  font-size: clamp(30px, 4.6vw, 46px); font-weight: 800; line-height: 1.12; letter-spacing: -0.6px;
  background: linear-gradient(135deg, rgba(20,20,20,1) 0%, rgba(46,46,46,1) 100%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 1px 1px rgba(255,255,255,0.7));
}
.article_standfirst { font-size: 18px; line-height: 1.55; color: var(--ink-2); margin-top: 16px; }
.byline { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 20px; padding: 14px 0; border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); font-size: 12px; letter-spacing: 0.6px; color: var(--ink-2); }
.byline strong { color: var(--ink); font-weight: 700; }
.article_hero { margin: 26px 0 8px; border-radius: 24px; overflow: hidden; }
.article_hero .responsive-img { padding-bottom: 56.25%; }
.article_caption { font-size: 12px; color: var(--ink-2); margin: 10px 2px 0; }
.article_body { margin-top: 26px; }
.article_body p { font-size: 17px; line-height: 1.72; color: var(--ink); margin-bottom: 20px; }
.article_body p:first-of-type { font-size: 18px; }
.more { padding-top: 12px; }

/* ===== 11. IN-APP GUARD (?appv=…) — same contract as index.html ===== */
.in-app .masthead_cta,
.in-app .datebar_links,
.in-app .promo,
.in-app .foot_links { display: none !important; }

/* ===== 12. RESPONSIVE ===== */
@media (max-width: 1080px) {
  .page_grid { grid-template-columns: minmax(0,1fr); }
  .rail { position: static; flex-direction: row; flex-wrap: wrap; }
  .rail > * { flex: 1 1 300px; }
}
@media (max-width: 900px) {
  .mosaic { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .grid4  { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .storyblock--hero { grid-column: span 2; flex-direction: column; }
  .storyblock--hero .responsive-img { padding-bottom: 56.25%; min-height: 0; height: auto; }
  .storyblock--hero .storyblock_body { padding: 18px 20px 22px; }
  .storyblock--hero .storyblock_title { font-size: 22px; }
  .storyblock--lead .storyblock_title { font-size: 25px; }
  .masthead .wrap { grid-template-columns: 1fr; justify-items: center; text-align: center; gap: 14px; }
  .masthead_cta { justify-self: center; }
}
@media (max-width: 640px) {
  :root { --gap: 18px; }
  .wrap { padding: 0 16px; }
  .mosaic, .grid4 { grid-template-columns: minmax(0,1fr); }
  .storyblock--lead, .storyblock--hero, .glowwrap { grid-column: span 1; }
  .storyblock--lead .storyblock_title { font-size: 22px; }
  .storyblock--lead .storyblock_body { padding: 16px 18px 20px; }
  /* ⛔ The date bar's link row is wider than a phone and body has overflow-x:hidden, so
     on 375px it was CLIPPING "Get æntenna" off the screen entirely. The same three links
     are in the footer, and the masthead already carries the session CTA, so the bar keeps
     the brand only. */
  .datebar_now { display: none; }
  .datebar_links { display: none; }
  .datebar .wrap { justify-content: center; }
  .block_head span { flex: 1 0 100%; }
  .trending_label { font-size: 10px; }
  .rail > * { flex: 1 1 100%; }
  .foot .wrap { flex-direction: column; align-items: flex-start; }
  .article_body p { font-size: 16px; }
}
