/* ===== Self-hosted fonts (variable, latin subset — avoids the Google Fonts CDN round-trip) =====
   Fraunces carries headlines; Instrument Sans carries body, UI and data.
   A display serif over a working grotesk is the same register as the print
   financial press, and it is deliberately not Inter: every crypto site sets
   Inter, and a site that wants to read as expensive cannot type like its
   competitors' defaults. */
@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/fraunces-var-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Instrument Sans";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/instrument-sans-var-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Instrument Sans";
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/instrument-sans-italic-var-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ===== Design tokens ===== */
:root {
  --color-bg: #0c0414;
  --color-bg-deep: #050108;
  --color-bg-elevated: #170a26;
  --color-surface: rgba(255, 255, 255, 0.045);
  --color-surface-hover: rgba(255, 255, 255, 0.08);
  --color-border: rgba(255, 255, 255, 0.09);
  --color-foreground: #f8fafc;
  --color-muted: #a996c4;

  --color-primary: #551a94;
  --color-primary-foreground: #ffffff;
  --color-primary-light: #8b5cf6;
  --color-accent: #c069ff;
  --color-success: #22c55e;
  --color-danger: #ef4444;

  /* The gold is the same one the logo and the social cards already carry —
     promoting it from the logo into eyebrows, kickers and rules is what ties
     the site to its own share cards. -text is the variant tuned to pass
     4.5:1 as small text in each scheme; plain gold is decorative only. */
  --color-gold: #d4a853;
  --color-gold-text: #d4a853;

  --radius-lg: 20px;
  --radius-md: 14px;
  --radius-sm: 10px;

  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-12: 48px;
  --space-16: 64px;

  --font-sans: "Instrument Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-display: "Fraunces", "Iowan Old Style", Georgia, serif;

  /* One grade over every stock photo. The pipeline pulls from two libraries
     with no shared art direction, and ungraded they read as what they are —
     assorted stock. A single warm-muted cast, leaning toward the brand gold,
     makes them read as a commissioned set. Tuned per scheme below. */
  --photo-grade: saturate(0.78) contrast(1.07) brightness(0.94) sepia(0.12) hue-rotate(-8deg);

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --dur-fast: 150ms;
  --dur-base: 250ms;
  --dur-slow: 400ms;

  color-scheme: dark;
}

@media (min-width: 1440px) {
  :root { --space-16: 88px; }
}

/* ===== Reset ===== */
*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%;
  /* The header is sticky, so an anchor jump would drop the heading behind
     it. Clears the 69px bar plus breathing room. */
  scroll-padding-top: 88px;
}
body {
  margin: 0;
  min-height: 100dvh;
  background: var(--color-bg);
  color: var(--color-foreground);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }
[hidden] { display: none !important; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: none; }
input { font: inherit; }
ul { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, h4, p { margin: 0; }

.container {
  width: 100%;
  max-width: 1200px;
  margin-inline: auto;
  padding-inline: var(--space-4);
}
@media (min-width: 768px) { .container { padding-inline: var(--space-6); } }
@media (min-width: 1024px) { .container { padding-inline: var(--space-8); } }

.sr-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0; padding: 0; margin: -1px;
}

.skip-link {
  position: fixed; top: -100%; left: var(--space-4); z-index: 1000;
  background: var(--color-primary); color: var(--color-primary-foreground);
  padding: var(--space-3) var(--space-4); border-radius: var(--radius-sm);
  font-weight: 600; transition: top var(--dur-base) var(--ease-out);
}
.skip-link:focus { top: var(--space-4); }

:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 3px;
  border-radius: 4px;
}

/* ===== Buttons ===== */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 0 var(--space-6);
  border-radius: var(--radius-sm); font-weight: 600; font-size: 0.95rem;
  cursor: pointer; transition: transform var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
  white-space: nowrap;
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn-primary {
  background: linear-gradient(135deg, var(--color-primary), var(--color-primary-light));
  color: var(--color-primary-foreground);
  box-shadow: 0 8px 24px -8px rgba(85, 26, 148, 0.5);
}
.btn-primary:hover { box-shadow: 0 10px 28px -6px rgba(85, 26, 148, 0.6); }
.btn-secondary {
  background: var(--color-accent); color: #2a0845;
  box-shadow: 0 8px 24px -8px rgba(192, 105, 255, 0.5);
}
.btn-ghost {
  background: var(--color-surface); border: 1px solid var(--color-border); color: var(--color-foreground);
}
.btn-ghost:hover { background: var(--color-surface-hover); }
.btn-sm { min-height: 38px; padding: 0 var(--space-4); font-size: 0.875rem; }

.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: var(--radius-sm);
  color: var(--color-muted); cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.icon-btn:hover { background: var(--color-surface); color: var(--color-foreground); }

/* ===== Header ===== */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: rgba(12, 4, 20, 0.65);
  border-bottom: 1px solid var(--color-border);
}
@supports (backdrop-filter: blur(1px)) {
  .site-header { backdrop-filter: blur(18px) saturate(140%); }
}
.header-inner {
  display: flex; align-items: center; justify-content: space-between;
  height: 68px; gap: var(--space-4);
}
.brand { display: flex; align-items: center; gap: var(--space-2); }
/* The hexagon logo is transparent inside, so the header shows through.
   No border-radius — that was for the old rounded-square monogram. */
.brand-mark { height: 30px; width: auto; flex-shrink: 0; display: block; }
.brand-name { font-weight: 800; font-size: 1.15rem; letter-spacing: -0.02em; }

.main-nav { display: none; align-items: center; }
/* WordPress menus output <ul><li><a>, so the list itself carries the layout. */
.main-nav .nav-list {
  display: flex; align-items: center; gap: var(--space-6);
  list-style: none; margin: 0; padding: 0;
}
.main-nav li { margin: 0; }
.main-nav a {
  font-weight: 500; font-size: 0.925rem; color: var(--color-muted);
  padding: var(--space-2) 0; position: relative; display: inline-block;
  transition: color var(--dur-fast) var(--ease-out);
}
.main-nav a:hover { color: var(--color-foreground); }
/* Highlight the section you're currently viewing. */
.main-nav .current-menu-item > a,
.main-nav .current-cat > a { color: var(--color-foreground); }
@media (min-width: 1024px) { .main-nav { display: flex; } }

.header-actions { display: flex; align-items: center; gap: var(--space-2); }
.header-actions .btn-sm { display: none; }
@media (min-width: 640px) { .header-actions .btn-sm { display: inline-flex; } }
.nav-toggle { display: inline-flex; }
@media (min-width: 1024px) { .nav-toggle { display: none; } }

.search-panel {
  border-bottom: 1px solid var(--color-border);
  padding-block: var(--space-3);
  animation: slide-down var(--dur-base) var(--ease-out);
}
.search-panel input {
  width: 100%; min-height: 44px; padding: 0 var(--space-4);
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--radius-sm); color: var(--color-foreground);
}
.search-panel input::placeholder { color: var(--color-muted); }

.mobile-nav {
  display: flex; flex-direction: column;
  border-bottom: 1px solid var(--color-border);
  background: var(--color-bg-elevated);
}
.mobile-nav .nav-list {
  display: flex; flex-direction: column;
  list-style: none; margin: 0; padding: 0;
}
.mobile-nav li { margin: 0; }
.mobile-nav a {
  padding: var(--space-4) var(--space-4);
  border-top: 1px solid var(--color-border);
  font-weight: 500; min-height: 44px; display: flex; align-items: center;
}
.mobile-nav .current-menu-item > a,
.mobile-nav .current-cat > a { color: var(--color-accent); }
@media (min-width: 1024px) { .mobile-nav { display: none !important; } }

@keyframes slide-down { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: translateY(0); } }

/* ===== Hero (Foxy) ===== */
.eyebrow {
  display: inline-flex; align-items: center; gap: var(--space-2);
  font-size: 0.8rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--color-gold-text);
}
.eyebrow::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: var(--color-success); box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.2);
  animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }.ticker-section { padding-block: var(--space-6) var(--space-2); }

.ticker-wrap {
  border: 1px solid var(--color-border); border-radius: var(--radius-md);
  background: var(--color-surface); overflow: hidden; position: relative;
}
@supports (backdrop-filter: blur(1px)) { .ticker-wrap { backdrop-filter: blur(12px); } }
.ticker-track {
  display: flex; gap: var(--space-8); padding: var(--space-4) var(--space-6);
  overflow-x: auto; scrollbar-width: none;
}
.ticker-track::-webkit-scrollbar { display: none; }
.ticker-loading, .feed-loading, .feed-empty { color: var(--color-muted); font-size: 0.9rem; }

.ticker-item { display: flex; align-items: center; gap: var(--space-3); flex-shrink: 0; }
.ticker-symbol { font-weight: 700; }
.ticker-price { font-variant-numeric: tabular-nums; color: var(--color-muted); }
.ticker-change { display: inline-flex; align-items: center; gap: 3px; font-weight: 600; font-variant-numeric: tabular-nums; font-size: 0.875rem; }
.ticker-change.up { color: var(--color-success); }
.ticker-change.down { color: var(--color-danger); }
.ticker-change svg { width: 12px; height: 12px; }

/* ===== Ad slot ===== */
.ad-slot { padding-block: var(--space-4); }
.ad-label {
  display: inline-block; font-size: 0.7rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--color-muted); margin-bottom: var(--space-2);
}
.ad-banner {
  border: 1px dashed var(--color-border); border-radius: var(--radius-md);
  min-height: 90px; display: flex; align-items: center; justify-content: center;
  color: var(--color-muted); font-size: 0.875rem; text-align: center; padding: var(--space-4);
  background: var(--color-surface);
}

/* ===== Filter pills ===== */
.filter-bar { padding-block: var(--space-6) var(--space-4); scroll-margin-top: 84px; }
.filter-pills {
  display: flex; gap: var(--space-2); overflow-x: auto; scrollbar-width: none;
  padding-bottom: 2px;
}
.filter-pills::-webkit-scrollbar { display: none; }
.pill {
  flex-shrink: 0; min-height: 40px; padding: 0 var(--space-4);
  border-radius: 999px; border: 1px solid var(--color-border);
  background: var(--color-surface); color: var(--color-muted);
  font-weight: 600; font-size: 0.875rem; cursor: pointer;
  transition: all var(--dur-fast) var(--ease-out);
}
.pill:hover { background: var(--color-surface-hover); color: var(--color-foreground); }
.pill.is-active {
  background: linear-gradient(135deg, var(--color-primary), var(--color-primary-light));
  color: var(--color-primary-foreground); border-color: transparent;
}

/* ===== Single article ===== */
.article-section { max-width: 720px; padding-block: var(--space-12) var(--space-8); }
.article-meta-top { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-3); margin-bottom: var(--space-4); }
/* Sits in .article-meta-top, which is already a flex row with a gap —
   no separator needed, the gap does the spacing. */
.article-byline {
  font-size: 0.85rem; font-weight: 600; color: var(--color-foreground);
}
.article-date { font-size: 0.85rem; color: var(--color-muted); }
.article-title { font-size: clamp(1.8rem, 4vw, 2.6rem); font-weight: 800; letter-spacing: -0.02em; line-height: 1.15; text-wrap: balance; margin-bottom: var(--space-3); }
.article-source { font-size: 0.9rem; color: var(--color-muted); margin-bottom: var(--space-6); }
.article-source a { color: var(--color-accent); text-decoration: underline; text-underline-offset: 2px; }
.article-thumb { border-radius: var(--radius-lg); overflow: hidden; margin-bottom: var(--space-6); }
.article-thumb img { width: 100%; height: auto; display: block; }
.article-body { font-size: 1.09rem; line-height: 1.75; color: var(--color-foreground); }
.article-body p { margin-bottom: var(--space-4); }
.article-body a { color: var(--color-accent); text-decoration: underline; text-underline-offset: 2px; }
.article-body h2, .article-body h3 { font-weight: 800; letter-spacing: -0.01em; margin-block: var(--space-6) var(--space-3); }
.related-heading { font-size: 1.3rem; font-weight: 800; letter-spacing: -0.01em; margin-bottom: var(--space-6); }

/* ===== Featured story ===== */
.featured-section { padding-block: var(--space-8) var(--space-2); }
.featured-card {
  position: relative;
  display: grid; grid-template-columns: 1fr; gap: var(--space-5);
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--radius-lg); padding: var(--space-6);
  transition: border-color var(--dur-base) var(--ease-out), background var(--dur-base) var(--ease-out);
}
.featured-card:hover { border-color: rgba(192, 105, 255, 0.35); background: var(--color-surface-hover); }
/* Stacked, not split — the same fix the homepage lead got, for the same
   reason: the split halved the image and left dead ground beside it. */
