/* ═══════════════════════════════════════════════════════════════
   TheHonestCopy — 1950s Broadsheet Newspaper Aesthetic
   ═══════════════════════════════════════════════════════════════ */

:root {
  --paper:       #f5f0e8;
  --paper-dark:  #ebe5d8;
  --ink:         #1a1a1a;
  --ink-light:   #3a3a3a;
  --ink-muted:   #6b6560;
  --accent:      #8b1a1a;
  --rule:        #1a1a1a;
  --rule-light:  #b5a99a;

  --font-display: 'Playfair Display', Georgia, 'Times New Roman', serif;
  --font-body:    Georgia, 'Times New Roman', serif;
  --font-sans:    'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;

  --col-gap: 1.5rem;
  --page-pad: 2.5rem;

  /* Spine = left edge of the centered broadsheet (1100px max) */
  --spine-x: max(0px, 50% - 550px);

  /* Paper-weight easing: slow peel, momentum through middle, soft settle */
  --page-ease: cubic-bezier(0.52, 0.01, 0.12, 1);
  /* Heavier easing for full newspaper flip (thicker object) */
  --news-ease: cubic-bezier(0.38, 0.02, 0.18, 1);
}

/* ── Reset & base ─────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
  font-size: 17px;
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: var(--font-body);
  color: var(--ink);
  background: #ddd7ca;  /* desk surface — slightly darker than newsprint */
  line-height: 1.6;
  min-height: 100dvh;
  overflow-x: hidden; /* prevent scrollbar during 3D page swing */
}

/* Subtle newsprint grain */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9999;
  opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg width='200' height='200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ── Broadsheet container ─────────────────────────────────────── */
.broadsheet {
  max-width: 1100px;
  margin: 0 auto;
  padding: var(--page-pad);
  position: relative;
  /* Layered paper background — tonal variation like real newsprint:
     slight yellowing at edges, warm/cool shifts across the sheet */
  background:
    /* warm spot (aged paper variation, top-left) */
    radial-gradient(ellipse at 15% 20%, rgba(210,195,165,0.08) 0%, transparent 50%),
    /* cool spot (slight blue-ish tint, bottom-right) */
    radial-gradient(ellipse at 85% 75%, rgba(190,185,175,0.06) 0%, transparent 45%),
    /* edge yellowing */
    radial-gradient(ellipse at 50% 50%, var(--paper) 35%, #ede6d5 100%);
  box-shadow:
    /* Spine gutter — deep shadow at the left binding edge */
    inset 6px 0 14px -4px rgba(0,0,0,0.08),
    inset 2px 0 4px rgba(0,0,0,0.04),
    /* Right-edge page lift */
    inset -2px 0 6px -2px rgba(0,0,0,0.03);
  /* No transition — box-shadow transition causes a visible sweep
     when data-state swaps and the broadsheet shadow changes. */
}

/* Fold creases — base styles. All broadsheets get the pseudo-element
   for potential creases; only front page gets the center fold. */
.broadsheet::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 5;
  background: none;
}

/* Front page: spine crease at the left edge + subtle horizontal fold.
   No center vertical line — the newspaper is lying flat, not halved. */
.page--front > .broadsheet::before {
  background:
    /* Spine crease — where the pages meet at the binding */
    linear-gradient(to right,
      rgba(0,0,0,0.12) 0%,
      rgba(0,0,0,0.07) 2px,
      rgba(0,0,0,0.035) 6px,
      rgba(0,0,0,0.015) 14px,
      transparent 28px
    ),
    /* Subtle horizontal fold crease (upper-third, newspaper was folded for delivery) */
    linear-gradient(to bottom,
      transparent calc(38% - 8px),
      rgba(0,0,0,0.008) calc(38% - 3px),
      rgba(0,0,0,0.025) 38%,
      rgba(0,0,0,0.008) calc(38% + 3px),
      transparent calc(38% + 8px)
    );
}

/* Edge curl + corner darkening — paper doesn't lay perfectly flat */
.broadsheet::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 4;
  border-radius: 1px;
  background:
    /* top-right corner lift */
    radial-gradient(ellipse at 100% 0%, rgba(0,0,0,0.05) 0%, transparent 40%),
    /* bottom-right corner lift */
    radial-gradient(ellipse at 100% 100%, rgba(0,0,0,0.04) 0%, transparent 35%),
    /* bottom-left corner lift */
    radial-gradient(ellipse at 0% 100%, rgba(0,0,0,0.03) 0%, transparent 30%),
    /* subtle edge darkening all around (paper curl shadow) */
    linear-gradient(to right, rgba(0,0,0,0.025), transparent 4%, transparent 96%, rgba(0,0,0,0.03)),
    linear-gradient(to bottom, rgba(0,0,0,0.015), transparent 2%, transparent 97%, rgba(0,0,0,0.025));
}

/* contain:layout isolates the front broadsheet from external layout
   changes (class removals on page-inside, data-state swaps) that would
   otherwise cascade a reflow into the front page content.
   No will-change or contain:paint — the broadsheet must paint as part
   of the flap's GPU layer so content is pre-rasterized for the flip. */
.page--front > .broadsheet {
  contain: layout;
  /* Keep permanently GPU-composited so text antialiasing doesn't switch
     between grayscale (GPU) and ClearType (CPU) when animations start/end.
     That switch shifts text by sub-pixels — the visible "shift." */
  transform: translateZ(0);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* View Transitions: hold the old-state screenshot while the compositor
   fully rasterizes the new layout, then swap instantly.  Old and new are
   the same front-page content so the swap is invisible. */
::view-transition-old(root) {
  animation: vt-hold 400ms step-end forwards;
}
::view-transition-new(root) {
  animation: vt-hold 400ms step-end forwards;
  animation-direction: reverse;
}
@keyframes vt-hold {
  from { opacity: 1; }
  to   { opacity: 0; }
}

/* ── Right-edge fold — front page is folded in half ────────────
   A real newspaper lying on a desk shows a visible fold edge on
   the right side: paper thickness, a highlight where light catches
   the rounded fold, and a shadow underneath from the doubled layers. */
.page--front > .broadsheet {
  border-right: 3px solid #d4cec0;
  box-shadow:
    /* Spine gutter — deep shadow at the left binding edge */
    inset 6px 0 14px -4px rgba(0,0,0,0.08),
    inset 2px 0 4px rgba(0,0,0,0.04),
    /* Right fold — inset shadow from the doubled paper edge */
    inset -4px 0 8px -2px rgba(0,0,0,0.06),
    inset -1px 0 2px rgba(0,0,0,0.04),
    /* Fold edge highlight — light catches the rounded paper fold */
    -1px 0 0 #e8e2d5,
    /* Backdrop — newspaper sitting on the desk */
    0 2px 4px rgba(0,0,0,0.06),
    0 6px 16px -2px rgba(0,0,0,0.08),
    0 14px 40px -4px rgba(0,0,0,0.07);
}

/* Bottom edge also shows doubled paper — slightly thicker shadow */
.page--front > .broadsheet::after {
  border-bottom: 2px solid #d8d2c5;
}

/* ── Masthead ─────────────────────────────────────────────────── */
.masthead {
  text-align: center;
  padding: 1.5rem 0 1rem;
  border-top:    4px double var(--rule);
  border-bottom: 4px double var(--rule);
  margin-bottom: 1.5rem;
}

.masthead-seal {
  width: 80px;
  height: 80px;
  margin: 0 auto 0.5rem;
}

.masthead-logo {
  display: block;
  width: 80px;
  height: 80px;
  aspect-ratio: 1;
  opacity: 0.85;
}

.masthead-title {
  font-family: var(--font-display);
  font-size: clamp(3rem, 8vw, 6rem);
  font-weight: 900;
  letter-spacing: 0.02em;
  line-height: 1;
  margin-bottom: 0.25rem;
  color: var(--ink);
}

.masthead-subtitle {
  font-family: var(--font-sans);
  font-size: 0.7rem;
  font-weight: 400;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-bottom: 0.75rem;
}

.dateline {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-family: var(--font-sans);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
  border-top: 1px solid var(--rule-light);
  padding-top: 0.4rem;
}

/* ── Section flags ────────────────────────────────────────────── */
.section-flag {
  font-family: var(--font-sans);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
  border-bottom: 2px solid var(--accent);
  display: inline-block;
  padding-bottom: 0.15rem;
  margin-bottom: 0.75rem;
}

/* ── Hairline rules ───────────────────────────────────────────── */
.rule          { border: none; border-top: 1px solid var(--rule-light); margin: 1.5rem 0; }
.rule--heavy   { border-top: 2px solid var(--rule); }
.rule--double  { border-top: 4px double var(--rule); }

/* ── Above the fold ───────────────────────────────────────────── */
.above-fold {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: var(--col-gap);
  min-height: calc(100dvh - 14rem);
  align-content: start;
}

/* Lead story */
.lead-story { border-right: 1px solid var(--rule-light); padding-right: var(--col-gap); }

.lead-headline {
  font-family: var(--font-display);
  font-size: clamp(1.8rem, 4vw, 2.8rem);
  font-weight: 900;
  line-height: 1.15;
  margin-bottom: 0.5rem;
  color: var(--ink);
}

.lead-deck {
  font-family: var(--font-display);
  font-size: 1.1rem;
  font-style: italic;
  color: var(--ink-light);
  margin-bottom: 1rem;
  line-height: 1.4;
}

.lead-byline {
  font-family: var(--font-sans);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-bottom: 1rem;
}

.lead-body {
  columns: 2;
  column-gap: var(--col-gap);
  column-rule: 1px solid var(--rule-light);
  font-size: 0.95rem;
  text-align: justify;
  hyphens: auto;
}

.lead-body p { margin-bottom: 0.9rem; break-inside: avoid; }

/* Drop cap */
.lead-body p:first-of-type::first-letter {
  font-family: var(--font-display);
  float: left;
  font-size: 3.4em;
  line-height: 0.8;
  padding-right: 0.08em;
  margin-top: 0.05em;
  font-weight: 900;
  color: var(--ink);
}

/* Sidebar */
.sidebar { padding-top: 0.25rem; }

.sidebar-box {
  border: 1px solid var(--rule-light);
  padding: 1rem;
  margin-bottom: 1.25rem;
  background: var(--paper);
}

.sidebar-box h3 {
  font-family: var(--font-sans);
  font-size: 0.72rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 0.6rem;
  border-bottom: 1px solid var(--rule-light);
  padding-bottom: 0.3rem;
}

.stat-row {
  display: flex;
  justify-content: space-between;
  padding: 0.35rem 0;
  border-bottom: 1px dotted var(--rule-light);
  font-size: 0.88rem;
}
.stat-row:last-child { border-bottom: none; }
.stat-label { color: var(--ink-muted); }
.stat-value { font-weight: 700; font-family: var(--font-sans); }

/* ── Fold rule ────────────────────────────────────────────────── */
.fold-rule {
  border: none;
  border-top: 1px solid var(--rule-light);
  margin: 2rem 0;
  position: relative;
}
.fold-rule::after {
  content: '§';
  position: absolute;
  left: 50%;
  top: -0.6em;
  transform: translateX(-50%);
  background: var(--paper);
  padding: 0 0.5rem;
  font-family: var(--font-display);
  color: var(--rule-light);
  font-size: 0.9rem;
}

/* ── Below the fold ───────────────────────────────────────────── */
.below-fold {
  display: flex;
  flex-direction: column;
  gap: var(--col-gap);
}

.below-fold-columns {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: var(--col-gap);
}

/* ── Wire bulletin ─────────────────────────────────────────────── */
.wire-bulletin {
  border: 2px solid var(--rule);
  padding: 0;
  margin-bottom: 0.25rem;
}

.wire-header {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.5rem 0.75rem;
  background: var(--ink);
  color: var(--paper);
}

.wire-slug {
  font-family: var(--font-sans);
  font-size: 0.65rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #b5a99a;
}

.wire-items {
  display: grid;
  grid-template-columns: 1fr 1fr;
  border-top: 1px solid var(--rule-light);
}

.wire-item {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  padding: 0.4rem 0.75rem;
  font-size: 0.78rem;
  line-height: 1.35;
  border-bottom: 1px solid var(--rule-light);
  border-right: 1px solid var(--rule-light);
}

.wire-item:nth-child(2n) {
  border-right: none;
}

.wire-item:nth-last-child(-n+2) {
  border-bottom: none;
}

.wire-badge {
  font-family: var(--font-sans);
  font-size: 0.58rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--accent);
  white-space: nowrap;
  flex-shrink: 0;
}

