/* =============================================================
   dn2about — public marketing site
   Composes DN2 design-system primitives. Tokens from dn2/tokens.css.
   New rules below extend the system for marketing layouts that
   the in-product design system does not directly cover (hero,
   public header, public footer, long-form prose).
   ============================================================= */

/* ===== Self-hosted Montserrat ===== */
@font-face { font-family: 'Montserrat'; font-style: normal; font-weight: 100; font-display: swap; src: url('/fonts/Montserrat/Montserrat-Thin.ttf') format('truetype'); }
@font-face { font-family: 'Montserrat'; font-style: normal; font-weight: 300; font-display: swap; src: url('/fonts/Montserrat/Montserrat-Light.ttf') format('truetype'); }
@font-face { font-family: 'Montserrat'; font-style: normal; font-weight: 400; font-display: swap; src: url('/fonts/Montserrat/Montserrat-Regular.ttf') format('truetype'); }
@font-face { font-family: 'Montserrat'; font-style: normal; font-weight: 500; font-display: swap; src: url('/fonts/Montserrat/Montserrat-Medium.ttf') format('truetype'); }
@font-face { font-family: 'Montserrat'; font-style: normal; font-weight: 600; font-display: swap; src: url('/fonts/Montserrat/Montserrat-SemiBold.ttf') format('truetype'); }
@font-face { font-family: 'Montserrat'; font-style: normal; font-weight: 700; font-display: swap; src: url('/fonts/Montserrat/montserrat-v15-latin-700.woff2') format('woff2'), url('/fonts/Montserrat/Montserrat-Bold.ttf') format('truetype'); }
@font-face { font-family: 'Montserrat'; font-style: normal; font-weight: 900; font-display: swap; src: url('/fonts/Montserrat/Montserrat-Black.ttf') format('truetype'); }

/* ===== Reset / base ===== */
html, body { margin: 0; padding: 0; }
body { min-height: 100vh; display: flex; flex-direction: column; }
img, svg { max-width: 100%; height: auto; }
a { color: var(--blue7); }

/* ===== Page container ===== */
.container { max-width: 120rem; margin: 0 auto; padding: 0 var(--public-page-side-margin); }
@media (min-width: 720px) { .container { padding: 0 var(--public-page-sm-side-margin); } }

.container-narrow { max-width: 78rem; margin: 0 auto; padding: 0 var(--public-page-side-margin); }
@media (min-width: 720px) { .container-narrow { padding: 0 var(--public-page-sm-side-margin); } }

/* =============================================================
   PUBLIC HEADER
   System has no public-page header; composed from primitives.
   White surface · greyE bottom border · logo + nav + CTAs.
   ============================================================= */
.public-header {
  background: #fff;
  border-bottom: 0.1rem solid var(--greyE);
  position: sticky;
  top: 0;
  z-index: var(--z-mobile-topbar);
}
.public-header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2.4rem;
  padding: 1.6rem 0;
}
.public-header .logo {
  display: inline-block;
  line-height: 0;
  flex: 0 0 auto;
}
.public-header .logo img { height: 3.6rem; width: auto; display: block; }
.public-header nav.primary {
  display: none;
  align-items: center;
  gap: 2.4rem;
  margin-left: auto;
}
@media (min-width: 720px) { .public-header nav.primary { display: flex; } }
.public-header nav.primary a {
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--blue2);
  text-decoration: none;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  transition: color var(--transition-time);
}
.public-header nav.primary a:hover { color: var(--blue7); }

/* Hamburger — visible below 720px, hidden on desktop. Three bars
   that animate to an X when aria-expanded="true". */
.public-header .hamburger {
  display: none;
  width: 4.4rem;
  height: 4.4rem;
  background: transparent;
  border: 0;
  padding: 0;
  cursor: pointer;
  margin-left: auto;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  position: relative;
}
@media (max-width: 719px) {
  .public-header .hamburger { display: inline-flex; }
}
.public-header .hamburger span {
  display: block;
  width: 2.4rem;
  height: 0.2rem;
  background: var(--blue2);
  border-radius: 0.1rem;
  transition: transform 0.2s, opacity 0.2s;
  transform-origin: center;
}
.public-header .hamburger[aria-expanded="true"] span:nth-child(1) {
  transform: translateY(0.8rem) rotate(45deg);
}
.public-header .hamburger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.public-header .hamburger[aria-expanded="true"] span:nth-child(3) {
  transform: translateY(-0.8rem) rotate(-45deg);
}