.featured-thumb {
  order: 2; min-height: 200px; border-radius: var(--radius-md);
  display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 2rem; letter-spacing: -0.02em; color: rgba(255, 255, 255, 0.9);
  background: linear-gradient(135deg, var(--thumb-a, #551a94), var(--thumb-b, #c069ff));
}
.featured-thumb { order: 1; }
.featured-body { order: 1; display: flex; flex-direction: column; gap: var(--space-3); }
.featured-body { order: 2; }
.featured-eyebrow { color: var(--color-accent); }
.featured-eyebrow::before { background: var(--color-accent); box-shadow: 0 0 0 3px rgba(192, 105, 255, 0.25); }
.featured-headline { font-size: clamp(1.7rem, 3.2vw, 2.6rem); font-weight: 800; line-height: 1.15; letter-spacing: -0.01em; text-wrap: balance; }
.featured-excerpt { color: var(--color-muted); font-size: 1rem; line-height: 1.6; }
.featured-meta { display: flex; gap: var(--space-3); font-size: 0.85rem; color: var(--color-muted); }

/* ===== News grid ===== */
.news-section { padding-block: var(--space-4) var(--space-12); }
.news-grid {
  display: grid; grid-template-columns: 1fr; gap: var(--space-6);
}
@media (min-width: 768px) { .news-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .news-grid { grid-template-columns: repeat(3, 1fr); } }

.news-card {
  position: relative;
  display: flex; flex-direction: column; gap: var(--space-3);
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--radius-lg); padding: var(--space-4);
  transition: transform var(--dur-base) var(--ease-out), background var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out);
}
.card-link { position: absolute; inset: 0; border-radius: inherit; z-index: 1; }
.news-card:hover {
  background: var(--color-surface-hover); border-color: rgba(192, 105, 255, 0.35);
  transform: translateY(-3px);
}
.card-thumb {
  height: 140px; border-radius: var(--radius-md);
  display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 1.4rem; letter-spacing: -0.02em; color: rgba(255,255,255,0.85);
  background: linear-gradient(135deg, var(--thumb-a, #551a94), var(--thumb-b, #c069ff));
}
.card-tag {
  align-self: flex-start; font-size: 0.7rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.05em; color: var(--color-accent);
  background: rgba(192, 105, 255, 0.14); padding: 4px 10px; border-radius: 999px;
}
.card-headline { font-size: 1.05rem; font-weight: 700; line-height: 1.35; letter-spacing: -0.01em; }
.card-excerpt { color: var(--color-muted); font-size: 0.95rem; line-height: 1.55; }
.card-meta {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 0.8rem; color: var(--color-muted); margin-top: auto; padding-top: var(--space-2);
  border-top: 1px solid var(--color-border);
}

.news-card.sponsored { border-color: rgba(85, 26, 148, 0.4); background: rgba(85, 26, 148, 0.1); }
.news-card.sponsored .card-tag { color: var(--color-accent); background: rgba(192, 105, 255, 0.16); }

/* ===== Newsletter ===== */
.newsletter { padding-block: var(--space-8) var(--space-12); }
.newsletter-card {
  border: 1px solid var(--color-border); border-radius: var(--radius-lg);
  background: linear-gradient(135deg, rgba(85, 26, 148, 0.16), rgba(192, 105, 255, 0.08));
  padding: var(--space-8);
  display: flex; flex-direction: column; gap: var(--space-6);
}
@media (min-width: 768px) {
  .newsletter-card { flex-direction: row; align-items: center; justify-content: space-between; }
  .newsletter-copy { max-width: 46ch; }
}
.newsletter-card h2 { font-size: 1.6rem; font-weight: 800; margin-bottom: var(--space-2); letter-spacing: -0.02em; }
.newsletter-card p { color: var(--color-muted); }
.newsletter-form { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.newsletter-form input {
  flex: 1 1 220px; min-height: 46px; padding: 0 var(--space-4);
  background: rgba(0,0,0,0.3); border: 1px solid var(--color-border);
  border-radius: var(--radius-sm); color: var(--color-foreground);
}
.newsletter-form input::placeholder { color: var(--color-muted); }
.newsletter-status { font-size: 0.875rem; color: var(--color-success); min-height: 1.2em; }
.newsletter-status.is-error { color: var(--color-danger); }

/* ===== Affiliate CTA ===== */
.affiliate-cta { padding-block: 0 var(--space-12); }
.affiliate-card {
  display: flex; flex-direction: column; gap: var(--space-4);
  border: 1px solid var(--color-border); border-radius: var(--radius-lg);
  padding: var(--space-6); background: var(--color-surface);
}
@media (min-width: 768px) { .affiliate-card { flex-direction: row; align-items: center; justify-content: space-between; } }
.affiliate-card h3 { font-size: 1.2rem; font-weight: 700; margin-block: var(--space-1); }
.affiliate-card p { color: var(--color-muted); font-size: 0.9rem; }

/* ===== Footer ===== */
.site-footer { border-top: 1px solid var(--color-border); padding-block: var(--space-8) var(--space-6); }
.footer-inner {
  display: flex; flex-direction: column; gap: var(--space-8);
}
@media (min-width: 768px) { .footer-inner { flex-direction: row; justify-content: space-between; } }
.footer-brand p { color: var(--color-muted); font-size: 0.875rem; margin-top: var(--space-2); max-width: 32ch; }
.footer-links { display: flex; flex-wrap: wrap; gap: var(--space-8) var(--space-12); }
/* Fifteen coins in one column would be taller than the rest of the footer
   put together, so they run in two. */
.footer-coins a { break-inside: avoid; }
@media (min-width: 560px) {
  .footer-coins { columns: 2; column-gap: var(--space-8); }
  .footer-coins h2 { column-span: all; }
}
/* h2 for the document outline (h4 here skipped a level after the page's
   last h2), styled as the small labels they visually are. */
.footer-links h2 { font-size: 0.8rem; font-family: var(--font-sans); font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-muted); margin-bottom: var(--space-3); }
.footer-links a { display: block; font-size: 0.9rem; color: var(--color-foreground); margin-bottom: var(--space-2); opacity: 0.85; }
.footer-links a:hover { opacity: 1; color: var(--color-primary); }
.footer-legal { border-top: 1px solid var(--color-border); margin-top: var(--space-8); padding-top: var(--space-6); }
.footer-legal p { color: var(--color-muted); font-size: 0.8rem; }

/* ===== Parallax intro ===== */
.parallax-intro { position: relative; overflow: hidden; height: 170vh; perspective: 1200px; }
.parallax-header { position: relative; z-index: 1; max-width: 640px; margin-inline: auto; text-align: center; padding-top: 100px; }
.parallax-header h2 { font-size: clamp(1.8rem, 4vw, 2.6rem); font-weight: 800; letter-spacing: -0.02em; margin-block: var(--space-4); text-wrap: balance; }
.parallax-header p { color: var(--color-muted); font-size: 1rem; }

.parallax-stack { position: relative; transform-style: preserve-3d; will-change: transform; margin-top: 64px; }
.parallax-row { display: flex; gap: 24px; margin-bottom: 24px; will-change: transform; padding-inline: var(--space-4); }

.parallax-card {
  flex-shrink: 0; width: 210px; height: 200px; border-radius: var(--radius-lg);
  display: flex; flex-direction: column; gap: 10px;
  padding: 16px 18px;
  background: var(--color-bg-elevated); border: 1px solid var(--color-border);
  color: var(--color-foreground);
  box-shadow: 0 20px 40px -20px rgba(0, 0, 0, 0.6);
  transition: transform 200ms var(--ease-out), border-color 200ms var(--ease-out);
}
.parallax-card:hover { transform: translateY(-10px); border-color: rgba(192, 105, 255, 0.35); }
.parallax-card-head { display: flex; align-items: center; gap: 10px; }
.parallax-card-icon { width: 32px; height: 32px; border-radius: 50%; background: rgba(255, 255, 255, 0.08); flex-shrink: 0; }
.parallax-card-top { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.parallax-card-symbol { font-size: 0.95rem; font-weight: 800; letter-spacing: 0.02em; }
.parallax-card-name { font-size: 0.68rem; color: var(--color-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.parallax-card-bottom { display: flex; align-items: baseline; justify-content: space-between; }
.parallax-card-price { font-size: 1.15rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.parallax-card-change {
  display: inline-flex; align-items: center; gap: 3px;
  font-size: 0.75rem; font-weight: 700;
}
.parallax-card-change.up { color: var(--color-success); }
.parallax-card-change.down { color: var(--color-danger); }
.parallax-card-chart { height: 56px; margin-top: auto; }
.parallax-card-chart svg { display: block; }
@media (min-width: 768px) {
  .parallax-card { width: 250px; height: 220px; padding: 18px 20px; }
  .parallax-card-symbol { font-size: 1.05rem; }
  .parallax-card-price { font-size: 1.3rem; }
}

@media (prefers-reduced-motion: reduce) {
  .parallax-intro { height: auto; padding-bottom: var(--space-12); }
  .parallax-stack, .parallax-row { transform: none !important; opacity: 1 !important; }
}

/* ===== Crypto dashboard ===== */
.crypto-dashboard-section { padding-block: var(--space-12) var(--space-8); }
.section-heading { text-align: center; max-width: 640px; margin-inline: auto; margin-bottom: var(--space-8); display: flex; flex-direction: column; align-items: center; gap: var(--space-2); }
.section-heading h2 { font-size: clamp(1.8rem, 4vw, 2.4rem); font-weight: 800; letter-spacing: -0.02em; }
.section-heading p { color: var(--color-muted); }
.dashboard-search-btn { margin-top: var(--space-4); gap: var(--space-3); }
.dashboard-search-btn kbd { font-family: inherit; font-size: 0.75rem; padding: 2px 7px; border-radius: 6px; background: var(--color-surface-hover); border: 1px solid var(--color-border); }

.dashboard-grid { display: grid; grid-template-columns: 1fr; gap: var(--space-6); }
@media (min-width: 640px) { .dashboard-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .dashboard-grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1440px) { .dashboard-grid { grid-template-columns: repeat(4, 1fr); } }

.coin-card {
  position: relative; background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--radius-lg); padding: var(--space-4);
  display: flex; flex-direction: column; gap: var(--space-3);
  opacity: 0; transform: translateY(14px);
  transition: transform var(--dur-base) var(--ease-out), background var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out);
}
.coin-card.is-visible { opacity: 1; transform: translateY(0); }
.coin-card:hover { background: var(--color-surface-hover); border-color: rgba(192, 105, 255, 0.35); }

.coin-card-head { display: flex; align-items: center; gap: var(--space-3); }
.coin-icon { width: 36px; height: 36px; border-radius: 50%; background: rgba(255, 255, 255, 0.06); flex-shrink: 0; }
.coin-card-head h3 { font-size: 1rem; font-weight: 700; }
.coin-symbol { font-size: 0.78rem; color: var(--color-muted); text-transform: uppercase; letter-spacing: 0.04em; }
/* The visible circle stays 26px so it doesn't shout, but the tappable area is
   padded out to the 44px accessibility minimum via a transparent border. It
   was 26x26, which is under the floor and genuinely fiddly on a phone. */
.coin-remove {
  margin-left: auto; width: 26px; height: 26px; border-radius: 50%; color: var(--color-muted);
  display: flex; align-items: center; justify-content: center; font-size: 1.1rem; cursor: pointer;
  position: relative;
  opacity: 0; transition: opacity 150ms, background 150ms, color 150ms;
}
.coin-remove::before { content: ""; position: absolute; inset: -9px; }
.coin-card:hover .coin-remove { opacity: 1; }
/* Opacity 0 hides it from sight but not from a keyboard, so it stays a silent
   tab stop that does something destructive when activated. */
.coin-remove:focus-visible { opacity: 1; outline: 2px solid var(--color-accent); outline-offset: 2px; }
.coin-remove:hover { background: rgba(239, 68, 68, 0.15); color: var(--color-danger); }

.coin-price-row { display: flex; align-items: baseline; justify-content: space-between; }
.coin-price { font-size: 1.3rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.coin-change { font-size: 0.85rem; font-weight: 700; display: inline-flex; align-items: center; gap: 3px; }
.coin-change.up { color: var(--color-success); }
.coin-change.down { color: var(--color-danger); }

.coin-chart { position: relative; height: 90px; }
.coin-chart svg { display: block; }

/* The percentage above the chart is a 24h figure; the chart is a week. Without
   this label the two read as one number and a card can look self-contradictory
   — a green +1.5% over a line that visibly falls. */
.coin-chart-window {
  position: absolute;
  top: 0;
  right: 0;
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--color-muted);
  opacity: 0.6;
  pointer-events: none;
}
.coin-chart-tooltip {
  position: absolute; pointer-events: none; background: var(--color-bg-elevated); border: 1px solid var(--color-border);
  border-radius: var(--radius-sm); padding: 5px 9px; font-size: 0.72rem; color: var(--color-foreground);
  white-space: nowrap; z-index: 5; opacity: 0; transition: opacity 100ms; font-variant-numeric: tabular-nums;
}
.coin-chart-tooltip.is-visible { opacity: 1; }

.coin-stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-3); padding-top: var(--space-2); border-top: 1px solid var(--color-border); }
.coin-stats div { display: flex; flex-direction: column; gap: 2px; }
.coin-stats span { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-muted); }
.coin-stats strong { font-size: 0.88rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.coin-stats strong.up { color: var(--color-success); }
.coin-stats strong.down { color: var(--color-danger); }


/* ----- Coins index page ----- */

/* The whole card is the link: a full-bleed overlay rather than wrapping the
   card in an <a>, so the remove button inside it stays clickable. */
.coin-card.is-linked { position: relative; transition: border-color var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out); }
.coin-card.is-linked:hover { border-color: var(--color-accent); transform: translateY(-3px); }
.coin-card-link { position: absolute; inset: 0; z-index: 1; border-radius: inherit; }
.coin-card-link:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.coin-card .coin-remove { position: relative; z-index: 2; }

.coins-intro-header { max-width: 640px; margin: 0 auto var(--space-8); text-align: center; }
.coins-intro-header h1, .coins-intro-header h2 { font-size: clamp(1.8rem, 4vw, 2.6rem); font-weight: 800; letter-spacing: -0.02em; margin-block: var(--space-4); text-wrap: balance; }
.coins-intro-header p { color: var(--color-muted); }
.coins-index-main { padding-top: var(--space-12); }

/*
 * The cards arrive as you scroll to them, not all at once on load.
 *
 * .coin-card already starts at opacity 0 and an IntersectionObserver adds
 * .is-visible with a 40ms stagger as each enters view — that machinery was
 * always here. Two things were hiding it: opacity was missing from the
 * transition list, so cards snapped in rather than fading, and a CSS
 * animation added here with `both` fill-mode was pinning them to their
 * finished state before the observer ever ran.
 *
 * So this now leans on the observer instead of competing with it, and just
 * gives the cards further to travel on this page than in a sidebar, which is
 * what makes the arrival read as movement rather than a flicker.
 */
/*
 * The settle: the grid lies back in 3D and rises to flat under its own timing.
 * Not scroll-linked — that spent the reader's scroll and left the top row above
 * the viewport by the time it landed.
 *
 * transform-origin sits at the top edge so the grid pivots around its own top
 * and the first row stays put; pivoting from the centre swings that row up
 * off screen, which was the other half of the same problem.
 *
 * The movement itself is driven from JS with the Web Animations API, not from
 * a class swap. It used to be two classes with the transition declared on the
 * tilted one, which animated the grid *into* the tilt and then cancelled it two
 * frames later when the second class landed — a sub-degree wobble, invisible.
 * A keyframe pair cannot express that bug: the start state is the first frame
 * by definition, so there is no ordering to get wrong.
 */
/*
 * The grid starts slanted back and comes straight as you scroll — one plane,
 * driven by scroll position, not a timer. The transform is written from JS, so
 * nothing is declared here: if the script never runs, the grid is flat and
 * readable rather than stuck at an angle.
 *
 * transform-origin sits on the top edge so straightening pushes the grid down
 * into the page rather than lifting it up. Pivoting from the centre was what
 * carried the first rows up off screen.
 */
.coins-index .crypto-dashboard-section { perspective: 1600px; }
.coins-index .dashboard-grid { transform-origin: 50% 0%; }

/* Cards are visible outright rather than waiting on the shared reveal
   observer: the grid moves as one piece, and a per-card reveal on top of that
   meant cards could still be invisible if the observer missed them. */
.coins-index .coin-card {
  opacity: 1;
  transform: none;
  transition:
    background var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out),
    transform var(--dur-fast) var(--ease-out);
}

/*
 * Compact enough that more than one row is on screen when the grid lands.
 * At full size each card was 505px tall — half a screen to show one price,
 * which is why only the top row was ever visible and why the animation kept
 * seeming to hide things. Four columns from 1200px instead of 1440px, and a
 * shorter sparkline, roughly halve the height.
 */
@media (min-width: 1200px) { .coins-index .dashboard-grid { grid-template-columns: repeat(4, 1fr); } }
.coins-index .coin-card { padding: var(--space-3); gap: var(--space-2); }
.coins-index .coin-chart { height: 52px; }
.coins-index .coin-price { font-size: 1.6rem; }
.coins-index .coin-stats { gap: var(--space-1) var(--space-3); }