.wire-text {
  color: var(--ink-light);
  flex: 1;
  min-width: 0;
}

.wire-bill {
  font-family: var(--font-sans);
  font-size: 0.65rem;
  color: var(--ink-muted);
  white-space: nowrap;
  flex-shrink: 0;
}

.section-teaser h2 {
  font-family: var(--font-display);
  font-size: 1.3rem;
  font-weight: 700;
  line-height: 1.2;
  margin-bottom: 0.4rem;
}

.section-teaser p {
  font-size: 0.88rem;
  color: var(--ink-light);
  line-height: 1.5;
}

.teaser-more {
  display: inline-block;
  font-family: var(--font-sans);
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
  text-decoration: none;
  margin-top: 0.5rem;
  border-bottom: 1px solid var(--accent);
}

/* ── Ad slot ──────────────────────────────────────────────────── */
.ad-slot {
  border: 1px solid var(--rule-light);
  padding: 1.25rem 1rem;
  background: var(--paper-dark);
  text-align: center;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

.ad-label {
  font-family: var(--font-sans);
  font-size: 0.58rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-bottom: 0.75rem;
}

.ad-slot .ad-title {
  font-family: var(--font-display);
  font-size: 1.2rem;
  font-weight: 700;
  margin-bottom: 0.3rem;
}

.ad-slot .ad-body {
  font-size: 0.82rem;
  color: var(--ink-light);
  line-height: 1.5;
}

.ad-slot .ad-cta {
  display: inline-block;
  margin-top: 0.6rem;
  font-family: var(--font-sans);
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--paper);
  background: var(--ink);
  padding: 0.4rem 1rem;
  text-decoration: none;
}
.ad-slot .ad-cta:hover { background: var(--accent); }

/* ── Colophon ─────────────────────────────────────────────────── */
.colophon {
  border-top: 4px double var(--rule);
  margin-top: 2rem;
  padding: 1.25rem 0 0.75rem;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem;
  font-family: var(--font-sans);
  font-size: 0.7rem;
  letter-spacing: 0.05em;
  color: var(--ink-muted);
}

.colophon a {
  color: var(--ink-muted);
  text-decoration: underline;
  text-decoration-color: var(--rule-light);
  text-underline-offset: 2px;
}
.colophon a:hover { color: var(--accent); }

.colophon-sources {
  max-width: 60%;
  line-height: 1.6;
}

/* ══════════════════════════════════════════════════════════════════
   PAGE-FLIP SYSTEM — Physical paper animation with 3D transforms
   ══════════════════════════════════════════════════════════════════ */

/* ── Paper Nav ───────────────────────────────────────────────── */
.paper-nav {
  position: sticky;
  top: 0;
  z-index: 100;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 0.75rem;
  padding: 0.6rem 1rem;
  background: var(--paper-dark);
  border-bottom: 1px solid var(--rule-light);
  font-family: var(--font-sans);
  font-size: 0.68rem;
  font-variant: small-caps;
  letter-spacing: 0.12em;
}

.paper-nav a {
  color: var(--ink-muted);
  text-decoration: none;
  padding: 0.15rem 0;
  border-bottom: 2px solid transparent;
  transition: color 200ms, border-color 200ms;
  cursor: pointer;
}

.paper-nav a:hover { color: var(--ink); }

.paper-nav a.active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.paper-nav a.disabled {
  pointer-events: none;
  opacity: 0.4;
}

.nav-dot { color: var(--rule-light); user-select: none; }

/* ── Perspective container ───────────────────────────────────── */
.perspective-container {
  perspective: 1400px;
  perspective-origin: 50% 50%;
  position: relative;
  overflow: visible;
  padding: 1.5rem 0 2rem;
}


/* ── Newspaper — the whole physical newspaper unit ───────────── */
/* Constrained to broadsheet width so only the paper-looking area
   participates in 3D transforms — not the full viewport. */
.newspaper {
  max-width: 1100px;
  margin: 0 auto;
  transform-style: preserve-3d;
  transform-origin: var(--spine-x) center;
  position: relative;
  z-index: 1;
  will-change: transform;
}

/* ── Paper edge on newspaper — visible at ~90° during whole flip ─ */
/* Perpendicular to the page surface at the spine. At newspaper 90°,
   the compound angle is 90 + (−90) = 0° → faces the camera.
   Both faces visible so the spine appears continuous through 360°. */