/* Mobile dropdown panel — drops below the sticky header */
@media (max-width: 719px) {
  .public-header nav.primary.open {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: #fff;
    border-bottom: 0.1rem solid var(--greyE);
    padding: 0.4rem 0;
    margin: 0;
    gap: 0;
    box-shadow: 0 0.4rem 1.2rem rgba(0,40,58,0.06);
  }
  .public-header nav.primary.open a {
    padding: 1.4rem var(--public-page-side-margin);
    border-bottom: 0.1rem solid var(--greyE);
  }
  .public-header nav.primary.open a:last-child { border-bottom: 0; }
}

/* =============================================================
   HERO — Study 02 "Soft brand" palette from Hero Color Studies.html
   $blueD ground (pale brand blue), $blue1 text, animated multi-stop
   gradient on the headline (brown1→blue1→blue7→blue5→brown1) with a
   ~9s flow. Three text slides crossfade through on a 15s cycle.
   ============================================================= */
.hero {
  background: var(--blueD);
  color: var(--blue1);
  position: relative;
  overflow: hidden;
  text-align: left;
}

/* Animated gradient flow on headline (from design study) */
@keyframes hero-flow {
  0%   { background-position:   0% 50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position:   0% 50%; }
}
.hero-grid {
  display: block;
  padding: 4rem 0 4.4rem;
}
@media (min-width: 720px) {
  .hero-grid { padding: 5.6rem 0 6rem; }
}
.hero-copy { width: 100%; }  /* fill the container; text aligns left, CTAs anchor right */

.hero-rotator {
  display: grid;        /* stack slides in one cell — auto-sizes to tallest */
  margin-bottom: 3.2rem;
}
.hero-slide {
  grid-area: 1 / 1;
  opacity: 0;
  animation: heroRotate 30s infinite;
  will-change: opacity;
}
.hero-slide.slide-1 { animation-delay: 0s; }
.hero-slide.slide-2 { animation-delay: 10s; }
.hero-slide.slide-3 { animation-delay: 20s; }
/* 30s cycle, 3 slides delayed 0/10/20s (= 33.33% apart).
   Fast fade-in (0→2% ≈0.6s), long hold (2→31% ≈8.7s), fast fade-out
   completing EXACTLY at the 33.33% slot boundary so slide N reaches
   opacity 0 the same instant slide N+1 begins its fade-in. The old
   keyframes left a ~1.5s empty hero between headlines; this removes
   the dead air (empty instant ≤1 frame) without changing the overall
   pacing. One headline visible at a time — no superimposed text. */
@keyframes heroRotate {
  0%       { opacity: 0; }
  2%       { opacity: 1; }
  31%      { opacity: 1; }
  33.33%   { opacity: 0; }
  100%     { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .hero-slide { animation: none; opacity: 0; }
  .hero-slide.slide-1 { opacity: 1; }
}
.hero-kicker {
  /* Study 02 eyebrow: $blue5 on $blueD */
  font-size: 1.4rem;
  font-weight: 700;
  color: var(--blue5);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin: 0 0 1.6rem;
}
.hero-title {
  /* Study 02 headline: animated gradient flowing through brown1 → blue1 →
     blue2 → blue7 → blue5 → blue2 → brown1. Bold across the whole title.
     line-height bumped from 1.05 to 1.15 — bold weight has heavier
     descenders (g/y/p) that the design's lighter 200 weight didn't
     need to accommodate. */
  font-size: 4.4rem;
  font-weight: 700;
  line-height: 1.15;
  margin: 0 0 2rem;
  letter-spacing: -0.01em;
  background-image: linear-gradient(
    90deg,
    var(--brown1)  0%,
    var(--blue1)  18%,
    var(--blue2)  36%,
    var(--blue7)  55%,
    var(--blue5)  72%,
    var(--blue2)  88%,
    var(--brown1) 100%
  );
  background-size: 220% 100%;
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
          color: transparent;
  animation: hero-flow 9s ease-in-out infinite;
}
@media (min-width: 720px) { .hero-title { font-size: 5.6rem; } }
/* No partial-bold strong — whole title is already 700 */
.hero-title strong { font-weight: inherit; color: inherit; }
@media (prefers-reduced-motion: reduce) {
  .hero-title { animation: none; background-position: 50% 50%; }
}
.hero-lede {
  /* Study 02 lede: $blue2 on $blueD */
  font-size: 1.6rem;
  font-weight: 400;
  line-height: 1.6;
  color: var(--blue2);
  margin: 0;
  max-width: 56rem;
}
.hero-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 1.2rem;
  justify-content: flex-end;  /* right-align — text is left, CTAs anchor right */
}
.hero-cta .btn.big {
  min-width: 18rem;  /* equal-width buttons regardless of label length */
}

/* Buttons revert to the standard system colors from buttons.css —
   .btn.color (solid $blue2 + white) and .btn (outlined $blue2). */

/* =============================================================
   PILLARS / FEATURE STRIP
   Three .base-card primitives in a 3-col grid on desktop
   ============================================================= */