/* ===== Search modal ===== */
.search-modal { position: fixed; inset: 0; z-index: 200; display: flex; align-items: flex-start; justify-content: center; padding: 10vh var(--space-4) var(--space-4); }
.search-modal-backdrop { position: absolute; inset: 0; background: rgba(8, 3, 14, 0.7); }
@supports (backdrop-filter: blur(1px)) { .search-modal-backdrop { backdrop-filter: blur(4px); } }
.search-modal-panel {
  position: relative; z-index: 1; width: 100%; max-width: 520px;
  background: var(--color-bg-elevated); border: 1px solid var(--color-border); border-radius: var(--radius-lg);
  overflow: hidden; box-shadow: 0 30px 60px -20px rgba(0, 0, 0, 0.6);
  animation: slide-down var(--dur-base) var(--ease-out);
}
.search-modal-panel input {
  width: 100%; min-height: 52px; padding: 0 var(--space-4); background: transparent; border: none;
  border-bottom: 1px solid var(--color-border); color: var(--color-foreground); font-size: 1rem;
}
.search-modal-panel input::placeholder { color: var(--color-muted); }
.search-modal-panel input:focus { outline: none; }
.search-modal-results { max-height: 320px; overflow-y: auto; }
.search-result-item {
  display: flex; align-items: center; gap: var(--space-3); width: 100%; padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border); cursor: pointer; text-align: left; background: transparent;
}
.search-result-item:hover { background: var(--color-surface-hover); }
/* Results are anchors for coins we have a page for, buttons for the rest —
   both must look identical, so the anchor needs the button's reset. */
a.search-result-item { text-decoration: none; color: inherit; border-left: 0; border-right: 0; border-top: 0; }
.search-result-item img { width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0; }
.search-result-item > span { display: flex; flex-direction: column; gap: 1px; }
.search-result-go {
  margin-left: auto; flex-direction: row !important; font-size: 0.72rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-primary); white-space: nowrap;
}
.search-result-name { font-weight: 600; font-size: 0.9rem; }
.search-result-symbol { font-size: 0.75rem; color: var(--color-muted); text-transform: uppercase; }
.search-modal-empty { padding: var(--space-6); text-align: center; color: var(--color-muted); font-size: 0.9rem; }

/* ===== Pagination ===== */
.pagination, .navigation.pagination { margin-top: var(--space-8); }
.pagination .nav-links {
  display: flex; flex-wrap: wrap; gap: var(--space-2);
  align-items: center; justify-content: center;
}
.pagination .screen-reader-text {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0; padding: 0; margin: -1px;
}
.pagination .page-numbers {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; min-height: 44px; padding: 0 var(--space-3);
  border: 1px solid var(--color-border); border-radius: var(--radius-sm);
  background: var(--color-surface); color: var(--color-muted);
  font-weight: 600; font-size: 0.9rem; text-decoration: none;
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.pagination .page-numbers:hover { background: var(--color-surface-hover); color: var(--color-foreground); }
.pagination .page-numbers.current {
  background: linear-gradient(135deg, var(--color-primary), var(--color-primary-light));
  color: var(--color-primary-foreground); border-color: transparent;
}
.pagination .page-numbers.dots { border-color: transparent; background: transparent; }

/* ===== 404 ===== */
.error-section {
  padding-block: var(--space-16) var(--space-8);
  display: flex; flex-direction: column; align-items: flex-start;
  gap: var(--space-4); max-width: 640px;
}
.error-title {
  font-size: clamp(1.9rem, 5vw, 2.8rem); font-weight: 800;
  letter-spacing: -0.03em; line-height: 1.1; text-wrap: balance;
}
.error-copy { color: var(--color-muted); font-size: 1.05rem; }
.error-actions { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-2); }
.error-search { margin-top: var(--space-6); width: 100%; }
.error-search p { color: var(--color-muted); font-size: 0.9rem; margin-bottom: var(--space-3); }

/* ===== Search form ===== */
.search-form { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.search-form label { flex: 1 1 220px; }
.search-form .search-field {
  width: 100%; min-height: 46px; padding: 0 var(--space-4);
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--radius-sm); color: var(--color-foreground);
}
.search-form .search-field::placeholder { color: var(--color-muted); }
.search-form .search-submit {
  min-height: 46px; padding: 0 var(--space-5); border-radius: var(--radius-sm);
  background: linear-gradient(135deg, var(--color-primary), var(--color-primary-light));
  color: var(--color-primary-foreground); font-weight: 600; cursor: pointer;
}

/* ===== Static page extras ===== */
.article-body ul, .article-body ol { margin-bottom: var(--space-4); padding-left: 1.4em; }
.article-body li { margin-bottom: var(--space-2); }
.article-body blockquote {
  border-left: 3px solid var(--color-accent);
  padding-left: var(--space-4); margin: var(--space-5) 0;
  color: var(--color-muted); font-style: italic;
}
.article-body img { max-width: 100%; height: auto; border-radius: var(--radius-md); }
.article-body table { width: 100%; border-collapse: collapse; margin-bottom: var(--space-4); }
.article-body th, .article-body td {
  text-align: left; padding: var(--space-3); border-bottom: 1px solid var(--color-border);
}
.page-links { display: flex; gap: var(--space-2); margin-top: var(--space-5); }

/* ===== Article structure blocks =====
   These three carry the house article format. The markup contract is in
   README.md — the automation and the block editor must produce the same
   classes, or these rules have nothing to hook onto. */

/* "The short version" — the 3-bullet summary that opens News and Explainers. */
.article-body .cb-short,
.article-body .is-style-cb-short {
  background: rgba(139, 92, 246, 0.1);
  border: 1px solid rgba(139, 92, 246, 0.26);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-6);
  margin-bottom: var(--space-6);
}
.article-body .cb-short::before,
.article-body .is-style-cb-short::before {
  content: "The short version";
  display: block;
  font-size: 0.7rem; font-weight: 700;
  letter-spacing: 0.15em; text-transform: uppercase;
  color: var(--color-accent);
  margin-bottom: var(--space-3);
}
.article-body .cb-short ul,
.article-body ul.is-style-cb-short { margin-bottom: 0; padding-left: 1.15em; }
.article-body .cb-short li,
.article-body .is-style-cb-short li { margin-bottom: var(--space-2); }
.article-body .cb-short li:last-child,
.article-body .is-style-cb-short li:last-child { margin-bottom: 0; }
.article-body .cb-short li::marker,
.article-body .is-style-cb-short li::marker { color: var(--color-primary-light); }

/* "Why this matters to you" — sits 4th in long pieces, last in briefs. */
.article-body .cb-why,
.article-body .is-style-cb-why {
  border-left: 3px solid var(--color-primary-light);
  padding-left: var(--space-4);
  margin-bottom: var(--space-6);
}
.article-body .cb-why::before,
.article-body .is-style-cb-why::before {
  content: "Why this matters to you";
  display: block;
  font-weight: 800; letter-spacing: -0.01em;
  color: var(--color-foreground);
  margin-bottom: var(--space-2);
}
.article-body .cb-why > p:last-child,
.article-body .is-style-cb-why > p:last-child { margin-bottom: 0; }

/* Images with credit lines. WordPress emits figure/figcaption; nothing
   styled them before, so photo credits rendered as loose body text. */
.article-body figure { margin: var(--space-6) 0; }
.article-body figure img { display: block; width: 100%; height: auto; }
.article-body figcaption,
.article-body .wp-element-caption {
  font-size: 0.8rem; line-height: 1.5;
  color: var(--color-muted);
  margin-top: var(--space-2);
}
.article-body figcaption strong { color: var(--color-foreground); font-weight: 600; }

/* Featured image on a card, when a post has one.
   The image is a branded card with text running close to its edges, so the
   container must hold the card's own 1200x630 ratio. Letting it stretch and
   relying on object-fit crops the wordmark and the beat label off the sides. */
.card-thumb-img,
.featured-thumb-img {
  padding: 0; overflow: hidden; background: var(--color-surface);
  aspect-ratio: 1200 / 630; min-height: 0; height: auto;
}
.card-thumb-img img,
.featured-thumb-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Stop the featured row stretching the image to match the text column. */
@media (min-width: 900px) {
  .featured-card:has(.featured-thumb-img) { align-items: center; }
}

/* ===== Coin links (taxonomy: /coin/bitcoin/) ===== */
a.coin-badge { transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out); }
a.coin-badge:hover { background: var(--color-surface-hover); color: var(--color-foreground); }

/* An older .coin-symbol rule lived here setting font-size: 0.5em. It was fully
   overridden for the coin page by the .coin-title .coin-symbol rule further
   down, so its only surviving effect was leaking onto the ticker on the
   /coins/ cards — whose parent is 16px, rendering "BTC" at 8px, well under the
   12px legibility floor. Removed rather than scoped, because scoping it would
   only have preserved dead code. Third collision of this kind in this file
   after .coin-badge and .coin-chart. */
.coin-switcher {
  display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-4);
}

/* Coins a story is about, shown under the article so a reader can carry on
   to everything else we've written about that coin. */
.article-coins {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2);
  margin-top: var(--space-8); padding-top: var(--space-6);
  border-top: 1px solid var(--color-border);
}
.article-coins-label { font-size: 0.85rem; color: var(--color-muted); margin-right: var(--space-1); }
/* ===== Reduced motion ===== */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }}

/* Static pages (How we write, Disclosure) reuse .article-body. The opening
   paragraph is set larger so the page has a lede, like an article does. */
.page-lede { font-size: 1.15rem; line-height: 1.6; color: var(--color-muted); margin-bottom: var(--space-6); }
.footer-legal a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }

/* ===== Coin pages =========================================================
   /coin/bitcoin/ and friends. These are the pages most likely to be somebody's
   first sight of Cryptobase, so the figures need to read as confidently as the
   writing does. ======================================================== */

.coin-hero {
  display: flex; flex-wrap: wrap; align-items: flex-end;
  justify-content: space-between; gap: var(--space-6);
  padding-block: var(--space-12) var(--space-6);
}
.coin-identity { display: flex; align-items: center; gap: var(--space-4); }
.coin-logo {
  width: 56px; height: 56px; flex-shrink: 0;
  display: grid; place-items: center;
  border-radius: 50%; background: var(--color-surface-hover);
  font-weight: 800; font-size: 1.4rem; color: var(--color-muted);
}
.coin-logo img { width: 100%; height: 100%; border-radius: 50%; display: block; }
.coin-title {
  font-size: clamp(1.9rem, 4vw, 2.6rem); font-weight: 800;
  letter-spacing: -0.02em; line-height: 1.1; margin: 0;
  display: flex; align-items: baseline; gap: var(--space-3); flex-wrap: wrap;
}
.coin-title .coin-symbol {
  font-size: 0.95rem; font-weight: 700; letter-spacing: 0.06em;
  color: var(--color-muted); padding: 2px 8px; border-radius: 5px;
  background: var(--color-surface-hover);
}
.coin-rank { margin: var(--space-2) 0 0; font-size: 0.85rem; color: var(--color-muted); }

.coin-price-block { text-align: right; margin-left: auto; }
.coin-price {
  font-size: clamp(1.8rem, 4vw, 2.4rem); font-weight: 800;
  letter-spacing: -0.02em; margin: 0; font-variant-numeric: tabular-nums;
}
.coin-change { margin: 2px 0 0; font-size: 0.95rem; font-weight: 600; color: var(--color-muted); }
.coin-change.is-up { color: var(--color-success); }
.coin-change.is-down { color: var(--color-danger); }
.coin-updated { margin: var(--space-1) 0 0; font-size: 0.78rem; color: var(--color-muted); }