.newspaper::before {
  content: '';
  position: absolute;
  top: 2px;
  bottom: 2px;
  left: -4px;
  width: 8px;
  background: linear-gradient(to right, #8a8070, #a09585 40%, #b5aa9a 70%, #a89e8e);
  transform: rotateY(-90deg);
  transform-origin: center center;
  backface-visibility: visible;
  pointer-events: none;
  z-index: 20;
  opacity: 0;
}

.newspaper.anim-news-fwd::before,
.newspaper.anim-news-rev::before,
.newspaper.anim-news-fwd-fast::before,
.newspaper.anim-news-rev-fast::before {
  opacity: 1;
}

/* ── Pages (faces of the newspaper) ──────────────────────────── */
.page {
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  background: var(--paper);
}

/* Back page: underside (face-down at rest, revealed when newspaper flips).
   Its own rotateY(180deg) compounds with the newspaper's spine-hinged
   flip: at 180° newspaper rotation, 180 + 180 = 360° = readable. */
.page--back {
  position: absolute;
  top: 0; left: 0; width: 100%;
  transform-origin: center center;
  /* translateZ(-2px) ensures proper 3D sorting: at rest (0°) the back page
     is behind the flap (Z=-2 < flap Z=0).  Past 90° newspaper rotation,
     cos(θ) < 0 so Z_world = -2 × cos(θ) > 0 — back page is IN FRONT. */
  transform: translateZ(-2px) rotateY(180deg);
}

/* Inside page: page 2 (hidden under front flap at rest) */
.page--inside {
  position: absolute;
  top: 0; left: 0; width: 100%;
  transform: translateZ(-1px);  /* sit behind the flap in 3D space */
}

/* Page-inside is only visible when data-state is page2.
   During front and back states, hide it so it never bleeds through. */
.newspaper[data-state="front"] .page--inside { visibility: hidden; }
.newspaper[data-state="back"]  .page--inside { visibility: hidden; }

/* During flap animation: show page-inside while keeping it position:
   absolute + translateZ(-1px) (behind the flap, no layout change).
   The flap stays position: relative and determines height — no jump. */
.newspaper.flap-moving .page--inside { visibility: visible; }

/* When page2 is active, inside becomes visible (stays position: absolute;
   newspaper height is managed by JS to avoid the position swap that caused
   a progressive repaint wave). */
.newspaper[data-state="page2"] .page--inside {
  visibility: visible;
  transform: none;
  z-index: 1;
  overflow: visible;  /* let the under-page peek outside bounds */
}

/* Stack order within page--inside: under-page behind broadsheet */
.newspaper[data-state="page2"] .under-page { z-index: 0; }
.newspaper[data-state="page2"] .page--inside > .broadsheet { position: relative; z-index: 2; }
/* In page2 state, the flap is folded behind.  It stays position: relative
   (no swap) to avoid the compositor-invalidation repaint wave.  min-height
   stretches it to the JS-managed newspaper height so the flap-back paper
   extends all the way down. */
.newspaper[data-state="page2"] .flap {
  min-height: 100%;
}

/* During flap close (page2→front): push page-inside just barely behind
   the flap in 3D space. The flap-close keyframes now stay at translateZ >= 0
   so even a small offset keeps the flap in front without a visible gap. */
.newspaper.flap-closing .page--inside {
  transform: translateZ(-1px);
}

/* ── Spine-gap shadow — cast by the lifting flap onto page below ── */
/* Smooth the shadow in/out so it doesn't snap at animation start/end */
.page--inside > .broadsheet {
  transition: box-shadow 250ms ease;
}

/* Open direction (front→page2): moderate shadow — gap is small */
.newspaper.flap-moving .page--inside > .broadsheet {
  box-shadow:
    inset 12px 0 20px -5px rgba(0,0,0,0.12),
    inset 3px 0 6px -1px rgba(0,0,0,0.08),
    inset -2px 0 6px -2px rgba(0,0,0,0.03);
}

/* Close direction (page2→front): heavier shadow — the flap sweeps
   over so the spine area needs a deeper, wider shadow to sell it. */
.newspaper.flap-closing .page--inside > .broadsheet {
  box-shadow:
    inset 22px 0 36px -6px rgba(0,0,0,0.18),
    inset 8px 0 14px -2px rgba(0,0,0,0.14),
    inset 3px 0 5px rgba(0,0,0,0.10),
    inset -2px 0 6px -2px rgba(0,0,0,0.03);
}

/* Back page stays position:absolute always — no position swap that would
   trigger a layout-shift repaint.  Newspaper height managed by JS. */
/* Flap stays position:relative in back state (no position swap).
   Hiding is deferred to .is-flipped (animation end) so the front
   page content remains visible on the rotating paper mid-flip. */

/* (Flap visibility during newspaper flip is handled below with
   transform-style: flat rules.) */

/* ── Front flap — hinged cover, opens like a book ────────────── */
.flap {
  position: relative;  /* determines newspaper height at rest */
  transform-style: preserve-3d;
  transform-origin: var(--spine-x) center;
  /* Pre-promote to GPU layer so animation start doesn't cause a pop */
  will-change: transform;
}

/* The front page back face is covered by .flap-back's semi-transparent
   paper overlay, letting reversed ink bleed through like real newsprint.
   backface-visibility is NOT hidden — the reversed content IS the bleed. */
.flap > .page--front {
  backface-visibility: visible;
  -webkit-backface-visibility: visible;
}

/* ── Flap back face — visible underside when front page folds over ── */
/* Covers the mirrored front-page content with an opaque paper surface.
   translateZ(1px) ensures it renders in front of page--front's back.
   Very faint ghost lines simulate ink bleed-through from the other side. */
.flap-back {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  /* Rotated 180° + pushed 1px forward to sit over page--front's backface */
  transform: rotateY(180deg) translateZ(1px);
  border-radius: 2px;
  overflow: hidden;
  /* Element-level opacity — lets the reversed page--front content
     bleed through like ink on real newsprint held to light. */
  opacity: 0.88;
  background:
    /* Faint ink bleed-through lines */
    repeating-linear-gradient(
      to bottom,
      transparent 0px, transparent 8px,
      rgba(60,50,35,0.04) 8px, rgba(60,50,35,0.04) 9px,
      transparent 9px, transparent 18px,
      rgba(60,50,35,0.03) 18px, rgba(60,50,35,0.03) 19px,
      transparent 19px, transparent 28px
    ),
    /* Column gutters */
    repeating-linear-gradient(
      to right,
      transparent 0px, transparent 180px,
      rgba(60,50,35,0.015) 180px, rgba(60,50,35,0.015) 182px,
      transparent 182px, transparent 360px
    ),
    /* Spine fold shadow */
    linear-gradient(to left,
      rgba(0,0,0,0.08) 0%, rgba(0,0,0,0.04) 1%, rgba(0,0,0,0.015) 3%, transparent 8%
    ),
    /* Opaque paper surface — opacity on the element handles the bleed-through */
    linear-gradient(170deg, #e3dccf, #e0d9cd 25%, #e5dfd3 50%, #e1dbd0 75%, #dcd6c9);
  box-shadow:
    /* Spine fold crease inset */
    inset -6px 0 16px -4px rgba(0,0,0,0.10),
    inset -2px 0 5px rgba(0,0,0,0.06);
}

/* During newspaper flip, hinge at the spine (left edge) like a
   real newspaper. translateX compensation in the keyframes keeps
   the visual center stable while the right side swings. Flatten
   the flap so its children don't separate in 3D space. */
.newspaper.anim-news-fwd,
.newspaper.anim-news-rev,
.newspaper.anim-news-fwd-fast,
.newspaper.anim-news-rev-fast {
  transform-origin: left center;
}

/* During newspaper flip: keep flap in 3D so backface-visibility works
   on page--front. Without preserve-3d, the flat context means the front
   face is always "facing forward" regardless of the newspaper's rotation,
   and the front page content stays visible throughout the flip. */
.newspaper.anim-news-fwd .flap,
.newspaper.anim-news-rev .flap,
.newspaper.anim-news-fwd-fast .flap,
.newspaper.anim-news-rev-fast .flap {
  transform-style: preserve-3d;
  visibility: visible !important;
}

/* During newspaper flip: push flap-back behind the back page
   so it doesn't z-fight with back page content past 90°. */
.newspaper.anim-news-fwd .flap-back,
.newspaper.anim-news-rev .flap-back,
.newspaper.anim-news-fwd-fast .flap-back,
.newspaper.anim-news-rev-fast .flap-back {
  transform: rotateY(180deg) translateZ(-1px);
}

/* ── Paper edge on flap — visible at 90° during fold-under ───── */
/* Positioned at the spine (left edge). Perpendicular to page surface,
   extending toward viewer (+Z). Becomes face-on when flap hits -90°.
   Centered on the spine with both faces visible for seamless edge. */
.flap::before {
  content: '';
  position: absolute;
  top: 2px;
  bottom: 2px;
  left: -4px;
  width: 8px;
  background: linear-gradient(to right, #8a8070, #a09585 40%, #b5aa9a 70%, #a89e8e);
  transform: rotateY(90deg);
  transform-origin: center center;
  backface-visibility: visible;
  pointer-events: none;
  z-index: 5;
}

/* ── Back face of front page — visible once flap passes 90° ──── */
/* Semi-transparent paper surface constrained to the spine area.
   Only covers ~100px near the fold, so on wide viewports the
   translucent "ink bleed" is visible as a narrow strip beside
   the folded page edge — not an unrealistically large sheet.
   Purely decorative (CSS opacity), no SEO impact. */
.flap::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 100px;  /* only the strip near the spine/fold */
  background:
    /* faint horizontal fold lines */
    repeating-linear-gradient(
      to bottom,
      transparent,
      transparent 120px,
      rgba(0,0,0,0.015) 120px,
      rgba(0,0,0,0.015) 121px
    ),
    /* translucent paper — lets front page ink bleed through */
    linear-gradient(135deg,
      rgba(237,231,218,0.84),
      rgba(235,229,216,0.86) 40%,
      rgba(229,223,210,0.84) 80%,
      rgba(236,230,217,0.86)
    );
  transform: rotateY(180deg);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  pointer-events: none;
  z-index: 1;
}

/* ── Spine-shadow overlays ───────────────────────────────────── */
.page--front::after,
.page--back::after,
.page--inside::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 10;
  opacity: 0;
  background: linear-gradient(
    to right,
    rgba(0,0,0,0.22) 0%,
    rgba(0,0,0,0.14) 8%,
    rgba(0,0,0,0.06) 22%,
    transparent 45%
  );
  background-size: 100% 100%;
}

/* ── Folded-page edges + tint ────────────────────────────────── */

/* Folded page underneath — the front page folds UNDER page 2,
   peeking out slightly at the right and bottom edges like a
   real misaligned page stack. z-index: -1 puts it behind the
   broadsheet but within the page--inside stacking context
   (which sits above the paper-stack). */
/* ── Folded-under page — real DOM element, not pseudo ─────────
   Sits behind the broadsheet via lower z-index. Peeks out at
   the right and bottom edges like a misaligned page in a stack.
   Uses a real element to avoid z-index:-1 stacking issues. */
.under-page {
  position: absolute;
  top: 3px;
  left: -2px;
  right: -16px;
  bottom: -18px;
  pointer-events: none;
  border-radius: 0 3px 14px 0;
  /* Slight rotation — real pages don't sit perfectly aligned */
  transform: rotate(0.15deg);
  transform-origin: top left;
  background:
    /* Corner curl highlight — light catches the lifted corner */
    radial-gradient(
      ellipse at calc(100% - 10px) calc(100% - 10px),
      rgba(255,255,255,0.5) 0%,
      rgba(255,255,255,0.15) 35%,
      transparent 65%
    ),
    /* Top-page shadow pressing down — darkened top+left edges */
    linear-gradient(to bottom,
      rgba(0,0,0,0.08) 0%, rgba(0,0,0,0.03) 2%, transparent 6%
    ),
    linear-gradient(to right,
      rgba(0,0,0,0.07) 0%, rgba(0,0,0,0.02) 2%, transparent 6%
    ),
    /* Faint text bleed-through at visible edges */
    repeating-linear-gradient(
      to bottom,
      transparent 0px, transparent 7px,
      rgba(80,70,55,0.05) 7px, rgba(80,70,55,0.05) 8px,
      transparent 8px, transparent 15px
    ),
    /* Paper surface — noticeably yellowed/aged vs top page */
    linear-gradient(155deg, #e0dacb, #ddd7c8 25%, #e2dccf 50%, #ded8cb 75%, #d9d3c6);
  /* Paper-edge highlight along the visible right + bottom edges */
  border-right: 2px solid #d2cbbf;
  border-bottom: 2px solid #d0c9bc;
  /* Inner top+left edge is darker — tucked under the top page */
  border-top: 1px solid rgba(0,0,0,0.04);
  border-left: 1px solid rgba(0,0,0,0.03);
  box-shadow:
    /* Shadow cast by the TOP page pressing down */
    inset 0 6px 14px -6px rgba(0,0,0,0.14),
    inset 6px 0 14px -6px rgba(0,0,0,0.12),
    /* Ambient occlusion between the two pages */
    inset 2px 2px 5px rgba(0,0,0,0.06),
    /* Paper-edge thickness — subtle double-line at the exposed edge */
    -1px -1px 0 rgba(0,0,0,0.02);
  opacity: 0;
  transition: opacity 400ms ease 200ms;
}

.newspaper[data-state="page2"] .under-page {
  opacity: 1;
}

/* Hide the under-page immediately when the flap starts closing —
   the flap sweeping back covers it, so the peek should vanish
   before the layout swap at animation end. */
.newspaper.flap-moving .under-page {
  opacity: 0;
  transition: opacity 200ms ease;
}

/* ── Corner curl — lifted corner of the page underneath ──────── */
.page-curl {
  position: absolute;
  bottom: 0;
  right: 0;
  width: 36px;
  height: 36px;
  pointer-events: none;
  background:
    radial-gradient(
      circle at 75% 75%,
      rgba(255,255,255,0.3) 0%, transparent 50%
    ),
    linear-gradient(
      225deg,
      transparent 38%,
      #d4cebf 39%,
      #ddd7ca 50%,
      #e8e2d6 62%,
      #f0ebe0 78%,
      #f2ede3 100%
    );
  border-radius: 0 0 4px 0;
  box-shadow:
    -2px -2px 6px rgba(0,0,0,0.10),
    -3px -3px 12px rgba(0,0,0,0.06),
    -1px -1px 2px rgba(0,0,0,0.06);
  clip-path: polygon(100% 0%, 100% 100%, 0% 100%);
}

/* ── Opened newspaper gutter + dimension (page 2 state) ─────── */

/* Deep spine gutter shadow — the fold creates a visible valley
   where the two halves meet. This is the most important visual
   cue that says "this is an opened newspaper." */
.newspaper[data-state="page2"] .page--inside::after {
  opacity: 1;
  background: linear-gradient(
    to right,
    rgba(0,0,0,0.18) 0%,
    rgba(0,0,0,0.12) 1%,
    rgba(0,0,0,0.06) 4%,
    rgba(0,0,0,0.025) 10%,
    transparent 22%
  );
  transition: opacity 400ms ease;
}

/* Broadsheet dimension — deep inset gutter on left (spine),
   subtle right-edge curl, elevated off the desk surface.
   page-settle animation gives a brief shadow pulse as the page "lands". */
.newspaper[data-state="page2"] .page--inside > .broadsheet {
  box-shadow:
    inset 10px 0 22px -6px rgba(0,0,0,0.10),    /* deep spine gutter */
    inset 2px 0 6px -1px rgba(0,0,0,0.06),      /* near-spine crease */
    inset -3px 0 10px -4px rgba(0,0,0,0.03),    /* right-edge curl inset */
    /* Backdrop */
    0 2px 4px rgba(0,0,0,0.06),
    0 6px 16px -2px rgba(0,0,0,0.08),
    0 14px 40px -4px rgba(0,0,0,0.07);
}

/* Right-edge paper curl — override base broadsheet::after to emphasize
   the outer edge of the opened newspaper lifting slightly */
.newspaper[data-state="page2"] .page--inside > .broadsheet::after {
  background:
    /* right-edge lift */
    radial-gradient(ellipse at 100% 20%, rgba(0,0,0,0.06) 0%, transparent 40%),
    radial-gradient(ellipse at 100% 80%, rgba(0,0,0,0.05) 0%, transparent 35%),
    /* subtle right-edge shadow strip */
    linear-gradient(to right, transparent 0%, transparent 94%, rgba(0,0,0,0.035) 98%, rgba(0,0,0,0.05) 100%),
    /* bottom-edge shadow */
    linear-gradient(to bottom, transparent 0%, transparent 96%, rgba(0,0,0,0.03) 100%);
}

/* Page 2 spine crease — no center fold (the newspaper is open flat).
   Crease only at the left spine where the pages meet. */
.newspaper[data-state="page2"] .page--inside > .broadsheet::before {
  background:
    /* Spine crease — sharp fold line at the left edge */
    linear-gradient(to right,
      rgba(0,0,0,0.10) 0%,
      rgba(0,0,0,0.06) 2px,
      rgba(0,0,0,0.03) 6px,
      rgba(0,0,0,0.01) 12px,
      transparent 24px
    );
}

/* Page stack underneath — when back page is showing, multiple
   pages (front + page 2) are folded under. Larger offset than
   the single-page fold to suggest thickness. */
.page--back::before {
  content: '';
  position: absolute;
  top: 4px;              /* more offset — thicker stack */
  left: 0;
  right: -8px;
  bottom: -8px;
  z-index: -1;
  pointer-events: none;
  background:
    /* Denser ink lines — multi-page stack */
    repeating-linear-gradient(
      to bottom,
      transparent 0px, transparent 12px,
      rgba(80,70,55,0.03) 12px, rgba(80,70,55,0.03) 13px
    ),
    linear-gradient(135deg, #e4ded1, #e8e2d6 40%, #e2dcd0 80%, #e6e0d4);
  border-right: 1px solid #c5bfb3;
  border-bottom: 1px solid #c5bfb3;
  border-radius: 0 1px 2px 0;
  opacity: 0;
  transition: opacity 350ms ease;
}

.newspaper[data-state="back"] .page--back::before {
  opacity: 1;
  /* Mirror: peek from left (open edge) instead of right */
  left: -8px;
  right: 0;
  border-right: none;
  border-left: 1px solid #c5bfb3;
  border-radius: 1px 0 0 2px;
}

.newspaper[data-state="back"] .page--back::after {
  opacity: 1;
  /* Spine gutter crease on the RIGHT */
  background: linear-gradient(
    to left,
    rgba(0,0,0,0.16) 0%,
    rgba(0,0,0,0.10) 2%,
    rgba(0,0,0,0.05) 6%,
    rgba(0,0,0,0.02) 14%,
    transparent 25%
  );
  transition: opacity 400ms ease;
}

.newspaper[data-state="back"] .page--back > .broadsheet {
  box-shadow:
    /* Spine gutter — visually on the RIGHT after flip */
    inset -6px 0 14px -4px rgba(0,0,0,0.08),
    inset -2px 0 6px -1px rgba(0,0,0,0.05),
    /* Open-edge curl — visually on the LEFT */
    inset 3px 0 10px -4px rgba(0,0,0,0.03),
    /* Backdrop */
    0 2px 4px rgba(0,0,0,0.06),
    0 6px 16px -2px rgba(0,0,0,0.08),
    0 14px 40px -4px rgba(0,0,0,0.07);
}

/* Back page spine crease — spine is on the RIGHT after flip */
.newspaper[data-state="back"] .page--back > .broadsheet::before {
  background:
    /* Spine crease at the RIGHT edge (mirrored after flip) */
    linear-gradient(to left,
      rgba(0,0,0,0.08) 0%,
      rgba(0,0,0,0.05) 2px,
      rgba(0,0,0,0.025) 6px,
      rgba(0,0,0,0.01) 12px,
      transparent 24px
    ),
    /* Keep horizontal fold crease — the back page was folded */
    linear-gradient(to bottom,
      transparent calc(38% - 8px),
      rgba(0,0,0,0.01) calc(38% - 3px),
      rgba(0,0,0,0.035) 38%,
      rgba(0,0,0,0.01) calc(38% + 3px),
      transparent calc(38% + 8px)
    );
}

/* Back page edge curl — open edge is on the LEFT after flip */
.newspaper[data-state="back"] .page--back > .broadsheet::after {
  background:
    /* Open-edge lifts (left side, away from spine) */
    radial-gradient(ellipse at 0% 20%, rgba(0,0,0,0.06) 0%, transparent 40%),
    radial-gradient(ellipse at 0% 80%, rgba(0,0,0,0.05) 0%, transparent 35%),
    /* Left-edge shadow strip */
    linear-gradient(to left, transparent 0%, transparent 94%, rgba(0,0,0,0.035) 98%, rgba(0,0,0,0.05) 100%),
    /* Bottom-edge shadow */
    linear-gradient(to bottom, transparent 0%, transparent 96%, rgba(0,0,0,0.03) 100%);
}

/* ── KEYFRAMES ───────────────────────────────────────────────── */

/* Flap opens: front page folds UNDER — right edge goes away from
   viewer, then tucks behind page 2.
   translateZ stays POSITIVE during the visible phase (0°–90°) so
   the folding page is in front of page-inside and the fold is
   visible. Past 90° the front face hides (backface-visibility)
   and translateZ goes negative to settle behind page-inside. */
@keyframes flap-open {
  0%   { transform: rotateY(0deg)     rotateX(0deg)     translateZ(0)   skewY(0deg); }
  3%   { transform: rotateY(-1deg)    rotateX(0.1deg)   translateZ(1px) skewY(0deg); }
  10%  { transform: rotateY(-12deg)   rotateX(0.4deg)   translateZ(2px) skewY(0.3deg); }
  20%  { transform: rotateY(-30deg)   rotateX(0.7deg)   translateZ(2px) skewY(0.5deg); }
  32%  { transform: rotateY(-58deg)   rotateX(0.8deg)   translateZ(2px) skewY(0.6deg); }
  42%  { transform: rotateY(-82deg)   rotateX(0.5deg)   translateZ(2px) skewY(0.3deg); }
  50%  { transform: rotateY(-95deg)   rotateX(0.2deg)   translateZ(1px) skewY(0deg); }
  60%  { transform: rotateY(-115deg)  rotateX(-0.1deg)  translateZ(0)   skewY(-0.15deg); }
  72%  { transform: rotateY(-145deg)  rotateX(-0.3deg)  translateZ(0)   skewY(-0.2deg); }
  84%  { transform: rotateY(-170deg)  rotateX(-0.15deg) translateZ(0)   skewY(0.05deg); }
  94%  { transform: rotateY(-182deg)  rotateX(0.05deg)  translateZ(0)   skewY(0deg); }
  100% { transform: rotateY(-180deg)  rotateX(0deg)     translateZ(0)   skewY(0deg); }
}

/* Flap closes: front page unfolds from behind back to cover.
   translateZ stays >= 0 but the arc is shallow — just enough clearance
   to pass over page-inside (at translateZ(-1px)) without a visible gap.
   The reduced lift keeps the pages feeling connected at the spine. */
@keyframes flap-close {
  0%   { transform: rotateY(-180deg) rotateX(0deg)     translateZ(0)   skewY(0deg); }
  3%   { transform: rotateY(-179deg) rotateX(-0.05deg) translateZ(0)   skewY(0deg); }
  8%   { transform: rotateY(-172deg) rotateX(-0.1deg)  translateZ(0)   skewY(-0.15deg); }
  20%  { transform: rotateY(-150deg) rotateX(-0.2deg)  translateZ(1px) skewY(-0.3deg); }
  30%  { transform: rotateY(-120deg) rotateX(-0.1deg)  translateZ(2px) skewY(-0.2deg); }
  42%  { transform: rotateY(-95deg)  rotateX(0deg)     translateZ(2px) skewY(0deg); }
  50%  { transform: rotateY(-82deg)  rotateX(0.1deg)   translateZ(2px) skewY(0.1deg); }
  62%  { transform: rotateY(-55deg)  rotateX(0.3deg)   translateZ(2px) skewY(0.4deg); }
  74%  { transform: rotateY(-30deg)  rotateX(0.4deg)   translateZ(1px) skewY(0.3deg); }
  84%  { transform: rotateY(-12deg)  rotateX(0.2deg)   translateZ(0)   skewY(0.1deg); }
  92%  { transform: rotateY(-2deg)   rotateX(0.05deg)  translateZ(0)   skewY(0deg); }
  97%  { transform: rotateY(1deg)    rotateX(-0.03deg) translateZ(0)   skewY(0deg); }
  100% { transform: rotateY(0deg)    rotateX(0deg)     translateZ(0)   skewY(0deg); }
}

/* Newspaper flips over to show back: hinged at spine (left edge).
   translateX follows (1-cos θ)/2 to keep the visual center stable
   while the right side physically swings around the spine.
   Transform order: translateX · translateZ · rotateY · rotateX
   so translations are in world space (applied after rotations). */
@keyframes news-flip-fwd {
  0%   { transform: translateX(0%)    translateZ(0)   rotateY(0deg)   rotateX(0deg)    skewX(0deg); }
  4%   { transform: translateX(0%)    translateZ(0)   rotateY(2deg)   rotateX(-0.1deg) skewX(0deg); }
  12%  { transform: translateX(2%)    translateZ(3px) rotateY(14deg)  rotateX(-0.3deg) skewX(0.2deg); }
  25%  { transform: translateX(12%)   translateZ(6px) rotateY(38deg)  rotateX(-0.4deg) skewX(0.4deg); }
  40%  { transform: translateX(32%)   translateZ(8px) rotateY(68deg)  rotateX(-0.2deg) skewX(0.3deg); }
  50%  { transform: translateX(50%)   translateZ(8px) rotateY(90deg)  rotateX(0deg)    skewX(0deg); }
  60%  { transform: translateX(68%)   translateZ(8px) rotateY(112deg) rotateX(0.2deg)  skewX(-0.3deg); }
  75%  { transform: translateX(88%)   translateZ(6px) rotateY(142deg) rotateX(0.4deg)  skewX(-0.4deg); }
  88%  { transform: translateX(99%)   translateZ(2px) rotateY(172deg) rotateX(0.2deg)  skewX(-0.1deg); }
  94%  { transform: translateX(100%)  translateZ(0)   rotateY(181deg) rotateX(-0.03deg)skewX(0deg); }
  100% { transform: translateX(100%)  translateZ(0)   rotateY(180deg) rotateX(0deg)    skewX(0deg); }
}

/* Newspaper flips back to front: spine-hinged reverse */
@keyframes news-flip-rev {
  0%   { transform: translateX(100%)  translateZ(0)   rotateY(180deg) rotateX(0deg)    skewX(0deg); }
  4%   { transform: translateX(100%)  translateZ(0)   rotateY(178deg) rotateX(0.1deg)  skewX(0deg); }
  12%  { transform: translateX(98%)   translateZ(3px) rotateY(166deg) rotateX(0.3deg)  skewX(-0.2deg); }
  25%  { transform: translateX(88%)   translateZ(6px) rotateY(142deg) rotateX(0.4deg)  skewX(-0.4deg); }
  40%  { transform: translateX(68%)   translateZ(8px) rotateY(112deg) rotateX(0.2deg)  skewX(-0.3deg); }
  50%  { transform: translateX(50%)   translateZ(8px) rotateY(90deg)  rotateX(0deg)    skewX(0deg); }
  60%  { transform: translateX(32%)   translateZ(8px) rotateY(68deg)  rotateX(-0.2deg) skewX(0.3deg); }
  75%  { transform: translateX(12%)   translateZ(6px) rotateY(38deg)  rotateX(-0.4deg) skewX(0.4deg); }
  88%  { transform: translateX(1%)    translateZ(2px) rotateY(8deg)   rotateX(-0.2deg) skewX(0.1deg); }
  94%  { transform: translateX(0%)    translateZ(0)   rotateY(-1deg)  rotateX(0.03deg) skewX(0deg); }
  100% { transform: translateX(0%)    translateZ(0)   rotateY(0deg)   rotateX(0deg)    skewX(0deg); }
}

/* Fold-crease shadow: fades in + widens at peak, then recedes */
@keyframes crease-sweep {
  0%   { opacity: 0; }
  15%  { opacity: 0.6; }
  40%  { opacity: 1; }
  60%  { opacity: 1; }
  85%  { opacity: 0.6; }
  100% { opacity: 0; }
}

/* Cast shadow: page lifts off the surface during animation */
/* Cast shadow: the desk surface darkens beneath the lifted page.
   Uses a pseudo-element on perspective-container instead of box-shadow
   (which would spill onto stack pages). */
@keyframes cast-shadow {
  0%   { opacity: 0; }
  25%  { opacity: 0.6; }
  50%  { opacity: 1; }
  75%  { opacity: 0.6; }
  100% { opacity: 0; }
}

/* Page settle: subtle bounce when page lands */
@keyframes page-settle {
  0%   { transform: translateY(-2px) scaleY(1.001); }
  40%  { transform: translateY(0.5px) scaleY(0.9995); }
  70%  { transform: translateY(-0.3px) scaleY(1.0002); }
  100% { transform: translateY(0) scaleY(1); }
}

/* Paper warp overlay: simulates paper bending during mid-flip.
   A gradient that shifts across the page surface. */
@keyframes paper-warp-fwd {
  0%   { opacity: 0; background-position: 100% 0; }
  20%  { opacity: 1; background-position: 80% 0; }
  50%  { opacity: 1; background-position: 50% 0; }
  80%  { opacity: 1; background-position: 20% 0; }
  100% { opacity: 0; background-position: 0% 0; }
}

@keyframes paper-warp-rev {
  0%   { opacity: 0; background-position: 0% 0; }
  20%  { opacity: 1; background-position: 20% 0; }
  50%  { opacity: 1; background-position: 50% 0; }
  80%  { opacity: 1; background-position: 80% 0; }
  100% { opacity: 0; background-position: 100% 0; }
}

/* Leading-edge curl: the free edge of the page bends ahead of the fold */
@keyframes edge-curl-open {
  0%   { opacity: 0; transform: scaleX(0); }
  15%  { opacity: 0.7; transform: scaleX(0.6); }
  40%  { opacity: 1; transform: scaleX(1); }
  65%  { opacity: 0.8; transform: scaleX(0.8); }
  85%  { opacity: 0.3; transform: scaleX(0.3); }
  100% { opacity: 0; transform: scaleX(0); }
}

@keyframes edge-curl-close {
  0%   { opacity: 0; transform: scaleX(0); }
  20%  { opacity: 0.5; transform: scaleX(0.5); }
  50%  { opacity: 1; transform: scaleX(1); }
  75%  { opacity: 0.7; transform: scaleX(0.7); }
  100% { opacity: 0; transform: scaleX(0); }
}

/* ── Animation classes (applied by JS) ───────────────────────── */

/* Flap open/close — front page turning like a book cover */
.anim-flap-open      { animation: flap-open  1000ms var(--page-ease) both; }
.anim-flap-close     { animation: flap-close 1000ms var(--page-ease) both; }
.anim-flap-close-fast { animation: flap-close 600ms var(--page-ease) both; }
.anim-flap-open-fast  { animation: flap-open  600ms var(--page-ease) both; }

/* Newspaper flip — entire unit turns over (heavier easing) */
.anim-news-fwd      { animation: news-flip-fwd 1400ms var(--news-ease) both; }
.anim-news-rev      { animation: news-flip-rev 1400ms var(--news-ease) both; }
.anim-news-fwd-fast { animation: news-flip-fwd 1100ms var(--news-ease) both; }
.anim-news-rev-fast { animation: news-flip-rev 1100ms var(--news-ease) both; }

/* Crease shadow during flap animations */
.anim-flap-open .page--front::after,
.anim-flap-close .page--front::after,
.anim-flap-close-fast .page--front::after,
.anim-flap-open-fast .page--front::after {
  animation: crease-sweep 1000ms ease-in-out;
}

/* Crease shadow on inside page when flap moves over it */
.newspaper.flap-moving .page--inside::after {
  animation: crease-sweep 1000ms ease-in-out;
}

/* Crease shadow during full newspaper flip (front page only —
   back page gets persistent spine shadow instead, see below) */
.anim-news-fwd .page--front::after,
.anim-news-rev .page--front::after,
.anim-news-fwd-fast .page--front::after,
.anim-news-rev-fast .page--front::after {
  animation: crease-sweep 1000ms ease-in-out;
}

/* Cast shadow — only on the desk pseudo-element, never on the pages themselves.
   The old cast-shadow rules on .page--front / .page--back animated opacity
   on the entire page, making it transparent. Removed. */

/* ── Back page paper effects during flip ─────────────────────── */
/* Activate spine shadow, page stack, and broadsheet depth on the
   back page DURING the flip animation so it looks like real paper
   as it rotates into view (90°–180°) — not just after animation ends.
   backface-visibility keeps these invisible during 0°–90°. */

/* Page stack underneath — visible as back page faces camera */
.newspaper.anim-news-fwd .page--back::before,
.newspaper.anim-news-rev .page--back::before,
.newspaper.anim-news-fwd-fast .page--back::before,
.newspaper.anim-news-rev-fast .page--back::before {
  opacity: 1;
}

/* During newspaper flip: hide the front page's back face so the reversed
   content doesn't occlude the back page. */
.anim-news-fwd .page--front,
.anim-news-fwd-fast .page--front,
.anim-news-rev .page--front,
.anim-news-rev-fast .page--front {
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

/* Flap visibility during newspaper flips is managed by JS timeouts
   at the midpoint (90° edge-on) — see go() in pageflip.js. */

/* Persistent spine gutter shadow — spine on right side of back page */
.newspaper.anim-news-fwd .page--back::after,
.newspaper.anim-news-rev .page--back::after,
.newspaper.anim-news-fwd-fast .page--back::after,
.newspaper.anim-news-rev-fast .page--back::after {
  opacity: 1;
  background: linear-gradient(
    to left,
    rgba(0,0,0,0.16) 0%,
    rgba(0,0,0,0.10) 2%,
    rgba(0,0,0,0.05) 6%,
    rgba(0,0,0,0.02) 14%,
    transparent 25%
  );
}

/* Enhanced broadsheet depth during flip — spine is on the right */
.newspaper.anim-news-fwd .page--back > .broadsheet,
.newspaper.anim-news-rev .page--back > .broadsheet,
.newspaper.anim-news-fwd-fast .page--back > .broadsheet,
.newspaper.anim-news-rev-fast .page--back > .broadsheet {
  box-shadow:
    inset -5px 0 14px -4px rgba(0,0,0,0.08),
    inset -2px 0 6px -1px rgba(0,0,0,0.05),
    inset 3px 0 10px -4px rgba(0,0,0,0.03);
}

/* ── Desk shadow — darkens the surface beneath the lifting page ── */
.perspective-container::after {
  content: '';
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  height: 60%;
  pointer-events: none;
  z-index: 0;
  opacity: 0;
  background: radial-gradient(
    ellipse at 50% 30%,
    rgba(0,0,0,0.12) 0%,
    rgba(0,0,0,0.06) 40%,
    transparent 70%
  );
  transition: opacity 200ms ease;
}

/* Show desk shadow during any animation */
.perspective-container:has(.anim-flap-open)::after,
.perspective-container:has(.anim-flap-close)::after,
.perspective-container:has(.anim-flap-open-fast)::after,
.perspective-container:has(.anim-flap-close-fast)::after,
.perspective-container:has(.anim-news-fwd)::after,
.perspective-container:has(.anim-news-rev)::after,
.perspective-container:has(.anim-news-fwd-fast)::after,
.perspective-container:has(.anim-news-rev-fast)::after {
  animation: cast-shadow 1000ms ease-in-out both;
}

/* page-settle removed — triggered on every data-state change,
   causing visible reflow artifacts on the broadsheet content. */

/* ── Interactive drag: grab zone + curl hint ──────────────────── */
.flap-grab-zone {
  position: absolute;
  top: 0;
  right: 0;
  width: 15%;
  height: 100%;
  z-index: 30;
  cursor: grab;
  -webkit-tap-highlight-color: transparent;
}

.flap-grab-zone:active { cursor: grabbing; }

/* Corner curl hint — invites user to grab the page */
.flap-grab-zone::before {
  content: '';
  position: absolute;
  bottom: 0;
  right: 0;
  width: 44px;
  height: 44px;
  pointer-events: none;
  border-radius: 0 0 0 0;
  background:
    radial-gradient(circle at 80% 80%, rgba(255,255,255,0.35) 0%, transparent 50%),
    linear-gradient(225deg, transparent 40%, #d4cebf 41%, #ddd7ca 52%, #e8e2d6 65%, #f0ebe0 80%, #f2ede3);
  clip-path: polygon(100% 0%, 100% 100%, 0% 100%);
  box-shadow: -2px -2px 6px rgba(0,0,0,0.10), -3px -3px 12px rgba(0,0,0,0.06);
  transform: scale(0);
  transform-origin: 100% 100%;
  transition: transform 350ms cubic-bezier(0.34, 1.56, 0.64, 1);
  opacity: 0.9;
}

.flap-grab-zone:hover::before {
  transform: scale(1);
}

/* Hide grab zone when flap is open or during animations */
.flap.is-open .flap-grab-zone,
.newspaper[data-state="page2"] .flap-grab-zone,
.newspaper[data-state="back"] .flap-grab-zone { display: none; }

/* Spine grab zone — left edge of newspaper, drag right to flip over */
.spine-grab-zone {
  position: absolute;
  top: 0;
  left: 0;
  width: 15%;
  height: 100%;
  z-index: 30;
  cursor: grab;
  -webkit-tap-highlight-color: transparent;
}
.spine-grab-zone:active { cursor: grabbing; }

/* Corner curl hint — bottom-left, mirrored from flap-grab-zone */
.spine-grab-zone::before {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  width: 44px;
  height: 44px;
  pointer-events: none;
  background:
    radial-gradient(circle at 20% 80%, rgba(255,255,255,0.35) 0%, transparent 50%),
    linear-gradient(315deg, transparent 40%, #d4cebf 41%, #ddd7ca 52%, #e8e2d6 65%, #f0ebe0 80%, #f2ede3);
  clip-path: polygon(0% 0%, 100% 100%, 0% 100%);
  box-shadow: 2px -2px 6px rgba(0,0,0,0.10), 3px -3px 12px rgba(0,0,0,0.06);
  transform: scale(0);
  transform-origin: 0% 100%;
  transition: transform 350ms cubic-bezier(0.34, 1.56, 0.64, 1);
  opacity: 0.9;
}
.spine-grab-zone:hover::before { transform: scale(1); }

/* Only visible on front page */
.newspaper[data-state="page2"] .spine-grab-zone,
.newspaper[data-state="back"] .spine-grab-zone { display: none; }

/* Back-page grab zones — flip newspaper back to front from either edge.
   The newspaper is rotated 180° so CSS left/right are visually swapped. */
.back-grab-left,
.back-grab-right {
  display: none;
  position: absolute;
  top: 0;
  width: 15%;
  height: 100%;
  z-index: 30;
  cursor: grab;
  -webkit-tap-highlight-color: transparent;
}
.back-grab-left:active,
.back-grab-right:active { cursor: grabbing; }

/* CSS right: 0 = visually LEFT (due to 180° rotation) */
/* translateZ(-3px) puts them IN FRONT of page-back (translateZ(-2px))
   when newspaper is at 180° — otherwise page-back blocks pointer events. */
.back-grab-left  { right: 0; transform: translateZ(-3px); }
/* CSS left: 0 = visually RIGHT (due to 180° rotation) */
.back-grab-right { left: 0; transform: translateZ(-3px); }

/* Corner curl hints */
.back-grab-left::before,
.back-grab-right::before {
  content: '';
  position: absolute;
  bottom: 0;
  width: 44px;
  height: 44px;
  pointer-events: none;
  opacity: 0.9;
  transform: scale(0);
  transition: transform 350ms cubic-bezier(0.34, 1.56, 0.64, 1);
}
/* Left curl (visually): positioned at CSS right due to 180° flip */
.back-grab-left::before {
  right: 0;
  background:
    radial-gradient(circle at 80% 80%, rgba(255,255,255,0.35) 0%, transparent 50%),
    linear-gradient(225deg, transparent 40%, #d4cebf 41%, #ddd7ca 52%, #e8e2d6 65%, #f0ebe0 80%, #f2ede3);
  clip-path: polygon(100% 0%, 100% 100%, 0% 100%);
  box-shadow: -2px -2px 6px rgba(0,0,0,0.10), -3px -3px 12px rgba(0,0,0,0.06);
  transform-origin: 100% 100%;
}
/* Right curl (visually): positioned at CSS left due to 180° flip */
.back-grab-right::before {
  left: 0;
  background:
    radial-gradient(circle at 20% 80%, rgba(255,255,255,0.35) 0%, transparent 50%),
    linear-gradient(315deg, transparent 40%, #d4cebf 41%, #ddd7ca 52%, #e8e2d6 65%, #f0ebe0 80%, #f2ede3);
  clip-path: polygon(0% 0%, 100% 100%, 0% 100%);
  box-shadow: 2px -2px 6px rgba(0,0,0,0.10), 3px -3px 12px rgba(0,0,0,0.06);
  transform-origin: 0% 100%;
}
.back-grab-left:hover::before,
.back-grab-right:hover::before { transform: scale(1); }

/* Only visible on back page */
.newspaper[data-state="back"] .back-grab-left,
.newspaper[data-state="back"] .back-grab-right { display: block; }

/* Close grab zone — left spine edge of page2 for dragging closed */
.close-grab-zone {
  display: none;
  position: absolute;
  top: 0;
  left: 0;
  width: 15%;
  height: 100%;
  z-index: 30;
  cursor: grab;
  -webkit-tap-highlight-color: transparent;
}
.close-grab-zone:active { cursor: grabbing; }
.newspaper[data-state="page2"] .close-grab-zone { display: block; }

/* Flip grab zone — right edge of page2, drag left to fold & flip to back */
.flip-grab-zone {
  display: none;
  position: absolute;
  top: 0;
  right: 0;
  width: 15%;
  height: 100%;
  z-index: 30;
  cursor: grab;
  -webkit-tap-highlight-color: transparent;
}
.flip-grab-zone:active { cursor: grabbing; }

/* Corner curl hint — bottom-right */
.flip-grab-zone::before {
  content: '';
  position: absolute;
  bottom: 0;
  right: 0;
  width: 44px;
  height: 44px;
  pointer-events: none;
  background:
    radial-gradient(circle at 80% 80%, rgba(255,255,255,0.35) 0%, transparent 50%),
    linear-gradient(225deg, transparent 40%, #d4cebf 41%, #ddd7ca 52%, #e8e2d6 65%, #f0ebe0 80%, #f2ede3);
  clip-path: polygon(100% 0%, 100% 100%, 0% 100%);
  box-shadow: -2px -2px 6px rgba(0,0,0,0.10), -3px -3px 12px rgba(0,0,0,0.06);
  transform: scale(0);
  transform-origin: 100% 100%;
  transition: transform 350ms cubic-bezier(0.34, 1.56, 0.64, 1);
  opacity: 0.9;
}
.flip-grab-zone:hover::before { transform: scale(1); }

.newspaper[data-state="page2"] .flip-grab-zone { display: block; }

/* ── Interactive drag: dynamic shadow tracking ────────────────── */
.newspaper.dragging .page--inside::after {
  opacity: var(--fold-progress, 0);
  transition: none;
}

/* Show desk shadow during drag */
.perspective-container:has(.dragging)::after {
  opacity: calc(var(--fold-progress, 0) * 0.8);
  transition: none;
}

/* ── End-state classes ───────────────────────────────────────── */
/* Transform must exactly match news-flip-fwd 100% keyframe so removing
   the animation class causes zero visual change (no sub-pixel shift). */
.newspaper.is-flipped {
  transform: translateX(100%) translateZ(0) rotateY(180deg) rotateX(0deg) skewX(0deg);
}

/* Flatten and hide the flap only after the flip animation completes.
   During the animation, the flap stays visible so the front page content
   is "printed on the paper" as it rotates.  is-flipped is added at
   animation end, not mid-flip. */
.newspaper.is-flipped .flap {
  transform-style: flat;
  visibility: hidden;
}

.flap.is-open {
  transform: rotateY(-180deg) translateZ(0);
}

/* When the flap is folded over and at rest, the back face sits flat
   on the left side. Add a right-edge shadow (which is the fold edge)
   and a subtle paper-stack effect. */
/* ── Letterpress test print on the flap back ─────────────────── */
/* Faded typographic ornament — like an old press alignment test
   or printer's mark left on the back of the front page. */
.flap-back-print {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.letterpress {
  font-family: 'Courier New', 'Courier', monospace;
  font-size: clamp(0.55rem, 0.9vw, 0.75rem);
  line-height: 1.5;
  color: rgba(90, 78, 58, 0.22);
  text-align: center;
  white-space: pre;
  margin: 0;
  padding: 2rem;
  letter-spacing: 0.05em;
  user-select: none;
  text-shadow:
    0 0.5px 0 rgba(255,255,255,0.35),
    0 -0.5px 0 rgba(0,0,0,0.04);
}

/* Folded-flat state: deeper spine crease, page pressing flat */
.flap.is-open .flap-back {
  box-shadow:
    /* Deep spine crease — right edge is the fold */
    inset -8px 0 18px -6px rgba(0,0,0,0.14),
    inset -2px 0 5px rgba(0,0,0,0.08),
    /* Top edge tuck-under shadow */
    inset 0 3px 6px -3px rgba(0,0,0,0.06);
}

/* ── Back page & Page 2 content styles ───────────────────────── */
.masthead--compact {
  padding: 1rem 0 0.75rem;
  margin-bottom: 1.25rem;
}

.masthead-title--sm {
  font-size: clamp(2rem, 5vw, 3.5rem);
}

/* Back page sections */
.back-section { margin-bottom: 1.5rem; }

.back-heading {
  font-family: var(--font-display);
  font-size: 1.4rem;
  font-weight: 700;
  line-height: 1.2;
  margin-bottom: 0.75rem;
}

.back-cols {
  columns: 2;
  column-gap: var(--col-gap);
  column-rule: 1px solid var(--rule-light);
  font-size: 0.92rem;
  text-align: justify;
  hyphens: auto;
}

.back-cols p { margin-bottom: 0.8rem; break-inside: avoid; }

.back-thresholds {
  margin-top: 1rem;
  border: 1px solid var(--rule-light);
  padding: 1rem;
  max-width: 480px;
}

.back-thresholds h3 {
  font-family: var(--font-sans);
  font-size: 0.7rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 0.5rem;
  border-bottom: 1px solid var(--rule-light);
  padding-bottom: 0.25rem;
}

/* Source table */
.source-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
  margin-top: 0.75rem;
}

.source-table th {
  font-family: var(--font-sans);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-muted);
  text-align: left;
  border-bottom: 2px solid var(--rule);
  padding: 0.4rem 0.75rem 0.4rem 0;
}

.source-table td {
  padding: 0.5rem 0.75rem 0.5rem 0;
  border-bottom: 1px solid var(--rule-light);
  color: var(--ink-light);
  vertical-align: top;
}

.source-table a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--rule-light);
  text-underline-offset: 2px;
}
.source-table a:hover { color: var(--accent); }

/* Page 2 sections */
.p2-section { margin-bottom: 1.5rem; }

.p2-heading {
  font-family: var(--font-display);
  font-size: 1.4rem;
  font-weight: 700;
  line-height: 1.2;
  margin-bottom: 0.75rem;
}

/* Page 2 grid — mirrors front page's lead story + sidebar pattern */
.p2-grid {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: var(--col-gap);
  align-content: start;
}

.p2-main {
  border-right: 1px solid var(--rule-light);
  padding-right: var(--col-gap);
  font-size: 0.92rem;
  text-align: justify;
  hyphens: auto;
}

.p2-main p { margin-bottom: 0.8rem; }

.p2-aside { padding-top: 0.25rem; }

.p2-aside .sidebar-box p {
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--ink-light);
}

/* Editor's Note — newspaper-style notice (no dashed wireframe borders) */
.p2-notice {
  margin-top: 1rem;
  padding: 0.6rem 0;
  border-top: 1px solid var(--rule-light);
  border-bottom: 1px solid var(--rule-light);
}

.notice-label {
  font-family: var(--font-sans);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.p2-notice p {
  font-size: 0.82rem;
  font-style: italic;
  color: var(--ink-muted);
  line-height: 1.5;
  margin-top: 0.2rem;
}

/* ── Published article cards on page 2 ─────────────────────────── */
.p2-stories {
  margin-top: 1rem;
}

.p2-story {
  padding: 0.8rem 0;
  border-top: 1px solid var(--rule-light);
}

.p2-story:last-child {
  border-bottom: 1px solid var(--rule-light);
}

.p2-story h3 {
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.3;
  margin-bottom: 0.2rem;
}

.p2-story h3 a {
  color: var(--ink);
  text-decoration: none;
}

.p2-story h3 a:hover {
  text-decoration: underline;
}

.p2-story-meta {
  font-family: var(--font-sans);
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-muted);
  margin-bottom: 0.3rem;
}

.p2-story > p {
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--ink-light);
}

/* ── Inner-page visual parity ──────────────────────────────────── */

/* Drop caps — match front page's lead-body drop cap */
.p2-section:first-of-type .p2-main p:first-of-type::first-letter,
.back-section:first-of-type .back-cols p:first-of-type::first-letter {
  font-family: var(--font-display);
  float: left;
  font-size: 3.4em;
  line-height: 0.8;
  padding-right: 0.08em;
  margin-top: 0.05em;
  font-weight: 900;
  color: var(--ink);
}

/* Ornamental section dividers — match front page's § fold-rule */
.p2-section + hr.rule,
.back-section + hr.rule {
  position: relative;
  margin: 2rem 0;
}
.p2-section + hr.rule::after,
.back-section + hr.rule::after {
  content: '§';
  position: absolute;
  left: 50%;
  top: -0.6em;
  transform: translateX(-50%);
  background: var(--paper);
  padding: 0 0.5rem;
  font-family: var(--font-display);
  color: var(--rule-light);
  font-size: 0.9rem;
}

/* Pull quotes — newspaper-style extracted quotations */
.pull-quote {
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-style: italic;
  line-height: 1.35;
  color: var(--ink);
  text-align: center;
  border-top: 2px solid var(--rule);
  border-bottom: 2px solid var(--rule);
  padding: 0.9rem 2rem;
  margin: 1.25rem 0;
}

/* ── Responsive ──────────────────────────────────────────────── */

/* Tablet */
@media (max-width: 900px) {
  :root { --page-pad: 1.5rem; }

  .above-fold {
    grid-template-columns: 1fr;
    min-height: auto;
  }

  .lead-story {
    border-right: none;
    padding-right: 0;
    border-bottom: 1px solid var(--rule-light);
    padding-bottom: 1.5rem;
    margin-bottom: 1rem;
  }

  .below-fold-columns { grid-template-columns: 1fr 1fr; }
  .wire-items { grid-template-columns: 1fr; }
  .wire-item { border-right: none; }

  .back-cols { columns: 1; }

  .p2-grid {
    grid-template-columns: 1fr;
  }
  .p2-main {
    border-right: none;
    padding-right: 0;
    border-bottom: 1px solid var(--rule-light);
    padding-bottom: 1rem;
    margin-bottom: 1rem;
  }
}

/* Touch devices: disable grab zones (use swipe instead) */
@media (pointer: coarse) {
  .flap-grab-zone { pointer-events: none; }
  .close-grab-zone { pointer-events: none; }
  .spine-grab-zone { pointer-events: none; }
  .back-grab-left { pointer-events: none; }
  .back-grab-right { pointer-events: none; }
  .flip-grab-zone { pointer-events: none; }
}

/* Swipe hint for touch devices — subtle arrow below nav */
@media (pointer: coarse) {
  .paper-nav::after {
    content: '\2190  swipe to turn pages  \2192';
    position: absolute;
    bottom: -1.4rem;
    left: 50%;
    transform: translateX(-50%);
    font-family: var(--font-sans);
    font-size: 0.55rem;
    letter-spacing: 0.1em;
    color: var(--ink-muted);
    opacity: 0.5;
    white-space: nowrap;
    pointer-events: none;
    animation: swipe-hint-fade 6s ease-in-out forwards;
  }
}
@keyframes swipe-hint-fade {
  0%, 60% { opacity: 0.5; }
  100%    { opacity: 0; }
}

/* ── Swipe direction hints ────────────────────────────────────── */
/* Metered gradient on the edge the user is swiping toward,
   hinting at a page underneath about to be revealed. */
.swipe-hint {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 60px;
  pointer-events: none;
  opacity: 0;
  transition: opacity 150ms ease-out;
  z-index: 25;
}
.swipe-hint--left {
  left: 0;
  background: linear-gradient(to right,
    rgba(0,0,0,0.12) 0%,
    rgba(0,0,0,0.06) 30%,
    rgba(0,0,0,0.02) 60%,
    transparent 100%
  );
  border-left: 1px solid rgba(0,0,0,0.08);
}
.swipe-hint--right {
  right: 0;
  background: linear-gradient(to left,
    rgba(0,0,0,0.12) 0%,
    rgba(0,0,0,0.06) 30%,
    rgba(0,0,0,0.02) 60%,
    transparent 100%
  );
  border-right: 1px solid rgba(0,0,0,0.08);
}
.swipe-hint.active {
  opacity: 1;
}

/* ── Newspaper mode toggle (mobile/tablet only) ──────────────── */
.newspaper-mode-toggle {
  display: none;  /* hidden on desktop */
}

@media (max-width: 600px) {
  .newspaper-mode-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    background: none;
    border: 1px solid var(--rule-light);
    border-radius: 3px;
    padding: 0.2rem 0.5rem;
    font-family: var(--font-sans);
    font-size: 0.6rem;
    font-variant: small-caps;
    letter-spacing: 0.08em;
    color: var(--ink-muted);
    cursor: pointer;
    margin-left: 0.5rem;
    transition: color 200ms, border-color 200ms;
  }
  .newspaper-mode-toggle:hover,
  .newspaper-mode-toggle.active {
    color: var(--accent);
    border-color: var(--accent);
  }
}

/* When newspaper mode is ON on mobile — undo flat overrides */
@media (max-width: 600px) {
  body.newspaper-mode .perspective-container {
    perspective: 1400px !important;
    padding: 1.5rem 0 2rem !important;
  }
  body.newspaper-mode .broadsheet {
    box-shadow:
      inset 6px 0 14px -4px rgba(0,0,0,0.08),
      inset 2px 0 4px rgba(0,0,0,0.04),
      inset -2px 0 6px -2px rgba(0,0,0,0.03) !important;
  }
  body.newspaper-mode .newspaper {
    transform: unset !important;
    animation: unset !important;
    max-width: 1100px;
    transform-style: preserve-3d !important;
    transform-origin: var(--spine-x) center;
    will-change: transform;
  }
  body.newspaper-mode .flap {
    transform: unset !important;
    animation: unset !important;
    transform-style: preserve-3d !important;
    transform-origin: var(--spine-x) center;
    will-change: transform;
  }
  body.newspaper-mode .newspaper::before,
  body.newspaper-mode .flap::before,
  body.newspaper-mode .flap::after,
  body.newspaper-mode .broadsheet::before,
  body.newspaper-mode .broadsheet::after { display: unset !important; }

  body.newspaper-mode .page--front::after,
  body.newspaper-mode .page--back::after,
  body.newspaper-mode .page--back::before,
  body.newspaper-mode .page--inside::after,
  body.newspaper-mode .page--inside::before { display: unset !important; }

  body.newspaper-mode .under-page,
  body.newspaper-mode .page-curl,
  body.newspaper-mode .flap-back,
  body.newspaper-mode .flap-back-print { display: unset !important; }

  body.newspaper-mode .flap-grab-zone,
  body.newspaper-mode .close-grab-zone,
  body.newspaper-mode .spine-grab-zone,
  body.newspaper-mode .back-grab-left,
  body.newspaper-mode .back-grab-right,
  body.newspaper-mode .flip-grab-zone { display: unset !important; pointer-events: auto !important; }

  body.newspaper-mode .page--inside,
  body.newspaper-mode .page--back {
    display: unset !important;
    position: absolute !important;
    transform: unset !important;
    visibility: unset !important;
  }
  body.newspaper-mode .page--back {
    transform: translateZ(-2px) rotateY(180deg) !important;
  }
  body.newspaper-mode .page--inside {
    transform: translateZ(-1px) !important;
  }

  /* Undo state-specific mobile overrides */
  body.newspaper-mode .newspaper[data-state="page2"] .flap { display: unset !important; }
  body.newspaper-mode .newspaper[data-state="page2"] .page--inside {
    display: unset !important;
    position: absolute !important;
  }
  body.newspaper-mode .newspaper[data-state="back"] .flap { display: unset !important; }
  body.newspaper-mode .newspaper[data-state="back"] .page--inside { display: unset !important; }
  body.newspaper-mode .newspaper[data-state="back"] .page--back {
    display: unset !important;
    position: absolute !important;
    transform: translateZ(-2px) rotateY(180deg) !important;
  }

  /* Hide swipe hint in newspaper mode */
  body.newspaper-mode .paper-nav::after { display: none !important; }
}

/* Mobile — no 3D, flat show/hide */
@media (max-width: 600px) {
  :root { --page-pad: 1rem; --col-gap: 1rem; }
  html { font-size: 16px; }

  .masthead-title { letter-spacing: 0; }
  .dateline { flex-direction: column; gap: 0.2rem; }

  .lead-body { columns: 1; }

  .below-fold-columns { grid-template-columns: 1fr; }

  .colophon { flex-direction: column; }
  .colophon-sources { max-width: 100%; }

  .back-cols { columns: 1; }
  .p2-grid { grid-template-columns: 1fr; }
  .p2-main { border-right: none; padding-right: 0; }

  .pull-quote { font-size: 1.1rem; padding: 0.75rem 1rem; }

  /* Kill 3D and animations */
  .perspective-container { perspective: none; padding: 0; }
  .broadsheet { box-shadow: none; }

  .newspaper {
    transform: none !important;
    animation: none !important;
    position: relative;
  }

  .flap {
    transform: none !important;
    animation: none !important;
    position: relative;
  }

  .newspaper::before { display: none; }
  .flap::before, .flap::after { display: none; }
  .broadsheet::before, .broadsheet::after { display: none; }

  .page--front::after,
  .page--back::after,
  .page--back::before,
  .page--inside::after,
  .page--inside::before { display: none; }
  .under-page, .page-curl { display: none; }
  .flap-back, .flap-back-print { display: none; }
  .flap-grab-zone { display: none; }
  .close-grab-zone { display: none; }
  .spine-grab-zone { display: none; }
  .back-grab-left { display: none; }
  .back-grab-right { display: none; }
  .flip-grab-zone { display: none; }

  .page--inside,
  .page--back {
    display: none;
    position: relative;
    transform: none;
    visibility: visible !important;  /* override desktop 3D visibility rules */
  }

  /* State: page 2 visible */
  .newspaper[data-state="page2"] .flap { display: none; }
  .newspaper[data-state="page2"] .page--inside { display: block; position: relative; }

  /* State: back page visible */
  .newspaper[data-state="back"] .flap { display: none; }
  .newspaper[data-state="back"] .page--inside { display: none; }
  .newspaper[data-state="back"] .page--back { display: block; position: relative; transform: none; }
}

/* ── Print ────────────────────────────────────────────────────── */
@media print {
  body::before { display: none; }
  .paper-nav { display: none; }
  .broadsheet { max-width: 100%; padding: 0; box-shadow: none; background: white; }
  .ad-slot { display: none; }
  .flap-back { display: none; }
  .under-page, .page-curl { display: none; }

  .newspaper::before { display: none; }
  .flap::before, .flap::after { display: none; }
  .broadsheet::before, .broadsheet::after { display: none; }
  .page--front::after, .page--back::after, .page--inside::after { display: none; }
  .page--back::before, .page--inside::before { display: none; }
  .under-page, .page-curl { display: none; }

  .perspective-container { perspective: none; }
  .newspaper {
    transform: none !important;
    animation: none !important;
    position: relative;
  }
  .flap {
    transform: none !important;
    animation: none !important;
    position: relative;
  }
  .page--inside {
    position: relative;
    page-break-before: always;
  }
  .page--back {
    transform: none;
    position: relative;
    page-break-before: always;
  }
}