.pillar-strip {
  padding: 6.4rem 0;
  background: #fff;
}
.pillar-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2rem;
}
@media (min-width: 720px) { .pillar-grid { grid-template-columns: repeat(3, 1fr); gap: 2.4rem; } }
.pillar-card {
  /* greyF tile on white strip — inverse of the white-tile-on-greyF
     pattern used elsewhere */
  background: var(--greyF);
  border: 0.1rem solid var(--greyE);
  border-radius: 0.4rem;
  padding: 2.8rem 2.4rem;
  text-decoration: none;
  display: block;
  color: inherit;
  transition: border-color var(--transition-time), transform var(--transition-time), box-shadow var(--transition-time);
}
a.pillar-card:hover {
  border-color: var(--blue7);
  transform: translateY(-0.2rem);
  box-shadow: 0 0.6rem 1.6rem rgba(0,40,58,0.08);
}
a.pillar-card:hover .pillar-title { color: var(--blue7); }
.pillar-card .pillar-title { transition: color var(--transition-time); }
.pillar-card .pillar-icon {
  width: 2.8rem;
  height: 2.8rem;
  color: var(--blue7);
  display: block;
  margin-bottom: 1rem;
}
.pillar-card .pillar-num {
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--blue7);
  margin: 0 0 0.8rem;
}
.pillar-card .pillar-title {
  font-size: 1.8rem;
  font-weight: 600;
  color: var(--blue2);
  margin: 0 0 1rem;
}
.pillar-card .pillar-body {
  font-size: 1.4rem;
  font-weight: 400;
  color: #000;
  line-height: 1.55;
  margin: 0;
}

/* =============================================================
   BLOG / "FROM THE BLOG" SECTION
   Uses .section-title-row + custom card for the post tile
   ============================================================= */
.blog-strip { padding: 4.8rem 0 6.4rem; background: #fff; }
/* Per-section spacing override on the title row above the blog grid —
   modifier class keeps inline `style=""` out of the template (CSP-friendly,
   avoids needing 'unsafe-inline' in style-src). */
.blog-strip .section-title-row--blog { margin-bottom: 2.4rem; }
.blog-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.6rem;
}
@media (min-width: 720px) {
  /* 2-col: 4 blog posts stacked left, full-height model card right.
     The model card's grid-column / grid-row / aspect override are
     defined further below in the .model-card section so they sit
     AFTER the base rule and win the cascade. */
  .blog-grid {
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
    gap: 2.4rem;
    align-items: stretch;
  }
  .blog-grid .post-card { grid-column: 1; }
}

.post-card {
  /* extends .base-card */
  background: #fff;
  border: 0.1rem solid var(--greyE);
  border-radius: 0.4rem;
  padding: 2rem 2rem 2.4rem;
  text-decoration: none;
  display: block;
  transition: border-color var(--transition-time), transform var(--transition-time), box-shadow var(--transition-time);
}
.post-card:hover {
  border-color: var(--blue7);
  transform: translateY(-0.2rem);
  box-shadow: 0 0.6rem 1.6rem rgba(0,40,58,0.08);
}
.post-card .date {
  /* matches .tiny-info */
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--grey7);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin: 0 0 0.8rem;
}
.post-card .title {
  font-size: 1.8rem;
  font-weight: 600;
  color: var(--blue2);
  line-height: 1.3;
  margin: 0 0 1rem;
  transition: color var(--transition-time);
}
.post-card:hover .title { color: var(--blue7); }
.post-card .excerpt {
  font-size: 1.3rem;
  font-weight: 400;
  color: #000;
  line-height: 1.55;
  margin: 0;
}

/* =============================================================
   BLOG INDEX — white-box post cards on offwhite body
   Inherits body $greyF as the surface; .post-card cards (white
   bg, $greyE border, hover lift) sit on it. Single column for
   readability of long excerpts.
   ============================================================= */
.blog-index { padding: 4.8rem 0 6.4rem; }
.blog-index .post-list {
  display: flex;
  flex-direction: column;
  gap: 1.6rem;
}
.blog-index .post-card .title { font-size: 2rem; }   /* slightly larger than homepage tile */
.blog-index .post-card .excerpt { max-width: none; }  /* span the full card */

/* =============================================================
   SLIM HERO — Study 01 "Mist" palette from Hero Color Studies.
   $greyF ground (page bg), animated headline gradient flowing
   blue1 → blue2 → blue5 → blue7 → blue5 → blue1. Used by:
   - legal template (/privacy-policy, /terms-and-conditions,
     /content-guidelines, /content-removal-policy, /2257-2)
   - blog index (/blog)
   ============================================================= */