.coin-stats {
  display: grid; gap: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  padding-bottom: var(--space-8);
}
.coin-stat {
  padding: var(--space-4); border-radius: var(--radius-md);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  display: flex; flex-direction: column; gap: 4px;
}
.coin-stat-label { font-size: 0.75rem; letter-spacing: 0.05em; text-transform: uppercase; color: var(--color-muted); }
.coin-stat-value { font-size: 1.25rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.coin-stat-note { font-size: 0.75rem; color: var(--color-muted); }

/* Change over each window, in a strip under the price. Sized to sit quietly:
   it is orientation for someone who just read the headline figure, not the
   main event. Scrolls sideways on a narrow phone rather than wrapping to two
   ragged rows, so the sequence 1h → 1y always reads left to right. */
.coin-performance {
  display: flex; gap: var(--space-2); padding-bottom: var(--space-6);
  overflow-x: auto; scrollbar-width: none;
}
.coin-performance::-webkit-scrollbar { display: none; }
.coin-perf {
  flex: 1 0 auto; min-width: 92px;
  display: flex; flex-direction: column; gap: 2px;
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.coin-perf-label {
  font-size: 0.7rem; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--color-muted); white-space: nowrap;
}
.coin-perf-value {
  font-size: 1rem; font-weight: 700; font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.coin-perf-value.is-up { color: var(--color-success); }
.coin-perf-value.is-down { color: var(--color-danger); }
.coin-perf-short { display: none; }

/* Below roughly a phone's width, five readable labels stop fitting. Swap to
   abbreviations rather than making the reader scroll sideways to find out
   what the year did — the long form stays in the DOM for screen readers. */
@media (max-width: 560px) {
  .coin-performance { gap: var(--space-1); }
  /* flex-basis 0 with shrink enabled, so the five share the row evenly instead
     of each sizing to its own content and pushing 1Y off the edge. */
  /* 4px inline, not a spacing token: a five-figure row on a 375px screen has
     no slack, and "-47.1%" needs every pixel of the box it is given. */
  .coin-perf { flex: 1 1 0; min-width: 0; padding: var(--space-3) 4px; text-align: center; }
  .coin-perf-long { display: none; }
  .coin-perf-short { display: inline; }
  /* Sized so a four-figure yearly move ("+1235%") still fits, not just a
     typical two-figure one. */
  .coin-perf-value { font-size: 0.8rem; letter-spacing: -0.01em; }
  /* Stacked, the equals sign reads as stranded punctuation rather than as the
     relationship between two boxes. The stacking says it well enough. */
  .coin-convert-eq { display: none; }
}

/* Converter. Two boxes either side of an equals sign, which is the whole
   mental model and needs no explaining. */
.coin-convert { padding-bottom: var(--space-12); }
.coin-convert-row {
  display: flex; flex-wrap: wrap; align-items: stretch; gap: var(--space-3);
  max-width: 560px;
}
.coin-convert-field {
  flex: 1 1 200px; display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  transition: border-color var(--dur-fast) var(--ease-out);
}
.coin-convert-field:focus-within { border-color: var(--color-accent); }
.coin-convert-label {
  font-size: 0.75rem; font-weight: 700; letter-spacing: 0.05em;
  color: var(--color-muted); white-space: nowrap; flex-shrink: 0;
}
.coin-convert-field input {
  flex: 1 1 auto; min-width: 0; width: 100%;
  background: none; border: 0; padding: 0; margin: 0;
  color: var(--color-foreground);
  font: inherit; font-size: 1.05rem; font-weight: 700;
  font-variant-numeric: tabular-nums; text-align: right;
}
.coin-convert-field input:focus { outline: none; }
.coin-convert-eq {
  align-self: center; color: var(--color-muted); font-weight: 700;
}
.coin-convert-note {
  margin: var(--space-3) 0 0; max-width: 560px;
  font-size: 0.8rem; color: var(--color-muted);
}

.coin-chart-section { padding-bottom: var(--space-12); }
.coin-chart-head {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: var(--space-4); margin-bottom: var(--space-5);
}
.coin-chart-head h2 { font-size: 1.15rem; font-weight: 700; margin: 0; }
.coin-ranges { display: flex; gap: 4px; flex-wrap: wrap; }
.coin-range {
  font: inherit; font-size: 0.8rem; font-weight: 600;
  padding: 6px 12px; border-radius: 999px; cursor: pointer;
  color: var(--color-muted); background: transparent;
  border: 1px solid var(--color-border);
  transition: color 0.15s ease, background-color 0.15s ease, border-color 0.15s ease;
}
.coin-range:hover { color: var(--color-foreground); border-color: var(--color-accent); }
.coin-range.is-active { color: #fff; background: var(--color-accent); border-color: var(--color-accent); }

.coin-price-chart {
  position: relative;
  height: clamp(240px, 38vw, 400px);
  width: 100%;
}
/* The library renders into a canvas and reads the container's size, so this
   element must have a real height before the chart is created. */
.coin-price-chart canvas { display: block; }

/* Price under the cursor. Reserves its line so the chart does not jump when
   the crosshair appears and disappears. */
/* Price under the cursor, following it around the chart. */
.coin-chart-tip {
  position: absolute; top: 0; left: 0; z-index: 3;
  pointer-events: none; opacity: 0;
  display: flex; flex-direction: column; gap: 1px;
  padding: 8px 10px; border-radius: var(--radius-sm);
  background: var(--color-bg-elevated); border: 1px solid var(--color-border);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
  font-size: 0.78rem; line-height: 1.35; white-space: nowrap;
  font-variant-numeric: tabular-nums;
  transition: opacity 120ms var(--ease-out, ease);
}
.coin-chart-tip.is-visible { opacity: 1; }
.coin-chart-tip .tip-price { font-size: 0.95rem; font-weight: 800; }
.coin-chart-tip .tip-when { color: var(--color-muted); font-size: 0.72rem; }
.coin-chart-tip .tip-row b { display: inline-block; min-width: 42px; font-weight: 600; color: var(--color-muted); }

.coin-chart-controls { display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap; }
.coin-styles { display: inline-flex; gap: 2px; }
.coin-style {
  font: inherit; font-size: 0.78rem; font-weight: 600;
  padding: 6px 12px; border-radius: 999px; cursor: pointer;
  color: var(--color-muted); background: transparent;
  border: 1px solid var(--color-border);
  transition: color 150ms var(--ease-out, ease), background-color 150ms var(--ease-out, ease), border-color 150ms var(--ease-out, ease);
}
.coin-style:active { transform: scale(0.97); }
.coin-style.is-active { color: var(--color-primary-foreground); background: var(--color-primary); border-color: var(--color-primary); }
@media (hover: hover) and (pointer: fine) {
  .coin-style:hover:not(.is-active) { color: var(--color-foreground); border-color: var(--color-accent); }
}
.coin-chart-source a { color: var(--color-muted); text-decoration: underline; text-underline-offset: 2px; }
.coin-chart-status {
  position: absolute; inset: 0; display: grid; place-items: center;
  margin: 0; font-size: 0.9rem; color: var(--color-muted);
}
.coin-chart-axis, .coin-chart-dates {
  display: flex; justify-content: space-between;
  font-size: 0.75rem; color: var(--color-muted);
  font-variant-numeric: tabular-nums;
}
.coin-chart-axis { margin-top: var(--space-2); }
.coin-chart-dates { margin-top: 2px; }
.coin-chart-source { margin-top: var(--space-4); font-size: 0.78rem; color: var(--color-muted); }

.coin-section-title { font-size: 1.15rem; font-weight: 700; margin: 0 0 var(--space-5); }

.coin-others { padding-bottom: var(--space-12); }
.coin-switcher { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.coin-badge {
  display: inline-flex; align-items: baseline; gap: 6px;
  padding: 8px 12px; border-radius: 999px; font-size: 0.82rem; text-decoration: none;
  color: var(--color-muted); background: var(--color-surface);
  border: 1px solid var(--color-border);
  transition: color 0.15s ease, border-color 0.15s ease;
}
.coin-badge:hover { color: var(--color-foreground); border-color: var(--color-accent); }
.coin-badge strong { font-weight: 700; letter-spacing: 0.04em; }
.coin-badge span { opacity: 0.7; }

@media (max-width: 640px) {
  .coin-hero { align-items: flex-start; }
  .coin-price-block { text-align: left; margin-left: 0; }
  .coin-badge span { display: none; }
}

/* The written half of a coin page. A measured reading column, because this is
   prose doing explainer work, not dashboard furniture. */
/* 720, not 760. With the container padding this gives a 656px column — the
   same measure as an article — so the two long-reads on the site set to the
   same line length instead of the coin pages running 15 characters wider. */
.coin-prose { max-width: 720px; padding-bottom: var(--space-8); }
.coin-prose h2 {
  font-size: 1.35rem; font-weight: 800; letter-spacing: -0.01em;
  margin: 0 0 var(--space-4);
}
.coin-prose h3 { font-size: 1.02rem; font-weight: 700; margin: var(--space-6) 0 var(--space-2); }
/* Matched to .article-body. These are the same job — a long read — and they
   were set two sizes apart, in the wider column, which put the FAQ answers
   past the 75-character line where reading measurably slows. */
.coin-prose p,
.coin-prose li { font-size: 1.09rem; line-height: 1.75; color: var(--color-foreground); opacity: 0.92; }
.coin-prose p { margin: 0 0 var(--space-4); }
.coin-reviewed {
  font-size: 0.8rem; color: var(--color-muted);
  margin: var(--space-6) 0 0;
}
.coin-prose-note {
  font-size: 0.85rem; color: var(--color-muted); opacity: 1;
  border-left: 3px solid var(--color-accent);
  padding-left: var(--space-3); margin-top: var(--space-6);
}
/* ----- Collapsible FAQ ----- */

.coin-faq-item { border-bottom: 1px solid var(--color-border); }
.coin-faq-item:first-of-type { border-top: 1px solid var(--color-border); }

.coin-faq-q {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) 0;
  cursor: pointer;
  list-style: none; /* Firefox */
  transition: color var(--dur-fast) var(--ease-out);
}
/* The default disclosure triangle, removed so the chevron below can replace
   it. Needs both rules: Safari and Chrome use the pseudo-element, Firefox
   uses list-style above. */
.coin-faq-q::-webkit-details-marker { display: none; }
.coin-faq-q::marker { content: ""; }
.coin-faq-q:hover { color: var(--color-accent); }
.coin-faq-q:focus-visible {
  outline: 2px solid var(--color-accent); outline-offset: 2px; border-radius: var(--radius-sm);
}

/* Override the prose h3 margins: inside a summary the row's padding is doing
   that job, and the default top margin would push the text off centre. */
.coin-prose .coin-faq-q h3 { margin: 0; font-size: 1rem; }

/* Chevron drawn in CSS rather than shipped as an icon: two borders rotated. */
.coin-faq-mark {
  flex-shrink: 0; width: 9px; height: 9px;
  border-right: 2px solid var(--color-muted);
  border-bottom: 2px solid var(--color-muted);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.coin-faq-item[open] .coin-faq-mark {
  transform: rotate(225deg) translate(-2px, -2px);
  border-color: var(--color-accent);
}

.coin-prose .coin-faq-a p { margin: 0 0 var(--space-4); }

/* Animate the open/close where the browser supports sizing to a keyword.
   Everything else simply snaps open, which is the correct fallback: the
   content is there either way, only the transition is missing. */
@supports (interpolate-size: allow-keywords) {
  :root { interpolate-size: allow-keywords; }
  .coin-faq-item::details-content {
    block-size: 0;
    overflow: hidden;
    transition: block-size var(--dur-fast) var(--ease-out), content-visibility var(--dur-fast) allow-discrete;
  }
  .coin-faq-item[open]::details-content { block-size: auto; }
}
@media (prefers-reduced-motion: reduce) {
  .coin-faq-mark { transition: none; }
  @supports (interpolate-size: allow-keywords) {
    .coin-faq-item::details-content { transition: none; }
  }
}

.coin-resources { padding-bottom: var(--space-8); }

/* A dated update or correction at the foot of an article. Deliberately not
   subtle: the corrections policy on /how-we-write/ promises readers we will
   never quietly edit a piece, and a note nobody notices is a quiet edit. */
.cb-update {
  margin: var(--space-8) 0 0;
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-md);
  border-left: 3px solid var(--color-accent);
  background: var(--color-surface);
  font-size: 0.92rem; line-height: 1.65;
}
.cb-update strong { display: block; margin-bottom: 4px; color: var(--color-foreground); }
.cb-update-correction { border-left-color: var(--color-danger); }

/* ===== The coin, turning behind the page ==================================
   Scroll-linked via animation-timeline, so the browser drives it off the main
   thread and no scroll listener runs in JavaScript. Where that isn't
   supported the coin simply sits still, which is a fine page to read.
   Only transform and opacity animate. ==================================== */

.coin-page { position: relative; }
.coin-page > section,
.coin-page > script { position: relative; z-index: 1; }

.coin-orb {
  position: fixed;
  top: 0;
  /* The band outside the 1200px container, and nothing more. Borrowing the
     container's inner padding looked safe — nothing draws text into it — but
     rules and borders paint across the whole box, padding included, so the
     footer's top rule ran under the coin. The coin is smaller for it, and it
     never touches anything.

     Sizing keeps a 16px margin inside that band, so what fits is driven by
     the display: about 104px on a 1440 laptop, up to the 300px cap on a
     large monitor. */
  --gutter: calc((100vw - 1200px) / 2);
  left: calc(var(--gutter) / 2);
  --orb-w: min(300px, calc(var(--gutter) - 16px));
  width: var(--orb-w);
  aspect-ratio: 1;
  /* Static fallback for reduced motion and browsers without scroll
     timelines: parked mid-gutter, upright. The -50% in the Y term is half
     the coin's own height, so the figure before it is where its CENTRE
     sits, not its top edge. */
  transform: translate(-50%, calc(50vh - 50%));
  perspective: 1400px;
  pointer-events: none;
  z-index: 0;
  opacity: var(--orb-opacity, 0.3);
  mix-blend-mode: screen;
  /* Travel only. No fade, no scale — it is simply there from the top of the
     page, and rides the scroll down. */
  animation: coin-orb-glide linear both;
  animation-timeline: scroll(root block);
}

/* Below this the band is under 88px and the coin stops reading as an object.
   1376 keeps it on every current MacBook at 100% zoom — the 1440 and 1470
   13-inch, the 1512 14-inch — and hides it on smaller windows rather than
   letting it crowd the page. */
@media (max-width: 1375px) {
  .coin-orb { display: none; }
}

@keyframes coin-orb-glide {
  /* Centre travels 26vh -> 74vh. Measured against the centre rather than the
     top edge because the previous version put the top at 82vh and left a
     third of the coin hanging below the fold at the end of the page. */
  from { transform: translate(-50%, calc(26vh - 50%)); }
  to   { transform: translate(-50%, calc(74vh - 50%)); }
}

.coin-orb-inner {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  animation: coin-orb-spin linear both;
  animation-timeline: scroll(root block);
}

/* Half the coin's thickness. Must be a length, not a percentage: translateZ
   rejects percentages, and an invalid value drops the whole transform, which
   silently left the coin flat. */
.coin-orb-inner { --depth: 18px; }

.coin-orb-face {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  backface-visibility: hidden;
  /* The struck field. Separate from the symbol so the symbol can be lit
     without lighting the field with it: a blue Cardano mark on a blue disc
     was camouflaged against its own background. */
  border-radius: 50%;
  background-color: var(--coin-tint, #8b5cf6);
  overflow: hidden;
  /* Lifted by the coin's own darkness, worked out in PHP, so a blue Ethereum
     reads as strongly as an orange Bitcoin instead of sinking into the page. */
  filter: saturate(1.2) brightness(var(--coin-lift, 1));
}

.coin-orb-face img {
  width: 100%;
  height: 100%;
  display: block;
  /* The img is its own 3D layer and does not inherit its parent's backface
     culling — without this, the far face's symbol paints through the coin
     as a mirrored ghost. */
  backface-visibility: hidden;
  /* A logo that already fills its circle runs edge to edge. A bare symbol is
     inset so it sits on the field, and lit so it reads against it. */
  padding: var(--coin-pad, 15%);
  box-sizing: border-box;
  object-fit: contain;
  filter: var(--coin-symbol, none);
}
.coin-orb-front { transform: translateZ(var(--depth)); }
.coin-orb-back { transform: rotateY(180deg) translateZ(var(--depth)); }

/* The edge: a closed cylindrical wall. Forty-eight plaques, each spanning
   7.5 degrees, stood tangent around the rim between the two faces. Unlike
   the old stack of parallel discs, adjacent plaques meet edge to edge, so
   there is no gap for the background to flash through at any angle. Each
   is lit by its angle around the rim, which is what makes the band read
   as a rounded solid rather than a flat ribbon. */
.coin-orb-wall {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 36px;                                       /* the coin's thickness */
  height: calc(var(--orb-w) * 0.0655 + 1.5px);       /* one 48th of the rim, plus seam overlap */
  margin-left: -18px;
  margin-top: calc(var(--orb-w) * -0.0327 - 0.75px);
  transform:
    rotateZ(calc(var(--i) * 7.5deg))
    translateX(calc(var(--orb-w) / 2 - 1px))
    rotateY(90deg);
  backface-visibility: hidden;
  background-color: var(--coin-tint, #8b5cf6);
  filter: brightness(calc(0.82 + 0.28 * (0.5 + 0.5 * cos(calc(var(--i) * 7.5deg - 220deg)))));
}

/* Tumbling, with a constraint: it spins fully on its vertical axis while
   the horizontal axis nods between about 8 and 32 degrees, never flipping
   end over end. Full X-flips presented the coin dead edge-on, and the edge
   is really twenty stacked discs — a cheat that held up as a translucent
   ghost but rendered as a striped smear the moment the light scheme made
   the coin solid. Capping the nod means a face is always showing, which is
   also just a better way to display a coin. Scroll still drives the
   timeline, so scrolling back up runs it in reverse for free. */
@keyframes coin-orb-spin {
  /*
   * A genuine tumble: two whole turns on the vertical axis and one full
   * end-over-end, landing square at both ends because both are multiples
   * of 360.
   *
   * Whole turns pass dead edge-on, which is the moment the edge has to be
   * convincing — it is not real geometry, it is forty flat discs stacked
   * along Z. At the twenty discs this used to have, spaced 3.2px apart, that
   * moment rendered as a stack of separate rings: the striped smear that
   * appeared at the same scroll position on every coin. At forty across a
   * thinner coin the spacing is 0.92px, under one device pixel, and the edge
   * reads solid. Verified by forcing the worst angles directly.
   *
   * The two axes are deliberately at different rates so the coin never
   * arrives at edge-on on both at once, which would collapse it to a point.
   */
  from { transform: rotateY(0deg)   rotateX(0deg); }
  to   { transform: rotateY(720deg) rotateX(360deg); }
}

/* Movement is the thing to remove, not the coin. It stays, it stops turning
   and it stops travelling; the static fallback position holds. */
@media (prefers-reduced-motion: reduce) {
  .coin-orb, .coin-orb-inner { animation: none; }
}

/* No gutter, no coin. Under ~1150px the text spans the screen, and the old
   behaviour — floating it behind the writing — is the thing being retired. */
@media (max-width: 1149px) {
  .coin-orb { display: none; }
}

/* Currency toggle. Sits under the price, deliberately quiet: it is an option,
   not a call to action, and most readers will never touch it. */
.coin-currency { display: inline-flex; gap: 2px; margin-top: var(--space-2); }
.coin-cur {
  font: inherit; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.04em;
  padding: 3px 9px; border-radius: 999px; cursor: pointer;
  color: var(--color-muted); background: transparent;
  border: 1px solid var(--color-border);
  transition: color 150ms var(--ease-out, ease), background-color 150ms var(--ease-out, ease), border-color 150ms var(--ease-out, ease);
}
.coin-cur:active { transform: scale(0.97); }
.coin-cur.is-active {
  color: var(--color-primary-foreground);
  background: var(--color-accent);
  border-color: var(--color-accent);
}
@media (hover: hover) and (pointer: fine) {
  .coin-cur:hover:not(.is-active) { color: var(--color-foreground); border-color: var(--color-accent); }
}.article-title   { font-weight: 640; letter-spacing: -0.008em; line-height: 1.12; }
.featured-headline { font-weight: 600; letter-spacing: -0.004em; line-height: 1.18; }
.card-headline   { font-weight: 620; font-size: 1.12rem; letter-spacing: 0; line-height: 1.28; }
.article-body h2 { font-weight: 600; letter-spacing: -0.004em; }
.related-heading,
.newsletter-card h2,
.parallax-header h2,
.section-heading h2,
.coins-intro-header h1,
.coins-intro-header h2 { font-weight: 600; letter-spacing: -0.006em; }
.coin-title      { font-weight: 620; letter-spacing: -0.006em; }
.coin-section-title { font-weight: 600; font-size: 1.25rem; }
.error-title     { font-weight: 620; letter-spacing: -0.006em; }

/* The ticker chips, prices and stat figures change every minute; tabular
   numerals stop the layout breathing in and out as digits flip. */
.coin-price, .coin-price-row, .coin-stats strong, .ticker-track,
.parallax-card-price, .coin-stat-value, .coin-perf-value {
  font-variant-numeric: tabular-nums;
}

/* The symbol pill inside a serif title should stay a sans artefact. */
.coin-title .coin-symbol { font-family: var(--font-sans); }

/* ===================================================================
   Light scheme — "editorial daylight"
   ===================================================================
   Follows the reader's OS setting; there is no toggle to maintain.
   Deliberately warm paper and plum-ink rather than SaaS white: the dark
   theme's identity is deep purple and gold, and this is the same
   identity lit from the front, not a different site.

   Everything that can flow through a token does; the selectors below
   the token block are the handful of places the dark build hard-coded
   an assumption (white-alpha surfaces, black fades, glow colours) that
   inverts badly.
   =================================================================== */

  html[data-theme="light"] {
    --color-bg: #faf8f4;
    --color-bg-deep: #f1ede5;
    --color-bg-elevated: #ffffff;
    --color-surface: rgba(26, 16, 38, 0.04);
    --color-surface-hover: rgba(26, 16, 38, 0.08);
    --color-border: rgba(26, 16, 38, 0.13);
    --color-foreground: #1a1026;
    --color-muted: #5d5170;

    --color-primary: #551a94;
    --color-primary-light: #6d28d9;
    --color-accent: #6d28d9;
    --color-success: #15803d;
    --color-danger: #c11d1d;

    --color-gold: #c89a3f;
    --color-gold-text: #8a6a1f;

    --photo-grade: saturate(0.82) contrast(1.04) sepia(0.10) hue-rotate(-6deg);

    color-scheme: light;
  }
  html[data-theme="light"] .site-header { background: rgba(250, 248, 244, 0.75); }
  html[data-theme="light"] .parallax-card-icon,
html[data-theme="light"] .coin-icon { background: rgba(26, 16, 38, 0.05); }

  html[data-theme="light"] .search-modal-backdrop { background: rgba(26, 16, 38, 0.35); }



/* ===== Photo grade ===== */
.article-body figure img,
.card-thumb-img img,
.featured-thumb-img img {
  filter: var(--photo-grade);
}

/* ===================================================================
   Mobile coin list
   ===================================================================
   Under 640px the dashboard cards become ledger rows: icon and name,
   a small week-line, price and change. The desktop card stacked on a
   phone was fifteen full cards — eight screens of scrolling for a
   glance a table answers in two. Different layout, not a smaller one;
   every figure the row drops is one tap away on the coin's own page.
   =================================================================== */
@media (max-width: 639px) {
  .coins-index .dashboard-grid { gap: var(--space-2); }

  .coins-index .coin-card {
    display: grid;
    /* Explicit areas, not auto-placement: the card's DOM order is
       head, price, chart, and auto-flow was seating the price in the
       narrow chart column, printing it over the coin's name. */
    grid-template-columns: minmax(0, 1fr) 76px auto;
    grid-template-areas: "head chart price";
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-sm);
  }
  .coins-index .coin-card-head { grid-area: head; }
  .coins-index .coin-chart { grid-area: chart; }
  .coins-index .coin-price-row { grid-area: price; }

  .coins-index .coin-card-head { min-width: 0; }
  .coins-index .coin-card-head h3 {
    font-size: 0.95rem;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .coins-index .coin-icon { width: 30px; height: 30px; }
  .coins-index .coin-remove { display: none; }

  .coins-index .coin-chart {
    height: 34px; margin: 0; overflow: hidden;
    /* Decorative at this size — taps belong to the card link. */
    pointer-events: none;
  }
  /* The sparkline SVG carries fixed pixel dimensions from whatever width
     the container had when the data arrived; scaling it to the cell means
     a chart drawn pre-layout can never spill across the row. */
  .coins-index .coin-chart svg { width: 100%; height: 100%; }
  .coins-index .coin-chart-window,
  .coins-index .coin-chart-tooltip { display: none; }

  .coins-index .coin-price-row {
    flex-direction: column; align-items: flex-end; gap: 2px; margin: 0;
  }
  .coins-index .coin-price { font-size: 1.02rem; }
  .coins-index .coin-change { font-size: 0.78rem; }

  .coins-index .coin-stats { display: none; }
}
/* ===== The coin in daylight =====
   Screen blending adds light, and adding light to paper is a no-op — in the
   light scheme the coin had simply vanished. Here it becomes a solid object
   instead: full colour, no blend, with an inked edge so the white-field
   coins (XRP, Litecoin, Stellar) read as discs on paper rather than
   dissolving into it. The brightness lift is dropped too — it was computed
   to survive screen-blending on black, and on paper it just bleaches. */

  html[data-theme="light"] .coin-orb { mix-blend-mode: normal; --orb-opacity: 0.9; }
  html[data-theme="light"] .coin-orb-face {
    filter: saturate(1.05);
    border: 1px solid rgba(26, 16, 38, 0.2);
    /* A 6% ink veil over the field. Invisible on an orange or blue coin,
       but it is what separates the white-field coins — XRP, Litecoin,
       Stellar — from the paper they would otherwise dissolve into. */
    background-image: linear-gradient(rgba(26, 16, 38, 0.06), rgba(26, 16, 38, 0.06));
  }


/* A keyboard shortcut is not a promise a phone can keep. */
@media (hover: none) {
  .dashboard-search-btn kbd { display: none; }
}

/* ===== Coin page: on-this-page nav =====
   Quiet by design: it is a signpost, not a call to action. Horizontally
   scrollable on a phone so five links never wrap into a stack. */
.coin-jump {
  display: flex; align-items: baseline; gap: var(--space-4);
  padding-block: var(--space-3);
  border-block: 1px solid var(--color-border);
  margin-bottom: var(--space-6);
}
.coin-jump-label {
  font-size: 0.7rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--color-gold-text); white-space: nowrap;
}
.coin-jump ul {
  list-style: none; margin: 0; padding: 0;
  display: flex; gap: var(--space-2); overflow-x: auto;
  scrollbar-width: none;
}
.coin-jump ul::-webkit-scrollbar { display: none; }
.coin-jump a {
  display: inline-block; white-space: nowrap;
  font-size: 0.85rem; font-weight: 600; text-decoration: none;
  color: var(--color-muted);
  padding: 5px 12px; border-radius: 999px;
  border: 1px solid transparent;
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.coin-jump a:hover, .coin-jump a:focus-visible {
  color: var(--color-foreground); border-color: var(--color-border);
}
@media (max-width: 560px) {
  .coin-jump { flex-direction: column; gap: var(--space-2); }
}

/* ===== Feed paging ===== */
.feed-more { display: flex; justify-content: center; padding-block: var(--space-8) var(--space-4); }

/* ===== Theme toggle ===== */
/* The button shows the theme a click will take you to: moon in light, sun
   in dark. Both icons live in the DOM; the active theme picks one. */
#theme-toggle .theme-icon-sun { display: block; }
#theme-toggle .theme-icon-moon { display: none; }
html[data-theme="light"] #theme-toggle .theme-icon-sun { display: none; }
html[data-theme="light"] #theme-toggle .theme-icon-moon { display: block; }

/* ===== Chart zoom hint ===== */
/* Appears only when someone scrolls over the chart without the modifier —
   the moment they'd wonder why nothing zoomed — then gets out of the way. */
.coin-chart-zoom-hint {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  padding: 8px 16px;
  border-radius: 999px;
  background: rgba(12, 4, 20, 0.78);
  color: #f8fafc;
  font-size: 0.85rem;
  font-weight: 600;
  pointer-events: none;
  opacity: 0;
  transition: opacity 200ms ease;
  z-index: 3;
  white-space: nowrap;
}
.coin-chart-zoom-hint.is-visible { opacity: 1; }
html[data-theme="light"] .coin-chart-zoom-hint {
  background: rgba(26, 16, 38, 0.82);
  color: #faf8f4;
}

/* ===================================================================
   Archive pages — /news/ and the section pages
   =================================================================== */
.archive-intro {
  max-width: 720px;
  margin-inline: auto;
  text-align: center;
  padding-block: var(--space-8) var(--space-4);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
}
.archive-intro h1 {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-weight: 600;
  letter-spacing: -0.006em;
  font-size: clamp(2rem, 4.5vw, 2.8rem);
  margin: 0;
  text-wrap: balance;
}
.archive-intro p { color: var(--color-muted); max-width: 52ch; margin: 0; }

/* The rail reuses the pill design; on phones it scrolls sideways rather
   than wrapping into a wall. */
.archive-rail {
  display: flex;
  gap: var(--space-2);
  justify-content: center;
  flex-wrap: wrap;
  margin-top: var(--space-2);
}
@media (max-width: 640px) {
  .archive-rail {
    flex-wrap: nowrap;
    overflow-x: auto;
    justify-content: flex-start;
    max-width: 100%;
    padding-bottom: 4px;
    scrollbar-width: none;
  }
  .archive-rail::-webkit-scrollbar { display: none; }
  .archive-rail .pill { flex-shrink: 0; }
}

/* Pills are links on archive pages; keep the button look. */
.archive-rail .pill { text-decoration: none; display: inline-flex; align-items: center; }

.feed-viewall { display: flex; justify-content: center; margin-top: var(--space-8); }

/* ===================================================================
   Front page: masthead strip, top story, live list
   =================================================================== */
.frontpage { padding-block: var(--space-6) var(--space-8); }

.masthead-strip {
  display: flex; align-items: center; gap: var(--space-4);
  padding-bottom: var(--space-4); margin-bottom: var(--space-6);
  border-bottom: 1px solid var(--color-border);
}
.masthead-brand { font-weight: 800; font-size: 0.95rem; letter-spacing: 0.08em; }
.masthead-brand b { color: var(--color-gold-text); }
.masthead-rule { flex: 1; height: 1px; background: linear-gradient(90deg, var(--color-gold), transparent); opacity: 0.5; }
.masthead-tag { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.14em; color: var(--color-muted); }

.frontpage-grid { display: grid; gap: var(--space-8); }
@media (min-width: 1024px) {
  .frontpage-grid { grid-template-columns: 280px minmax(0, 1fr); align-items: start; }
}

/* --- The live list: times and headlines, nothing else. --- */
.live-list { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
@media (max-width: 1023px) { .live-list { order: 2; } }
.live-list-title {
  display: flex; align-items: center; gap: var(--space-2);
  font-family: var(--font-sans); font-size: 0.8rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.08em; color: var(--color-gold-text);
  margin: 0 0 var(--space-2);
}
.live-dot {
  width: 7px; height: 7px; border-radius: 50%; display: inline-block;
  background: var(--color-success); box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.18);
  animation: pulse 2s ease-in-out infinite;
}
.live-list ol { list-style: none; margin: 0; padding: 0; }
.live-list li {
  display: grid; grid-template-columns: 44px 1fr; gap: var(--space-3);
  padding-block: var(--space-3);
  border-bottom: 1px solid var(--color-border);
}
.live-list li:first-child { padding-top: 0; }
.live-list time {
  font-size: 0.78rem; font-variant-numeric: tabular-nums;
  color: var(--color-muted); padding-top: 2px;
}
.live-list li a {
  color: var(--color-foreground); text-decoration: none;
  font-size: 0.9rem; font-weight: 600; line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.live-list li a:hover { color: var(--color-accent); }
.live-list-more {
  margin-top: var(--space-3); font-size: 0.85rem; font-weight: 700;
  color: var(--color-accent); text-decoration: none;
}
.live-list-more:hover { text-decoration: underline; }

/* --- The top story: a front page's front page. --- */
/* The lead stacks: image at the full width of its column, text beneath in
   large type. It used to sit in a side-by-side split that halved the image
   and left a field of empty ground under both halves — Faeren screenshotted
   it and asked why the top story was small on its own front page. Fair. On a
   paper the lead dominates the fold, and a stacked lead is nearly twice the
   size in the same column. */
.top-story {
  position: relative; display: flex; flex-direction: column;
  gap: var(--space-5); min-width: 0;
}
.top-story-media { border-radius: var(--radius-lg); overflow: hidden; border: 1px solid var(--color-border); }
.top-story-media img { width: 100%; height: 100%; object-fit: cover; display: block; filter: var(--photo-grade); }
.top-story-body { display: flex; flex-direction: column; gap: var(--space-4); }
.top-story-kicker {
  display: flex; gap: var(--space-2); align-items: center; margin: 0;
  font-size: 0.78rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.12em; color: var(--color-gold-text);
}
.top-story-headline {
  font-family: var(--font-display); font-optical-sizing: auto;
  font-weight: 640; letter-spacing: -0.01em; line-height: 1.08;
  font-size: clamp(1.9rem, 3.4vw, 3rem);
  margin: 0; text-wrap: balance;
}
.top-story-headline a { color: inherit; text-decoration: none; }
.top-story-headline a:hover { color: var(--color-accent); }
.top-story-excerpt { color: var(--color-muted); font-size: 1.1rem; line-height: 1.6; margin: 0; max-width: 62ch; }
.top-story-meta {
  display: flex; flex-wrap: wrap; gap: var(--space-2); margin: 0;
  font-size: 0.85rem; color: var(--color-muted);
}
.top-story-meta span + span::before { content: "\00B7"; margin-right: var(--space-2); }
.top-story-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-4); margin-top: var(--space-2); }

/* --- Coin chips: symbol-first links to the coin pages. --- */
.coin-chips { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.coin-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 12px; border-radius: 999px;
  border: 1px solid var(--color-border); background: var(--color-surface);
  color: var(--color-muted); font-size: 0.8rem; text-decoration: none;
  transition: border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.coin-chip strong { color: var(--color-foreground); font-weight: 700; }
.coin-chip:hover { border-color: var(--color-accent); color: var(--color-foreground); }

/* ===================================================================
   Archive layout: main column beside the rail
   =================================================================== */
.archive-layout { display: grid; gap: var(--space-8); align-items: start; }
@media (min-width: 1024px) { .archive-layout { grid-template-columns: minmax(0, 1fr) 280px; } }
.archive-main { min-width: 0; }
.archive-main .featured-section { margin-bottom: var(--space-8); }

/* Two columns beside the rail: bigger cards beat three cramped ones. */
.news-grid-rail { grid-template-columns: 1fr; }
@media (min-width: 700px) { .news-grid-rail { grid-template-columns: repeat(2, 1fr); } }

.news-rail { display: none; flex-direction: column; gap: var(--space-5); position: sticky; top: 90px; }
@media (min-width: 1024px) { .news-rail { display: flex; } }
.rail-panel {
  border: 1px solid var(--color-border); border-radius: var(--radius-md);
  background: var(--color-surface); padding: var(--space-5);
}
.rail-title {
  font-family: var(--font-sans); font-size: 0.75rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.08em; color: var(--color-muted);
  margin: 0 0 var(--space-3);
}
.rail-list { list-style: none; margin: 0; padding: 0; }
.rail-list li + li { border-top: 1px solid var(--color-border); }
.rail-list a {
  display: block; padding-block: var(--space-2);
  color: var(--color-foreground); text-decoration: none; font-size: 0.92rem; font-weight: 600;
}
.rail-list a:hover { color: var(--color-accent); }
.rail-list a.is-active { color: var(--color-gold-text); }
.rail-note { color: var(--color-muted); font-size: 0.85rem; line-height: 1.5; margin: 0 0 var(--space-3); }
.rail-cta { font-size: 0.88rem; font-weight: 700; color: var(--color-accent); text-decoration: none; }
.rail-cta:hover { text-decoration: underline; }

/* The pills strip stands in for the rail below 1024px, and hides above. */
.mobile-rail-strip { display: block; width: 100%; }
@media (min-width: 1024px) { .mobile-rail-strip { display: none; } }

/* ===================================================================
   Breadcrumbs and the freshness line
   =================================================================== */
.breadcrumbs {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2);
  font-size: 0.8rem; color: var(--color-muted);
}
.archive-intro .breadcrumbs { justify-content: center; }
.breadcrumbs a { color: var(--color-muted); text-decoration: none; }
.breadcrumbs a:hover { color: var(--color-foreground); }
.breadcrumbs [aria-current] { color: var(--color-foreground); }
.crumb-sep { opacity: 0.5; }
.article-section .breadcrumbs { margin-bottom: var(--space-4); }

.updated-line {
  display: inline-flex; align-items: center; gap: var(--space-2); margin: 0;
  font-size: 0.8rem; color: var(--color-muted);
  font-variant-numeric: tabular-nums;
}

/* ===== Comparison tables in long-form pages =====
   The guide pages carry real comparison tables. Header row in the small-caps
   style the site uses for labels; the wrapper scrolls sideways on phones so
   a six-column table never squeezes the page. */
.table-scroll { overflow-x: auto; margin-bottom: var(--space-6); -webkit-overflow-scrolling: touch; }
.table-scroll table { margin-bottom: 0; min-width: 640px; }
.article-body th {
  font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--color-muted); font-weight: 700;
}
.article-body td { font-size: 0.95rem; line-height: 1.5; vertical-align: top; }
.article-body td strong { white-space: nowrap; }
.article-body tbody tr:hover { background: var(--color-surface); }

/* ===== Guide chrome =====
   The trust furniture every /guides/ page gets from the template: byline
   with a last-checked date, the "In this guide" jump menu built from the
   page's own h2s, and the how-we-made-this box at the end. Everything uses
   theme variables so it follows light/dark and any palette experiment. */
.guide-meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem;
  margin: calc(-1 * var(--space-4)) 0 var(--space-6);
  font-size: 0.9rem; color: var(--color-muted);
}
.guide-meta a { color: var(--color-primary); text-decoration: none; }
.guide-meta a:hover { text-decoration: underline; }
.guide-meta-sep { opacity: 0.5; }

/* The guide jump menu reuses the coin pages' .coin-jump strip wholesale —
   its rules live with the coin styles. Only the anchor offset is ours. */
.article-body h2[id] { scroll-margin-top: 90px; }

/* Update log + author box share the trust box's look, lighter. */
.guide-updates, .guide-author {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  padding: var(--space-5) var(--space-6);
  margin-top: var(--space-5);
}
.guide-updates ul { margin: 0; padding: 0; list-style: none; }
.guide-updates li { font-size: 0.92rem; color: var(--color-muted); margin-bottom: var(--space-2); }
.guide-updates li strong { color: var(--color-foreground); font-weight: 600; }
.guide-author p { font-size: 0.92rem; color: var(--color-muted); margin: 0; }
.guide-author p strong { color: var(--color-foreground); }

/* Verdict cards: the two big squares at the top of a comparison page, each
   naming a winner for one job — "Best for beginners: Coinbase" beside "Best
   for security: Kraken". The prose still argues the case; these state it. */
.verdict-cards {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4);
  margin: var(--space-6) 0;
}
@media (max-width: 640px) { .verdict-cards { grid-template-columns: 1fr; } }
.verdict-card {
  border: 1px solid var(--color-border);
  border-top: 3px solid var(--color-primary);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  padding: var(--space-5) var(--space-6);
}
.verdict-card .verdict-label {
  display: block; font-size: 0.7rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--color-primary); margin-bottom: var(--space-2);
}
.article-body .verdict-card h3 {
  margin: 0 0 var(--space-2); font-size: 1.35rem;
}
.article-body .verdict-card p {
  font-size: 0.92rem; color: var(--color-muted); margin: 0;
}

/* Homepage guides band: one editorial shelf, three named cards. */
.guides-band { margin-block: var(--space-8); }
.guides-band-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--space-4); margin-bottom: var(--space-5);
}
.guides-band-head h2 { font-family: var(--font-serif, inherit); font-size: 1.5rem; margin: 0; }
.guides-band-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-4);
}
@media (max-width: 820px) { .guides-band-grid { grid-template-columns: 1fr; } }
.guides-band-card {
  display: flex; flex-direction: column; gap: var(--space-2);
  border: 1px solid var(--color-border); border-radius: var(--radius-lg);
  background: var(--color-surface); padding: var(--space-5);
  text-decoration: none; color: var(--color-foreground);
  transition: border-color var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}
.guides-band-card:hover { border-color: var(--color-accent); transform: translateY(-2px); }
.guides-band-card h3 { margin: 0; font-size: 1.05rem; }
.guides-band-card p { margin: 0; font-size: 0.9rem; color: var(--color-muted); flex-grow: 1; }
.guides-band-checked {
  font-size: 0.72rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--color-primary);
}

/* "Full review →" under a platform's name in a comparison table. */
.article-body .row-review-link {
  font-size: 0.78rem; font-weight: 600; text-decoration: none;
  color: var(--color-primary); white-space: nowrap;
}
.article-body .row-review-link:hover { text-decoration: underline; }