.slim-hero {
  background: var(--greyF);
  padding: 4rem 0 4.4rem;          /* matches .hero-grid mobile */
  border-bottom: 0.1rem solid var(--greyE);
}
@media (min-width: 720px) {
  .slim-hero { padding: 5.6rem 0 6rem; }   /* matches .hero-grid desktop */
}
.slim-hero .kicker {
  font-size: 1.1rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--blue7);
  margin: 0 0 1.2rem;
}
.slim-hero h1 {
  /* Mist gradient — narrower stop range than the main hero so the
     cyan peak still pulls the eye on shorter titles. Whole title bold.
     white-space: pre-line preserves explicit \n in YAML titles
     (e.g. "Why DN 2.0 Launched Early:\nOur Choice to Stay Alive"). */
  font-size: 3.2rem;
  font-weight: 700;
  line-height: 1.2;
  margin: 0 0 1.2rem;
  letter-spacing: -0.005em;
  white-space: pre-line;
  background-image: linear-gradient(
    90deg,
    var(--blue1)  0%,
    var(--blue2) 22%,
    var(--blue5) 45%,
    var(--blue7) 60%,
    var(--blue5) 78%,
    var(--blue1) 100%
  );
  background-size: 220% 100%;
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
          color: transparent;
  animation: hero-flow 9s ease-in-out infinite;
}
@media (min-width: 720px) { .slim-hero h1 { font-size: 4rem; } }
@media (prefers-reduced-motion: reduce) {
  .slim-hero h1 { animation: none; background-position: 50% 50%; }
}
.slim-hero .lede {
  font-size: 1.4rem;
  font-weight: 400;
  line-height: 1.55;
  color: var(--grey3);
  max-width: 56rem;
  margin: 0;
}

/* Used by legal pages — white prose body following the slim hero */
.slim-body {
  background: #fff;
  padding: 4rem 0 8rem;
}

/* =============================================================
   VERIFIED PAGE — extras layered on top of slim-hero/slim-body.
   Hero-with-badge, trust chips, two-layer comparison, step flow.
   ============================================================= */

/* Hero with the brand VerifiedIcon next to the title */
.verified-hero .hero-with-badge {
  display: flex;
  align-items: center;
  gap: 2.4rem;
  flex-wrap: wrap;
}
.verified-hero-badge {
  width: 7.2rem;
  height: 7.2rem;
  flex: 0 0 auto;
  color: var(--blue7);
}
@media (min-width: 720px) {
  .verified-hero-badge { width: 9.6rem; height: 9.6rem; }
}

/* Trust chip row — sits above the prose */
.slim-body .trust-chips {
  list-style: none;
  margin: 0 0 3.2rem;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
}
.slim-body .trust-chips .chip {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.6rem 1.2rem;
  background: var(--greyF);
  border: 0.1rem solid var(--greyE);
  border-radius: 999px;
  font-size: 1.2rem;
  font-weight: 600;
  color: var(--blue2);
  letter-spacing: 0.01em;
}
.slim-body .trust-chips .chip svg {
  width: 1.4rem;
  height: 1.4rem;
  color: var(--blue7);
  flex: 0 0 auto;
}

/* Two-layer comparison — side-by-side cards with brand icons.
   Generous padding, large iconography, clear hierarchy:
   icon → label → title → body. */
.public-prose .two-layers {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.6rem;
  margin: 3.2rem 0 4rem;
  /* break out of the prose narrow column on desktop for a more
     premium "panel" feeling — same width as the hero title above */
}
@media (min-width: 720px) {
  .public-prose .two-layers { grid-template-columns: 1fr 1fr; gap: 2.4rem; }
}
.public-prose .layer-card {
  background: #fff;
  border: 0.1rem solid var(--greyE);
  border-radius: 0.6rem;
  padding: 3.2rem 2.8rem;
  box-shadow: 0 0.1rem 0.2rem rgba(0,40,58,0.04);
  position: relative;
}
.public-prose .layer-card .layer-icon {
  width: 4.4rem;
  height: 4.4rem;
  color: var(--blue7);
  display: block;
  margin-bottom: 2rem;
}
.public-prose .layer-card .layer-label {
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--blue7);
  margin: 0 0 0.6rem;
}
.public-prose .layer-card .layer-title {
  font-size: 1.8rem;
  font-weight: 700;
  color: var(--blue1);
  margin: 0 0 1.2rem;
  line-height: 1.25;
  letter-spacing: -0.005em;
}
.public-prose .layer-card .layer-body {
  font-size: 1.4rem;
  line-height: 1.6;
  color: var(--grey3);
  margin: 0;
}

/* 3-step flow — numbered steps with a visual rhythm. Vertical on
   mobile (with a connecting line down the left), 3-up on desktop. */