.guides-band-more { margin: var(--space-4) 0 0; font-size: 0.92rem; color: var(--color-muted); }
.guides-band-more a { color: var(--color-primary); text-decoration: none; font-weight: 600; }
.guides-band-more a:hover { text-decoration: underline; }

/* Hub decks: the guides and reviews hubs render their children as cards. */
.hub-deck { margin-top: var(--space-7); }
.hub-deck h2 { font-size: 1.3rem; margin-bottom: var(--space-2); }
.hub-deck-note { font-size: 0.92rem; color: var(--color-muted); margin-bottom: var(--space-4); }
/* Inside the article body every link is gold and underlined; a whole card is
   a link, so its heading and text have to be told they are not. */
.article-body .hub-deck .guides-band-card { text-decoration: none; color: var(--color-foreground); }
.article-body .hub-deck .guides-band-card h3 { margin: 0; font-size: 1.05rem; color: var(--color-foreground); }
.article-body .hub-deck .guides-band-card:hover h3 { color: var(--color-primary); }
.article-body .hub-deck .guides-band-card p { margin: 0; font-size: 0.9rem; color: var(--color-muted); }

/* Head-to-head links on a platform review. */
.versus-strip {
  border: 1px solid var(--color-border); border-radius: var(--radius-lg);
  background: var(--color-surface); padding: var(--space-5) var(--space-6);
  margin-top: var(--space-6);
}
.versus-links { display: flex; flex-wrap: wrap; gap: var(--space-4); }
.article-body .versus-strip a { color: var(--color-primary); text-decoration: none; font-weight: 600; }
.article-body .versus-strip a:hover { text-decoration: underline; }

/* "Buying X in the UK" card on every coin page. */
.coin-buy { margin-block: var(--space-7); }
.coin-buy-card {
  border: 1px solid var(--color-border); border-left: 3px solid var(--color-primary);
  border-radius: var(--radius-lg); background: var(--color-surface);
  padding: var(--space-5) var(--space-6);
}
.coin-buy-card p { font-size: 0.95rem; color: var(--color-muted); margin: var(--space-2) 0 var(--space-3); }
.coin-buy-cta { display: inline-block; font-weight: 700; color: var(--color-primary); text-decoration: none; }
.coin-buy-cta:hover { text-decoration: underline; }
.coin-buy-reviews {
  display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: baseline;
  margin-top: var(--space-4); padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
  font-size: 0.88rem;
}
.coin-buy-reviews span { color: var(--color-muted); font-weight: 600; }
.coin-buy-reviews a { color: var(--color-foreground); text-decoration: none; }
.coin-buy-reviews a:hover { color: var(--color-primary); text-decoration: underline; }

/* "Go deeper" card at the foot of every article: one guide or review. */
.go-deeper {
  border: 1px solid var(--color-border); border-left: 3px solid var(--color-primary);
  border-radius: var(--radius-lg); background: var(--color-surface);
  padding: var(--space-5) var(--space-6); margin-top: var(--space-6);
}
.go-deeper-link {
  display: block; font-weight: 700; font-size: 1.02rem;
  color: var(--color-foreground); text-decoration: none; margin-bottom: var(--space-2);
}
.go-deeper-link:hover { color: var(--color-primary); }
.go-deeper p { margin: 0; font-size: 0.9rem; color: var(--color-muted); }

/* Wirecutter-style pick chips for table rows: a small gold label that marks
   the fact-based pick ("Budget pick", "Most headroom"). Used inline in guide
   and review tables. */
.pick-chip {
  display: inline-block; padding: 2px 9px; border-radius: 999px;
  font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
  background: var(--color-primary); color: var(--color-primary-foreground);
  white-space: nowrap; vertical-align: middle; margin-left: 6px;
}
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

.guide-trust {
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-primary);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  padding: var(--space-5) var(--space-6);
  margin-top: var(--space-8);
}
.guide-trust-title {
  display: block; font-size: 0.75rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--color-primary); margin-bottom: var(--space-3);
}
.guide-trust p { font-size: 0.92rem; color: var(--color-muted); margin-bottom: var(--space-3); }
.guide-trust p:last-child { margin-bottom: 0; }
.guide-trust a { color: var(--color-primary); }

/* ===================================================================
   GOLD THEME EXPERIMENT — delete this entire block to restore purple.
   ===================================================================
   Faeren, 17 Aug 2026: light mode trades its purple accents for the
   logo's gold; dark mode becomes black and gold. Everything is an
   override on top of the purple design, appended last so it wins by
   order. Nothing above this block was touched.
   =================================================================== */

/* ---- Dark: black and gold ---- */
:root {
  --color-bg: #0a0a08;
  --color-bg-deep: #050504;
  --color-bg-elevated: #16130b;
  --color-foreground: #f5f1e6;
  --color-muted: #b5a988;
  --color-primary: #d4a853;
  --color-primary-light: #e6c069;
  --color-primary-foreground: #191307;
  --color-accent: #dfb968;
}.btn-primary { box-shadow: 0 8px 24px -8px rgba(212, 168, 83, 0.45); }
.btn-primary:hover { box-shadow: 0 10px 28px -6px rgba(212, 168, 83, 0.55); }.featured-card:hover, .news-card:hover, .coin-card:hover, .parallax-card:hover { border-color: rgba(212, 168, 83, 0.4); }
.featured-thumb, .card-thumb { background: linear-gradient(135deg, var(--thumb-a, #8a6a1f), var(--thumb-b, #d4a853)); }
.featured-eyebrow::before { background: var(--color-accent); box-shadow: 0 0 0 3px rgba(212, 168, 83, 0.25); }
.card-tag { background: rgba(212, 168, 83, 0.14); }
.news-card.sponsored { border-color: rgba(138, 106, 31, 0.4); background: rgba(138, 106, 31, 0.1); }
.news-card.sponsored .card-tag { background: rgba(212, 168, 83, 0.16); }
.newsletter-card { background: linear-gradient(135deg, rgba(138, 106, 31, 0.16), rgba(212, 168, 83, 0.08)); }

/* ---- Light: paper and gold ---- */
html[data-theme="light"] {
  --color-foreground: #211a0e;
  --color-muted: #675c48;
  --color-primary: #8a6a1f;
  --color-primary-light: #a3822e;
  --color-primary-foreground: #ffffff;
  --color-accent: #8a6a1f;
  --color-surface: rgba(33, 26, 14, 0.04);
  --color-surface-hover: rgba(33, 26, 14, 0.08);
  --color-border: rgba(33, 26, 14, 0.13);
}
html[data-theme="light"] .btn-primary { box-shadow: 0 8px 24px -8px rgba(138, 106, 31, 0.4); }
html[data-theme="light"] .btn-primary:hover { box-shadow: 0 10px 28px -6px rgba(138, 106, 31, 0.5); }html[data-theme="light"] .card-tag { background: rgba(138, 106, 31, 0.12); }
html[data-theme="light"] .newsletter-card { background: linear-gradient(135deg, rgba(138, 106, 31, 0.10), rgba(200, 154, 63, 0.06)); }

/* The article's "short version" box carried its own purple wash as a
   literal, so the token switch missed it. Gold wash works on both schemes:
   a warm tint over black and over paper alike. */
.article-body .cb-short,
.article-body .is-style-cb-short {
  background: rgba(212, 168, 83, 0.10);
  border-color: rgba(212, 168, 83, 0.32);
}

/* ================== end GOLD THEME EXPERIMENT ================== */

/* A delayed price says so, in the site's warning colour rather than silently. */
[data-coin-updated].is-stale { color: var(--color-primary); font-weight: 600; }

/* ---------------------------------------------------------------------------
   Cookie consent
   A bar, not a blocker. It sits at the bottom, does not cover the article, and
   gives Decline exactly the same weight as Accept — a decline that is harder
   to find than the accept is the specific thing the ICO rules out.
--------------------------------------------------------------------------- */
.cb-consent {
  position: fixed;
  z-index: 900;
  left: var(--space-4);
  right: var(--space-4);
  bottom: var(--space-4);
  margin-inline: auto;
  max-width: 760px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-bg-elevated);
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.45);
  color: var(--color-foreground);
  /* Hidden until the script decides this reader has not chosen yet, so it
     never flashes at someone who settled the question weeks ago. */
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.25s ease, transform 0.25s ease;
  pointer-events: none;
}

.cb-consent.is-visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.cb-consent-text {
  flex: 1 1 300px;
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--color-muted);
}

.cb-consent-text a {
  color: var(--color-gold-text);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.cb-consent-actions {
  display: flex;
  gap: var(--space-3);
  flex: 0 0 auto;
}

.cb-consent button {
  font-family: var(--font-sans);
  font-size: 0.9rem;
  font-weight: 600;
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.cb-consent .cb-consent-accept {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-primary-foreground);
}

.cb-consent .cb-consent-accept:hover { background: var(--color-primary-light); border-color: var(--color-primary-light); }

.cb-consent .cb-consent-decline {
  background: var(--color-surface);
  color: var(--color-foreground);
}

.cb-consent .cb-consent-decline:hover { background: var(--color-surface-hover); }

.cb-consent button:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

@media (max-width: 560px) {
  .cb-consent { padding: var(--space-4); gap: var(--space-3); }
  .cb-consent-actions { width: 100%; }
  .cb-consent-actions button { flex: 1 1 0; }
}

@media (prefers-reduced-motion: reduce) {
  .cb-consent { transition: none; transform: none; }
}

/* ---------------------------------------------------------------------------
   Support page
   The QR codes are inline SVG using currentColor, so they invert with the
   theme rather than sitting in a white box on a black page.
--------------------------------------------------------------------------- */
.cb-donate {
  display: flex;
  gap: var(--space-5);
  align-items: flex-start;
  padding: var(--space-5);
  margin: 0 0 var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.cb-donate-qr {
  flex: 0 0 132px;
  line-height: 0;
  color: var(--color-foreground);
}

.cb-donate-qr .cb-qr { width: 132px; height: 132px; display: block; }

.cb-donate-body { flex: 1 1 auto; min-width: 0; }

.cb-donate-body h3 { margin: 0 0 var(--space-2); font-size: 1.05rem; }

.cb-donate-note {
  margin: 0 0 var(--space-3);
  font-size: 0.9rem;
  color: var(--color-muted);
  line-height: 1.5;
}

/* The address must be selectable, unambiguous and never silently truncated:
   a half-copied address is a donation sent to nobody. */
.cb-donate-addr { margin: 0; }

.cb-donate-addr code {
  display: block;
  padding: var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--color-bg-deep);
  border: 1px solid var(--color-border);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.82rem;
  line-height: 1.5;
  word-break: break-all;
  user-select: all;
}

/* The selector carries .article-body deliberately. Page content is styled by
   `.article-body a { color: var(--color-accent) }`, which is more specific
   than a bare `.cb-kofi` and was winning: gold text on a gold button, 1.18:1
   in dark and 1.00:1 in light, where the two colours are identical and the
   label vanished completely. This is why a button inside prose needs to out-
   specify the prose link rule, not merely come after it. */
.cb-kofi,
.article-body a.cb-kofi {
  display: inline-block;
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-sm);
  background: var(--color-primary);
  color: var(--color-primary-foreground);
  font-weight: 600;
  text-decoration: none;
}

.cb-kofi:hover,
.article-body a.cb-kofi:hover {
  background: var(--color-primary-light);
  color: var(--color-primary-foreground);
}

.cb-donate-warning {
  padding: var(--space-4);
  border-radius: var(--radius-sm);
  border: 1px solid rgba(212, 168, 83, 0.32);
  background: rgba(212, 168, 83, 0.08);
  font-size: 0.92rem;
  line-height: 1.6;
}

@media (max-width: 560px) {
  .cb-donate { flex-direction: column; gap: var(--space-4); }
  .cb-donate-qr { flex: 0 0 auto; align-self: center; }
}

/* ---------------------------------------------------------------------------
   End-of-article support block
   One per page, at the end, and nowhere else. Quiet enough that it does not
   undo the "no ads, no paywall" claim it is making.
--------------------------------------------------------------------------- */
.cb-support {
  margin: var(--space-8) 0 0;
  padding: var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.cb-support-lead {
  margin: 0 0 var(--space-4);
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--color-muted);
}

.cb-support-lead strong { color: var(--color-foreground); }

.cb-support-actions { margin: 0; display: flex; flex-wrap: wrap; gap: var(--space-3); }

/* Out-specifies `.article-body a`, which sets the prose link colour and would
   otherwise win and paint the label the same gold as the button. */
.cb-support .cb-support-btn,
.article-body ~ .cb-support .cb-support-btn {
  display: inline-block;
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-sm);
  background: var(--color-primary);
  color: var(--color-primary-foreground);
  font-size: 0.92rem;
  font-weight: 600;
  text-decoration: none;
  border: 1px solid var(--color-primary);
}

.cb-support .cb-support-btn:hover { background: var(--color-primary-light); border-color: var(--color-primary-light); }

.cb-support .cb-support-btn-alt {
  background: transparent;
  color: var(--color-foreground);
  border-color: var(--color-border);
}

.cb-support .cb-support-btn-alt:hover { background: var(--color-surface-hover); }

@media (max-width: 480px) {
  .cb-support-actions { flex-direction: column; }
  .cb-support .cb-support-btn { text-align: center; }
}

/* ---------------------------------------------------------------------------
   Support dialog
--------------------------------------------------------------------------- */
.cb-modal { position: fixed; inset: 0; z-index: 950; display: grid; place-items: center; padding: var(--space-4); }
.cb-modal[hidden] { display: none; }

.cb-modal-backdrop {
  position: absolute; inset: 0;
  background: rgba(0, 0, 0, 0.62);
  opacity: 0; transition: opacity 0.2s ease;
}

.cb-modal-panel {
  position: relative;
  width: 100%; max-width: 420px;
  padding: var(--space-6);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-bg-elevated);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
  opacity: 0; transform: translateY(10px) scale(0.98);
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.cb-modal.is-open .cb-modal-backdrop { opacity: 1; }
.cb-modal.is-open .cb-modal-panel { opacity: 1; transform: none; }

.cb-modal-panel h2 { margin: 0 0 var(--space-3); font-size: 1.3rem; }

.cb-modal-lead {
  margin: 0 0 var(--space-5);
  font-size: 0.92rem; line-height: 1.6;
  color: var(--color-muted);
}

/* Out-specifies .article-body a, which would otherwise paint the label the
   same gold as the button. Same bug as the Ko-fi button on the support page. */
.cb-modal .cb-modal-primary,
.article-body ~ * .cb-modal .cb-modal-primary {
  display: block; text-align: center;
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-sm);
  background: var(--color-primary);
  color: var(--color-primary-foreground);
  font-weight: 700; font-size: 1rem;
  text-decoration: none;
}

.cb-modal .cb-modal-primary:hover { background: var(--color-primary-light); }

.cb-modal-alt {
  margin: var(--space-4) 0 0;
  text-align: center;
  font-size: 0.88rem;
  color: var(--color-muted);
}

.cb-modal .cb-modal-alt a { color: var(--color-gold-text); text-decoration: underline; text-underline-offset: 2px; }

.cb-modal-x {
  position: absolute; top: var(--space-3); right: var(--space-3);
  width: 32px; height: 32px;
  border: 0; border-radius: 50%;
  background: transparent;
  color: var(--color-muted);
  font-size: 1.5rem; line-height: 1;
  cursor: pointer;
}

.cb-modal-x:hover { background: var(--color-surface-hover); color: var(--color-foreground); }
.cb-modal-x:focus-visible, .cb-modal a:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  .cb-modal-backdrop, .cb-modal-panel { transition: none; }
}

/* ------------------------------------------------------------ buy box --- */
/* Gold is the tell. Editorial links on this site are purple; every link that
   earns us money is gold, so a reader who clocks that once can see which is
   which without reading a word of small print. That is a stronger disclosure
   than any footer, and it costs nothing to maintain. */

.cb-buy-group { margin: var(--space-8) 0; }
.cb-buy-note {
  margin: 0 0 var(--space-3); font-size: 0.94rem; font-weight: 600;
  color: var(--color-foreground);
}
.cb-buy-row { display: grid; gap: var(--space-4); }
@media (min-width: 620px) {
  .cb-buy-group.is-pair .cb-buy-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.cb-buy {
  display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-5); border-radius: var(--radius-md);
  background: var(--color-bg-elevated);
  border: 1px solid var(--color-border);
}
/* Only the paid box takes the gold edge. The unpaid one sits beside it looking
   deliberately plainer, which is the point: on a comparison page the
   difference between the two boxes is the disclosure. */
.cb-buy.is-paid { border-color: color-mix(in srgb, var(--color-gold) 42%, transparent); }

.cb-buy-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
.cb-buy-name {
  font-family: var(--font-display); font-weight: 600; font-size: 1.15rem;
  line-height: 1.2; color: var(--color-foreground);
}
.cb-ad {
  flex-shrink: 0; font-size: 0.62rem; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; padding: 3px 8px; border-radius: 5px;
  background: var(--color-gold); color: #0c0414;
}
html[data-theme="light"] .cb-ad { color: #231600; }

.cb-buy-blurb { margin: 0; font-size: 0.92rem; line-height: 1.55; color: var(--color-muted); }

.cb-buy-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3); margin-top: auto; padding-top: var(--space-2);
}
.cb-buy-price {
  font-size: 1.05rem; font-weight: 700; color: var(--color-foreground);
  font-variant-numeric: tabular-nums;
}
/* Specificity note: .article-body a wins over a bare .cb-buy-btn, which is how
   the Ko-fi button ended up invisible. Scoped here so it cannot happen again. */
.cb-buy-btn,
.article-body .cb-buy-btn {
  display: inline-block; text-decoration: none; white-space: nowrap;
  font-size: 0.92rem; font-weight: 600; padding: 10px 16px;
  border-radius: var(--radius-sm);
  background: var(--color-gold); color: #0c0414; border: 1px solid transparent;
  transition: filter 0.12s ease, transform 0.12s ease;
}
html[data-theme="light"] .cb-buy-btn,
html[data-theme="light"] .article-body .cb-buy-btn { color: #231600; }
.cb-buy-btn:hover { filter: brightness(1.07); transform: translateY(-1px); }
.cb-buy-btn:focus-visible { outline: 2px solid var(--color-foreground); outline-offset: 3px; }

.cb-buy-btn.is-plain,
.article-body .cb-buy-btn.is-plain {
  background: transparent; color: var(--color-muted); border-color: var(--color-border);
}
.cb-buy-btn.is-plain:hover { background: var(--color-surface); filter: none; }

.cb-buy-disclosure {
  margin: var(--space-3) 0 0; font-size: 0.8rem; line-height: 1.5;
  color: var(--color-muted);
}
.cb-buy-disclosure a { color: inherit; text-underline-offset: 2px; }

/* ------------------------------------------------------ article rail --- */
/* The article keeps its 720px measure — reading width is not negotiable — and
   the rail sits beside it, so the pair is wider than the old single column but
   the line length is identical. Below 1024px the rail moves under the article,
   because most readers are on a phone and that is where the route from a news
   story to a guide matters most. */

.article-layout { display: grid; gap: var(--space-8); align-items: start; }
.article-layout > .article-section { min-width: 0; max-width: 720px; padding-inline: 0; }
@media (min-width: 1024px) {
  .article-layout { grid-template-columns: minmax(0, 720px) 280px; justify-content: center; }
}
/* The rail is display:none under 1024px for the archive pages. On an article it
   should still be reachable, so it is shown and laid out as cards instead. */
@media (max-width: 1023px) {
  .article-layout .news-rail { display: flex; position: static; }
  /* Sections duplicate the header nav on a phone; guides and reviews do not. */
  .article-layout .news-rail .rail-panel:first-child { display: none; }
}

/* An odd item at the end of a 2-up group used to sit alone at half width,
   which read as a rendering mistake. Full width reads as a footnote row. */
.cb-buy-group.is-pair .cb-buy:last-child:nth-child(odd) { grid-column: 1 / -1; }

/* ----------------------------------------------------------- glossary --- */
/* A marked term is a button dressed as text with a dotted underline in the
   ordinary text colour. Not purple and not gold, deliberately: purple links
   are editorial and gold links earn us money, and a definition is neither. */

.cb-term {
  all: unset; font: inherit; color: inherit; cursor: help;
  border-bottom: 1px dotted color-mix(in srgb, var(--color-muted) 75%, transparent);
  padding-bottom: 1px;
}
.cb-term:hover, .cb-term[aria-expanded="true"] { border-bottom-style: solid; border-bottom-color: var(--color-muted); }
.cb-term:focus-visible { outline: 2px solid var(--color-primary-light); outline-offset: 2px; border-radius: 2px; }

.cb-term-card {
  position: absolute; z-index: 70;
  background: var(--color-bg-elevated); border: 1px solid var(--color-border);
  border-radius: var(--radius-md); padding: var(--space-4) var(--space-5);
  box-shadow: 0 10px 32px rgba(0, 0, 0, 0.35);
  font-size: 0.9rem; line-height: 1.55;
}
html[data-theme="light"] .cb-term-card { box-shadow: 0 10px 28px rgba(26, 16, 38, 0.16); }
.cb-term-card strong {
  display: block; font-family: var(--font-sans); font-size: 0.72rem; font-weight: 700;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--color-gold-text);
  margin-bottom: var(--space-2);
}
.cb-term-card p { margin: 0; color: var(--color-foreground); }
.cb-term-card .cb-term-eg { margin-top: var(--space-2); color: var(--color-muted); font-style: italic; }