.public-prose .step-flow {
  list-style: none;
  margin: 3.2rem 0 4rem;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.6rem;
  counter-reset: none;
}
@media (min-width: 720px) {
  .public-prose .step-flow {
    grid-template-columns: repeat(3, 1fr);
    gap: 2rem;
    align-items: stretch;
  }
}
.public-prose .step-flow li {
  background: var(--greyF);
  border: 0.1rem solid var(--greyE);
  border-radius: 0.6rem;
  padding: 2.4rem 2rem;
  margin: 0;
  position: relative;
}
.public-prose .step-flow .step-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3.2rem;
  height: 3.2rem;
  border-radius: 50%;
  background: var(--blue7);
  color: #fff;
  font-size: 1.4rem;
  font-weight: 700;
  margin-bottom: 1.4rem;
  box-shadow: 0 0 0 0.4rem rgba(0,171,237,0.1);
}
.public-prose .step-flow h4 {
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--blue2);
  margin: 0 0 0.6rem;
  line-height: 1.3;
}
.public-prose .step-flow p {
  font-size: 1.3rem;
  line-height: 1.55;
  color: var(--grey3);
  margin: 0;
}

/* Verified-page CTA block — sits below the prose, above the back-link.
   Buttons match the home hero: solid blue2 primary + outlined secondary. */
.verified-cta {
  margin: 4rem 0 0;
  padding: 3.2rem 0 0;
  border-top: 0.1rem solid var(--greyE);
}
.verified-cta h2 {
  font-size: 2.4rem;
  font-weight: 700;
  color: var(--blue1);
  margin: 0 0 0.8rem;
  letter-spacing: -0.005em;
}
.verified-cta p {
  font-size: 1.5rem;
  color: var(--grey3);
  line-height: 1.55;
  margin: 0 0 2rem;
  max-width: 56rem;
}
.verified-cta .cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 1.2rem;
}
.verified-cta .cta-row .btn.big { min-width: 18rem; }

/* =============================================================
   PROSE — long-form content page (about, legal pages, blog post)
   Composes from system tokens. Not in DN2 because the in-product
   app has no long-form prose surfaces.
   ============================================================= */
.prose-page { padding: 4rem 0 8rem; }
.prose-page .head { margin-bottom: 3.2rem; }
.prose-page .kicker {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--blue7);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin: 0 0 1rem;
}
.prose-page h1 {
  /* extends .public-headline-title; weight bumped to 300 for legal/long-form clarity */
  font-size: 3.6rem;
  font-weight: 300;
  color: var(--blue2);
  line-height: 1.15;
  margin: 0 0 1.2rem;
  letter-spacing: -0.01em;
}
@media (min-width: 720px) { .prose-page h1 { font-size: 4.4rem; } }
.prose-page .lede {
  font-size: 1.6rem;
  color: var(--grey3);
  line-height: 1.55;
  margin: 0 0 3.2rem;
  max-width: 64rem;
}

.public-prose {
  color: #000;
  font-size: 1.5rem;
  line-height: 1.7;
}
.public-prose > * + * { margin-top: 1.4rem; }
.public-prose h2 {
  font-size: 2.2rem;
  font-weight: 600;
  color: var(--blue2);
  line-height: 1.3;
  margin: 3.6rem 0 1.2rem;
  letter-spacing: -0.005em;
}
.public-prose h3 {
  font-size: 1.7rem;
  font-weight: 600;
  color: var(--blue2);
  line-height: 1.35;
  margin: 2.6rem 0 0.8rem;
}
/* H4 = Claudio's preferred section break in blog posts (#### in markdown).
   Styled to mirror the home page's "FROM THE BLOG" section title
   (.featured-dudes-title): uppercase, light weight base, brand blue,
   with <strong> sub-spans coming through bold for keyword emphasis.
   Slightly smaller than the home version since posts use these as
   sub-section headers, not whole-section titles. */