/* Role labels and table-cell buy links, per the PCMag/Wirecutter pass. */
.cb-buy-role {
  display: block; font-size: 0.66rem; font-weight: 700; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--color-muted); margin-bottom: var(--space-2);
}
.cb-buy-cell {
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
  font-size: 0.8rem; font-weight: 600; text-decoration: none;
  padding: 5px 10px; border-radius: 7px;
  background: var(--color-gold); color: #0c0414;
}
html[data-theme="light"] .cb-buy-cell { color: #231600; }
.cb-buy-cell:hover { filter: brightness(1.07); }
.cb-buy-cell.is-plain {
  background: transparent; color: var(--color-muted);
  border: 1px solid var(--color-border);
}
.cb-buy-cell.is-plain:hover { background: var(--color-surface); filter: none; }
.cb-ad-mini { font-size: 0.5rem; padding: 1px 4px; border-radius: 3px; }

/* The picks strip: the answers, at the top, compactly. */
.cb-picks { display: grid; gap: var(--space-3); margin: var(--space-5) 0 var(--space-6); }
@media (min-width: 640px) { .cb-picks { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.cb-pick {
  display: flex; flex-direction: column; gap: 5px; align-items: flex-start;
  padding: var(--space-4); border-radius: var(--radius-md);
  background: var(--color-bg-elevated); border: 1px solid var(--color-border);
}
.cb-pick-name { font-family: var(--font-display); font-weight: 600; font-size: 1.02rem; line-height: 1.2; color: var(--color-foreground); }
.cb-pick-price { font-size: 0.85rem; color: var(--color-muted); font-variant-numeric: tabular-nums; }
.cb-pick .cb-buy-cell { margin-top: 4px; }

/* ---------------------------------------------------------- masthead --- */
/* The front page opens like a paper now: wordmark, date, motto, one gold
   rule. The rule is the same gradient the share cards end with, so the page
   a shared link opens matches the card that was shared. Real readers called
   the old animated hero machine-made, and the fix is the oldest design on
   earth: a masthead. */

.masthead {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: var(--space-2); padding: var(--space-8) 0 var(--space-4);
}
.masthead-date {
  margin: 0; font-size: 0.76rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--color-muted);
}
.masthead-title {
  margin: 0; font-size: clamp(2.5rem, 7vw, 4.1rem); font-weight: 800;
  letter-spacing: 0.045em; line-height: 1; color: var(--color-foreground);
}
.masthead-title b { color: var(--color-gold-text); }
.masthead-motto {
  margin: 0; font-family: var(--font-display); font-style: italic;
  font-size: clamp(0.95rem, 2vw, 1.12rem); color: var(--color-muted);
}
.masthead-goldrule {
  width: min(340px, 62%); height: 3px; margin-top: var(--space-3); border-radius: 2px;
  background: linear-gradient(90deg, transparent, var(--color-gold) 30%, var(--color-gold) 70%, transparent);
}
@media (max-width: 640px) { .masthead { padding-top: var(--space-6); } }

/* Phones read the top story first, then the list. The DOM keeps the list
   first for the desktop grid, so this is a layout decision, not an accident
   of shrinking — the checklist's point seven. */
@media (max-width: 1023px) {
  .frontpage-grid { display: flex; flex-direction: column; }
  .frontpage-grid .live-list { order: 2; }
}

/* Ticker items are links now. Inherit everything, glow the symbol on hover,
   and never wrap mid-item while drifting. */
a.ticker-item { color: inherit; text-decoration: none; border-radius: var(--radius-sm); }
a.ticker-item:hover .ticker-symbol { color: var(--color-gold-text); }
a.ticker-item:focus-visible { outline: 2px solid var(--color-primary-light); outline-offset: 3px; }
.ticker-track { overscroll-behavior-x: contain; }


/* Prose links: ink with an underline. Gold is reserved for links that earn. */
.article-body a,
.page-lede a,
.guide-trust a {
  color: var(--color-foreground);
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--color-muted) 55%, transparent);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
.article-body a:hover,
.page-lede a:hover,
.guide-trust a:hover {
  text-decoration-color: var(--color-foreground);
}

/* ================================================================
   POLISH LAYER — the invisible details pass, September 2026.
   Faeren asked for the card entrance back and for the site to stop
   feeling basic. Every rule here follows the same tests: does it
   answer the reader or the page, does it run on the GPU, does it
   respect reduced motion, and would a designer nod rather than
   roll their eyes.
   ================================================================ */

/* Card entrance, restored and tuned. It was 14px of travel at 250ms on
   everything; now 8px, only for readers who accept motion, with the 40ms
   stagger the JS already provides. Fast, short, once. */
@media (prefers-reduced-motion: no-preference) {
  .news-card {
    opacity: 0;
    transform: translateY(8px);
    transition: opacity 300ms var(--ease-out), transform 300ms var(--ease-out),
      background var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out);
  }
  .news-card.is-visible { opacity: 1; transform: translateY(0); }
  .news-card.is-visible:hover { transform: translateY(-3px); }
}

/* Everything pressable presses. The scale is the interface saying "heard". */
.btn:active,
.cb-buy-btn:active,
.cb-buy-cell:active,
a.ticker-item:active,
.guides-band-card:active { transform: scale(0.97); }

/* Text selection in house colours — a detail seen a hundred times a week. */
::selection { background: var(--color-gold); color: #191307; }

/* The ticker's ends dissolve instead of chopping mid-coin. */
.ticker-track {
  mask-image: linear-gradient(90deg, transparent, #000 36px, #000 calc(100% - 36px), transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 36px, #000 calc(100% - 36px), transparent);
}

/* Pages cross-fade into each other instead of flashing white. Free with the
   platform, and the single biggest "this site is finished" signal there is. */
@view-transition { navigation: auto; }
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

/* The masthead's one moment: on arrival the gold rule draws itself in and
   the lines settle. Load-time only, once per visit, skipped for reduced
   motion. Rare frequency is where delight is allowed to live. */
@media (prefers-reduced-motion: no-preference) {
  .masthead-date, .masthead-title, .masthead-motto {
    animation: masthead-settle 480ms var(--ease-out) backwards;
  }
  .masthead-title { animation-delay: 60ms; }
  .masthead-motto { animation-delay: 120ms; }
  .masthead-goldrule {
    transform-origin: center;
    animation: masthead-rule 560ms var(--ease-out) 200ms backwards;
  }
}
@keyframes masthead-settle {
  from { opacity: 0; transform: translateY(6px); }
}
@keyframes masthead-rule {
  from { transform: scaleX(0); }
}

/* Lead images breathe on hover — pointer-answering motion, mouse only. */
.top-story-media img, .featured-thumb-img img {
  transition: transform 600ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .top-story:hover .top-story-media img,
  .featured-card:hover .featured-thumb-img img { transform: scale(1.02); }
  .guides-band-card { transition: transform 200ms var(--ease-out), border-color 200ms var(--ease-out); }
  .guides-band-card:hover { transform: translateY(-3px); }
}

/* ------------------------------------------------- story tiers --- */
/* The middle weight between the lead and the grid, and the labels that
   give each band of the page a name. Four sizes on a page is what
   separates a front page from wallpaper. */

.story-row { display: grid; gap: var(--space-5); margin-top: var(--space-6); }
@media (min-width: 720px) { .story-row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.story-med {
  position: relative; display: grid; grid-template-columns: 168px minmax(0, 1fr);
  gap: var(--space-4); align-items: center;
  padding: var(--space-3); border-radius: var(--radius-md);
  border: 1px solid transparent;
  transition: background var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .story-med:hover { background: var(--color-surface); border-color: var(--color-border); }
  .story-med:hover .story-med-headline { color: var(--color-gold-text); }
}
.story-med-link { position: absolute; inset: 0; z-index: 1; border-radius: inherit; }
.story-med-thumb {
  aspect-ratio: 3 / 2; border-radius: var(--radius-sm); overflow: hidden;
  border: 1px solid var(--color-border);
}
.story-med-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; filter: var(--photo-grade); }
.story-med-body { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.story-med-kicker {
  font-size: 0.68rem; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--color-gold-text);
}
.story-med-headline {
  margin: 0; font-family: var(--font-display); font-weight: 600;
  font-size: 1.12rem; line-height: 1.25; letter-spacing: -0.005em;
  color: var(--color-foreground); transition: color var(--dur-fast) var(--ease-out);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.story-med-time { font-size: 0.78rem; color: var(--color-muted); font-variant-numeric: tabular-nums; }
@media (max-width: 480px) {
  .story-med { grid-template-columns: 108px minmax(0, 1fr); }
  .story-med-headline { font-size: 1rem; -webkit-line-clamp: 3; }
}

/* The band label: small caps, then a hairline to the edge. A page whose
   sections have names reads as edited; one long scroll does not. */
.section-kicker {
  display: flex; align-items: center; gap: var(--space-4);
  margin-bottom: var(--space-5);
}
.section-kicker span {
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--color-gold-text); white-space: nowrap;
}
.section-kicker::after { content: ""; flex: 1; height: 1px; background: var(--color-border); }

/* ------------------------------------------- editorial finish --- */
/* The second polish pass: the details that make a page read as set by a
   person. Drop caps on news, a closing mark, a reading progress line,
   markets tiles, and a footer that ends the page instead of trailing off. */

/* News articles open with a drop cap, three lines tall, in the display
   face. The oldest signal in print that somebody set this page. */
.single .article-body > p:first-of-type::first-letter {
  font-family: var(--font-display); font-weight: 640;
  font-size: 3.1em; line-height: 0.82;
  float: left; padding: 0.04em 0.12em 0 0;
  color: var(--color-foreground);
}

/* And they end with a mark, not a fade-out. */
.single .article-body::after {
  content: "◆"; display: block; text-align: center;
  color: var(--color-gold); font-size: 0.72rem; opacity: 0.85;
  margin-top: var(--space-8);
}

/* The reading progress line. Gold, two pixels, GPU-only. */
.read-progress {
  position: fixed; top: 0; left: 0; z-index: 120;
  width: 100%; height: 2px;
  background: var(--color-gold);
  transform: scaleX(0); transform-origin: left;
  pointer-events: none;
}

/* Grid card photos breathe like the leads do. */
.card-thumb { overflow: hidden; }
.card-thumb img { transition: transform 600ms var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .news-card:hover .card-thumb img { transform: scale(1.03); }
}

/* Markets band tiles. */
.markets-band { padding-block: var(--space-4) var(--space-8); }
.markets-grid { display: grid; gap: var(--space-4); grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 900px) { .markets-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.mkt-tile {
  display: flex; flex-direction: column; gap: 4px;
  padding: var(--space-5); border-radius: var(--radius-md);
  background: var(--color-bg-elevated); border: 1px solid var(--color-border);
  text-decoration: none; color: var(--color-foreground);
  transition: transform 200ms var(--ease-out), border-color 200ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .mkt-tile:hover { transform: translateY(-3px); border-color: color-mix(in srgb, var(--color-gold) 45%, transparent); }
}
.mkt-role {
  font-size: 0.66rem; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--color-muted);
}
.mkt-sym { font-weight: 800; font-size: 0.95rem; letter-spacing: 0.02em; }
.mkt-price { font-family: var(--font-display); font-weight: 620; font-size: 1.5rem; font-variant-numeric: tabular-nums; line-height: 1.1; }
.mkt-chg { font-size: 0.85rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.mkt-chg.up { color: var(--color-success); }
.mkt-chg.down { color: var(--color-danger); }
.markets-more { margin: var(--space-4) 0 0; font-size: 0.9rem; }
.markets-more a { color: var(--color-muted); text-decoration: none; }
.markets-more a:hover { color: var(--color-foreground); }

/* The newsletter card sets its invitation in the display face. */
.newsletter-card h2 { font-family: var(--font-display); font-weight: 640; letter-spacing: -0.01em; font-size: 1.9rem; }
.newsletter-form input {
  background: var(--color-bg-elevated); border: 1px solid var(--color-border);
  color: var(--color-foreground); border-radius: var(--radius-sm);
  padding: 12px 14px; min-width: 240px;
  transition: border-color var(--dur-fast) var(--ease-out);
}
.newsletter-form input:focus-visible { outline: none; border-color: var(--color-gold); }

/* The footer ends the page the way the masthead opened it: with the rule. */
.site-footer { position: relative; margin-top: var(--space-12); }
.site-footer::before {
  content: ""; position: absolute; top: -2px; left: 50%; transform: translateX(-50%);
  width: min(340px, 62%); height: 3px; border-radius: 2px;
  background: linear-gradient(90deg, transparent, var(--color-gold) 30%, var(--color-gold) 70%, transparent);
}
.footer-brand .brand-name { font-weight: 800; letter-spacing: 0.05em; }
.footer-brand .brand-name b { color: var(--color-gold-text); }
.footer-links h2 { color: var(--color-gold-text); letter-spacing: 0.12em; font-size: 0.72rem; font-weight: 700; }

/* -------------------------------------------- newsroom vitals --- */
/* The header zones stop being static: the news hero carries today's lead,
   the week's output, the daily re-check promise and the section chips on
   every screen size; the masthead carries the same pulse in one line. All
   of it reads from real content, so none of it can overclaim. */

.newsroom-meta {
  display: flex; flex-wrap: wrap; justify-content: center; align-items: center;
  gap: var(--space-2) var(--space-4); margin: 0;
  font-size: 0.85rem; color: var(--color-muted);
}
.newsroom-meta-live { display: inline-flex; align-items: center; gap: var(--space-2); }
.newsroom-meta > span + span::before {
  content: "\00B7"; margin-right: var(--space-4); color: var(--color-border);
}
.newsroom-meta > span:nth-child(2)::before { content: "\00B7"; }

.hero-rail-strip { width: 100%; margin-top: var(--space-4); }
.hero-rail-strip .filter-pills { justify-content: center; }

.masthead-live {
  display: inline-flex; align-items: center; gap: var(--space-2);
  margin: var(--space-2) 0 0; font-size: 0.82rem; color: var(--color-muted);
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------ open editorial cards --- */
/* The last structural template-tell: every story sat in a box. Boxes are
   dashboard grammar. Stories now sit open — image, kicker, headline,
   whitespace — and boxes are reserved for utilities: rails, markets
   tiles, buy boxes, the newsletter. One rule, applied everywhere:
   editorial breathes, tools have edges. */

.masthead-mark { display: block; margin-bottom: var(--space-2); }

.news-card {
  background: transparent; border: none; border-radius: 0; padding: 0;
  gap: var(--space-3);
}
@media (prefers-reduced-motion: no-preference) {
  .news-card.is-visible:hover { transform: none; }
}
.news-card:hover { background: transparent; border-color: transparent; }
.card-thumb { border-radius: var(--radius-md); border: 1px solid var(--color-border); }
.card-tag {
  background: transparent; padding: 0; border-radius: 0;
  color: var(--color-gold-text); font-size: 0.68rem;
  letter-spacing: 0.12em; font-weight: 700;
}
.card-headline { transition: color var(--dur-fast) var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .news-card:hover .card-headline { color: var(--color-gold-text); }
}
.card-meta { border-top: 1px solid var(--color-border); }

.featured-card {
  background: transparent; border: none; padding: 0; border-radius: 0;
}
.featured-card:hover { background: transparent; border-color: transparent; }
.featured-thumb { border: 1px solid var(--color-border); }
@media (hover: hover) and (pointer: fine) {
  .featured-card:hover .featured-headline { color: var(--color-gold-text); }
}
.featured-headline { transition: color var(--dur-fast) var(--ease-out); }