.public-prose h4 {
  font-size: 2rem;
  font-weight: 300;
  color: var(--blue2);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  line-height: 1.25;
  margin: 3.6rem 0 1.2rem;
}
.public-prose h4 strong { font-weight: 700; }
@media (min-width: 720px) {
  .public-prose h4 { font-size: 2.4rem; }
}
.public-prose p { font-size: 1.5rem; line-height: 1.7; color: #000; margin: 0 0 1.4rem; }
.public-prose ul, .public-prose ol { font-size: 1.5rem; line-height: 1.7; margin: 0 0 1.6rem 1.8rem; padding: 0; }
.public-prose li { margin-bottom: 0.4rem; }
.public-prose strong { color: var(--blue2); font-weight: 700; }
.public-prose a {
  color: var(--blue7);
  text-decoration: underline;
  text-decoration-thickness: 0.1rem;
  text-underline-offset: 0.3rem;
  transition: color var(--transition-time);
}
.public-prose a:hover { color: var(--blue5); }
.public-prose img {
  max-width: 100%;
  height: auto;
  border-radius: 0.4rem;
  margin: 2.4rem 0;
  display: block;
}
.public-prose blockquote {
  border-left: 0.3rem solid var(--blue7);
  padding-left: 1.6rem;
  margin: 2rem 0;
  color: var(--grey3);
  font-style: italic;
}
.public-prose hr {
  border: 0;
  border-top: 0.1rem solid var(--greyE);
  margin: 3.2rem 0;
}

.prose-back {
  margin-top: 4.8rem;
  padding-top: 2.4rem;
  border-top: 0.1rem solid var(--greyE);
}
.prose-back a {
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--blue7);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  text-decoration: none;
}
.prose-back a:hover { color: var(--blue5); }

/* End-of-post "Read next" block — two recent posts shown as cards
   below the body. Reuses .post-card from the home page blog-strip
   so styling stays consistent across the site. */
/* =============================================================
   BEFORE / AFTER REVEAL — used in blog posts to show old vs new
   site visuals. Two stacked images; the OLD layer wipes away
   horizontally to reveal the NEW behind it, holds, then wipes
   back. ~10s cycle. Honours prefers-reduced-motion (just shows new).
   ============================================================= */
.before-after-reveal {
  position: relative;
  width: 100%;
  aspect-ratio: 6 / 5;          /* compromise between old (1.19) + new (0.97) */
  margin: 3.2rem 0;
  border: 0.1rem solid var(--greyE);
  border-radius: 0.4rem;
  overflow: hidden;
  background: var(--blue1);     /* dark base if either image fails to load */
}
.before-after-reveal img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: top center;
  background: #fff;             /* keeps screenshots from blending into the dark base */
  margin: 0;                    /* override the public-prose img margin */
  border-radius: 0;             /* override the public-prose img radius */
  display: block;
}
.before-after-reveal .reveal-new { z-index: 1; }
.before-after-reveal .reveal-old {
  z-index: 2;
  animation: revealOld 10s infinite ease-in-out;
  will-change: clip-path, opacity;
}
@keyframes revealOld {
  0%, 25%   { clip-path: inset(0 0 0 0);    opacity: 1; }
  45%, 75%  { clip-path: inset(0 100% 0 0); opacity: 0; }
  95%, 100% { clip-path: inset(0 0 0 0);    opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .before-after-reveal .reveal-old { animation: none; opacity: 0; clip-path: inset(0 100% 0 0); }
}

.post-footer {
  margin-top: 5.6rem;
  padding-top: 3.2rem;
  border-top: 0.1rem solid var(--greyE);
}
.post-footer h3 {
  font-size: 1.4rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--blue7);
  margin: 0 0 2rem;
}
.post-footer .read-next-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.6rem;
}
@media (min-width: 720px) {
  .post-footer .read-next-grid {
    grid-template-columns: 1fr 1fr;
    gap: 2.4rem;
  }
}

/* =============================================================
   MODEL CARD — rotating tile inside the blog grid
   Sits as the 4th cell of the .blog-grid (3 posts + 1 carousel).
   Pure CSS crossfade through Randy / Kenny / Nico — 12s cycle,
   each photo visible ~4s with crossfade. No JS.
   ============================================================= */
.blog-grid .model-card {
  position: relative;
  display: block;
  border: 0.1rem solid var(--greyE);
  border-radius: 0.4rem;
  overflow: hidden;
  background: var(--blue1);
  text-decoration: none;
  aspect-ratio: 4 / 5;
  transition: transform var(--transition-time), box-shadow var(--transition-time);
}
.blog-grid .model-card:hover {
  transform: translateY(-0.2rem);
  box-shadow: 0 0.6rem 1.6rem rgba(0,40,58,0.18);
}
/* Crossfade carousel — fade style aligned with the hero rotator,
   but with overlapping handoffs so total opacity stays at 1.0
   throughout (no blue card-surface peek between faces).
   30s cycle · 10s per face · ~1.5s crossfade · zero gap.

   Trick: each face uses the SAME keyframes (visible during the
   first 33.33% of its cycle, hidden after). Negative animation-
   delays stagger the cycles so when face-1 is fading out
   (28.33% → 33.33% of its cycle = t=8.5s → 10s), face-2's
   "fade back in for next loop" segment (95% → 100%) is firing
   at the same wall-clock window. Opacities sum to 1 the whole
   time — proper crossfade, never any background showing. */
.blog-grid .model-card .rotator { position: absolute; inset: 0; }
.blog-grid .model-card .face {
  position: absolute;
  inset: 0;
  opacity: 0;
  animation: modelFade 15s infinite;
  will-change: opacity;
}
.blog-grid .model-card .face img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 25%;
  display: block;
}
/* Negative delays put each face mid-cycle at t=0:
   face-1 at  0% → visible now,  fades out  at t=4.25–5s, wraps in at 14.25–15s
   face-3 at 33% → just faded,   fades back in at t=9.25–10s
   face-2 at 67% → hidden,       fades back in at t=4.25–5s
   Sequence: Randy (0-5s) → Kenny (5-10s) → Nico (10-15s) → repeat. */
.blog-grid .model-card .face-1 { animation-delay: 0s; }
.blog-grid .model-card .face-2 { animation-delay: -10s; }
.blog-grid .model-card .face-3 { animation-delay: -5s; }
@keyframes modelFade {
  0%      { opacity: 1; }    /* visible at slot start */
  28.33%  { opacity: 1; }    /* still visible at 8.5s of slot */
  33.33%  { opacity: 0; }    /* faded out by end of slot (10s) */
  95%     { opacity: 0; }    /* hidden through middle 2/3 of cycle */
  100%    { opacity: 1; }    /* fade back in 1.5s before next slot */
}
@media (prefers-reduced-motion: reduce) {
  /* Static — show only the first face, no rotation */
  .blog-grid .model-card .face { animation: none; opacity: 0; }
  .blog-grid .model-card .face-1 { opacity: 1; }
}
.blog-grid .model-card .overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 2rem;
  /* Blue gradient covers only the bottom 20% of the image */
  background: linear-gradient(180deg, transparent 80%, rgba(0,40,58,0.92) 100%);
  color: #fff;
}
.blog-grid .model-card .overlay .kicker {
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--brownA);
  margin: 0 0 0.4rem;
}
.blog-grid .model-card .overlay .title {
  font-size: 1.8rem;
  font-weight: 600;
  color: #fff;
  margin: 0;
  letter-spacing: -0.005em;
}

/* Wide-screen layout override: model card fills the right column,
   spanning all four post rows. aspect-ratio is unset so the card
   takes the height of the stacked posts. Width is determined by
   the grid column (1fr). Defined here so it sits AFTER the base
   aspect-ratio rule and wins the cascade. */
@media (min-width: 720px) {
  .blog-grid .model-card {
    grid-column: 2;
    grid-row: 1 / span 4;
    aspect-ratio: auto;
    height: 100%;
  }
}

/* =============================================================
   PUBLIC FOOTER
   $blue1 surface · $brownC text — matches Style Guide §
   .shell-footer-mock palette. Composed for marketing-site use.
   ============================================================= */
.public-footer {
  /* $blue2 (#003A51) matches the dn-logo-on-brand-square.png background
     exactly — the logo's pre-composed square blends seamlessly into the
     footer surface, so the visible mark is just the monogram. */
  background: var(--blue2);
  color: var(--brownC);
  margin-top: auto;
  padding: 5.6rem 0 2.4rem;
}
.public-footer .top {
  display: grid;
  grid-template-columns: 1fr;
  gap: 3.2rem;
  margin-bottom: 4.8rem;
}
@media (min-width: 720px) { .public-footer .top { grid-template-columns: 2fr 1fr 1fr 1fr; gap: 4rem; } }

.public-footer .brand-cell .logo img {
  /* dn-logo-on-brand-square.png is pre-composed on $blue1 — the
     square's background blends with the footer surface, no filter
     or inversion needed. The visible mark is the white-on-grey
     monogram floating on the dark footer. */
  width: 8.8rem;
  height: 8.8rem;
  margin: 0 0 0.4rem -1.6rem;  /* nudge left so the monogram aligns with the column edge after the square's internal padding */
  display: block;
}
.public-footer .brand-cell p {
  font-size: 1.3rem;
  color: var(--brownC);
  line-height: 1.6;
  margin: 0;
  max-width: 32rem;
}

.public-footer h4 {
  /* matches .settings-subtitle (1.4rem · 700 · uppercase · letter-spacing 0.04em) */
  font-size: 1.2rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #fff;
  margin: 0 0 1.4rem;
}
.public-footer ul { list-style: none; padding: 0; margin: 0; }
.public-footer li { margin-bottom: 0.8rem; }
.public-footer a {
  font-size: 1.3rem;
  color: var(--brownC);
  text-decoration: none;
  transition: color var(--transition-time);
}
.public-footer a:hover { color: #fff; }

/* Bluesky icon — sits under the Join column's link list */
.public-footer .social-bsky {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3.6rem;
  height: 3.6rem;
  margin-top: 1.6rem;
  border-radius: 50%;
  color: var(--brownC);
  background: rgba(255, 255, 255, 0.06);
  transition: color var(--transition-time), background-color var(--transition-time), transform var(--transition-time);
}
.public-footer .social-bsky:hover {
  color: #1185fe;  /* Bluesky brand blue */
  background: rgba(255, 255, 255, 0.16);
  transform: translateY(-0.1rem);
}
.public-footer .social-bsky svg {
  width: 1.8rem;
  height: 1.8rem;
  display: block;
}

.public-footer .bottom {
  border-top: 0.1rem solid rgba(255,255,255,0.08);
  padding-top: 2rem;
  margin-top: 0.8rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  text-align: center;
  /* .copyright-text spec is brown3 (#5B4045) but that's unreadable on
     the dark $blue2 footer surface; using brownC (the light tone used
     for the link cells above) keeps the brand palette and stays legible. */
  font-size: 1.1rem;
  font-weight: 400;
  color: rgba(237, 221, 210, 0.55);  /* brownC at 55% — quiet fine print */
}
.public-footer .bottom p {
  margin: 0;
  color: inherit;  /* override the global `p { color: #000; }` from typography.css */
}

/* =============================================================
   UPGRADE / PRICING PAGE
   Uses the existing pillar-strip/pillar-grid/pillar-card pattern
   for the 3 price tiers. Only new CSS is the price number display,
   the gold featured-card treatment, and the small-print line.
   ============================================================= */

/* Large price number inside a pillar-card */
.pricing-price {
  font-size: 4.8rem;
  font-weight: 700;
  color: var(--blue2);
  line-height: 1;
  margin: 0.4rem 0 0.2rem;
  letter-spacing: -0.02em;
}
.pricing-period {
  color: var(--grey7) !important;
  margin-bottom: 2.8rem !important;
}

/* Featured (annual) card — white bg, gold border */
.pricing-featured {
  background: #fff !important;
  border-color: #d4af35 !important;
  box-shadow: 0 0.4rem 2rem rgba(212, 175, 53, 0.12);
}
.pricing-featured .pillar-num { color: #b8961f; }

/* "Best value" chip above the plan name */
.pricing-badge {
  display: inline-block;
  background: #d4af35;
  color: #fff;
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.3rem 1.2rem;
  border-radius: 99rem;
  margin-bottom: 1.2rem;
}

/* CTA button — full width, sits at the bottom of the card */
.pricing-cta {
  display: block;
  text-align: center;
  margin-top: 0.8rem;
}

/* Small print below the grid */
.pricing-small-print {
  text-align: center;
  font-size: 1.2rem;
  color: var(--grey7);
  margin-top: 2.4rem;
}

/* PRICING MATRIX TABLE
   Canonical Free vs Supporter comparison.
   Classes: .pm-col-free, .pm-col-supporter, .pm-section-header,
            .pm-supporter-top, .pm-supporter-bottom
   ============================================================= */
.pricing-matrix {
  overflow-x: auto;
  margin: 2.8rem 0 2.4rem;
}
.pricing-matrix table {
  width: 100%;
  border-collapse: collapse;
  font-size: 1.4rem;
  line-height: 1.4;
}
.pricing-matrix thead th {
  padding: 0.8rem 1.6rem;
  font-size: 1.2rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  border-bottom: 2px solid #e8eaed;
}
.pricing-matrix tbody td {
  padding: 0.9rem 1.6rem;
  border-bottom: 1px solid #eef0f2;
  color: #1a1a2e;
  font-weight: 400;
}
/* Free column */
.pricing-matrix .pm-col-free {
  text-align: center;
  color: var(--grey7);
  width: 10rem;
}
.pricing-matrix thead .pm-col-free {
  color: var(--grey7);
}
/* Supporter column — gold borders, tinted bg */
.pricing-matrix .pm-col-supporter {
  text-align: center;
  font-weight: 700;
  color: var(--blue2);
  background: rgba(212,175,53,0.07);
  border-left: 2px solid #d4af35;
  border-right: 2px solid #d4af35;
  width: 14rem;
}
.pricing-matrix thead .pm-col-supporter {
  color: #b8961f;
  background: rgba(212,175,53,0.07);
  border-left: 2px solid #d4af35;
  border-right: 2px solid #d4af35;
}
/* Top and bottom gold caps on the supporter column */
.pricing-matrix .pm-supporter-top  { border-top: 2px solid #d4af35; }
.pricing-matrix .pm-supporter-bottom { border-bottom: 2px solid #d4af35 !important; }
/* Section header rows */
.pricing-matrix .pm-section-header td {
  background: #f5f7fa;
  font-weight: 700;
  font-size: 1.5rem;
  color: var(--blue2);
  padding: 1.4rem 1.6rem 1rem;
  border-bottom: none;
}
