/* ===================================================================
   Frolicy — self-hosted fonts (Schibsted Grotesk)

   Self-hosted from Google Fonts' own served files (fonts/*.woff2),
   removing the third-party fonts.googleapis.com/fonts.gstatic.com
   round-trip that every page previously made independently. Google
   serves this family as a single variable-font file per unicode
   range (latin / latin-ext) covering the whole 400-700 weight span
   -- confirmed by fetching the real Google Fonts CSS response, which
   points all four weight declarations at the same two files. These
   @font-face blocks mirror that exact structure (weight + unicode-range
   pairs) against the two local files, so nothing about how weights
   resolve changes from the Google-hosted version.
   =================================================================== */

@font-face {
  font-family: 'Schibsted Grotesk';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/schibsted-grotesk-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Schibsted Grotesk';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/schibsted-grotesk-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: 'Schibsted Grotesk';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/schibsted-grotesk-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Schibsted Grotesk';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/schibsted-grotesk-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: 'Schibsted Grotesk';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/schibsted-grotesk-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Schibsted Grotesk';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/schibsted-grotesk-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: 'Schibsted Grotesk';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/schibsted-grotesk-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Schibsted Grotesk';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/schibsted-grotesk-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;
}

/* ===================================================================
   Frolicy — design tokens + base styles
   =================================================================== */

:root {
  --color-cream: #FBF6EE;
  --color-ink: #362F2B;
  --color-coral: #E8734A;
  --color-coral-dark: #B14A26;
  --color-coral-tint: #FDE7DC;
  --color-sage: #6B8F71;
  --color-sage-dark: #3F5A44;
  --color-sage-tint: #E4EDE3;
  --color-honey: #E8A94C;
  --color-honey-dark: #92601A;
  --color-honey-tint: #FBECD3;
  --color-border: #E8DFD1;
  --color-card: #FFFDF9;
  --color-muted: #8A7F6E;
  --color-secondary: #5B5347;
  --color-photo: #EFE6D9;
  --color-photo-border: #E0D5C2;
  --color-error: #B14A26;
  --color-strip-bg: #F5F1E6;

  --font-sans: 'Schibsted Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

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

  --container: 1120px;
  --container-narrow: 640px;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--font-sans);
  background: var(--color-cream);
  color: var(--color-ink);
  font-weight: 400;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }

a { color: inherit; text-decoration: none; }

button, input { font-family: inherit; }

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

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

h1, h2, h3, h4 {
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 0;
  line-height: 1.2;
}

h2, h3, h4 { font-weight: 600; }

p { margin: 0; }

.icon {
  width: 20px;
  height: 20px;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex-shrink: 0;
}

/* ===================================================================
   Buttons
   =================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 15px;
  border-radius: var(--radius-md);
  padding: 14px 26px;
  border: none;
  cursor: pointer;
  transition: transform 0.1s ease, opacity 0.15s ease;
}

.btn:active { transform: scale(0.98); }

.btn-primary {
  background: var(--color-coral);
  color: #FFFDF9;
}

.btn-primary:hover { opacity: 0.92; }

.btn-secondary {
  background: transparent;
  color: var(--color-ink);
  border: 1px solid var(--color-border);
}

.btn-secondary:hover { background: rgba(0,0,0,0.02); }

.btn-block { width: 100%; }

.btn-sm {
  padding: 9px 16px;
  font-size: 13px;
}

/* ===================================================================
   Badges + chips
   =================================================================== */

.badge {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  padding: 5px 12px;
  border-radius: var(--radius-sm);
  background: var(--color-honey-tint);
  color: var(--color-honey-dark);
}

.chip {
  display: inline-flex;
  align-items: center;
  font-size: 13px;
  font-weight: 500;
  padding: 8px 16px;
  border-radius: var(--radius-sm);
  background: var(--color-card);
  border: 1px solid var(--color-border);
  color: var(--color-secondary);
  cursor: pointer;
}

.chip.is-active {
  background: var(--color-coral);
  border-color: var(--color-coral);
  color: #FFFDF9;
  font-weight: 600;
}

/* ===================================================================
   Header + nav
   =================================================================== */

.site-header {
  border-bottom: 1px solid var(--color-border);
}

.site-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: 18px;
  padding-bottom: 18px;
  gap: 16px;
}

.logo {
  font-weight: 700;
  font-size: 21px;
  letter-spacing: -0.01em;
  color: var(--color-ink);
}

.nav-links {
  display: flex;
  gap: 28px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav-links a {
  font-size: 14px;
  font-weight: 500;
  color: var(--color-secondary);
}

.nav-links a:hover { color: var(--color-ink); }

.nav-toggle {
  display: none;
  background: none;
  border: none;
  cursor: pointer;
  padding: 6px;
}

/* Without this, taps on the icon's SVG/line children can fail to bubble a
   click to the button on some mobile browsers — force the button itself to
   always be the hit target. */
.nav-toggle svg, .nav-toggle svg * { pointer-events: none; }

.header-cta { flex-shrink: 0; }

/* Minimal header used on the guide download page — logo + back link only */
.site-header-minimal .container {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-top: 16px;
  padding-bottom: 16px;
  font-size: 14px;
  font-weight: 500;
  color: var(--color-secondary);
}

.site-header-minimal a { display: inline-flex; align-items: center; gap: 6px; }
.site-header-minimal a:hover { color: var(--color-ink); }

@media (max-width: 780px) {
  .nav-links { display: none; }
  .nav-toggle { display: inline-flex; }
  .header-cta { display: none; }
}

/* ===================================================================
   Site search
   =================================================================== */

.search-trigger {
  background: none;
  border: none;
  cursor: pointer;
  padding: 6px;
  color: var(--color-secondary);
  display: inline-flex;
  align-items: center;
}

.search-trigger:hover { color: var(--color-ink); }
.search-trigger svg, .search-trigger svg * { pointer-events: none; }

/* ===================================================================
   Header auth (js/site-header.js) -- injected on every page that has
   the full .site-header, not present in markup by default. Stays
   visible at every width, same as .search-trigger, rather than being
   folded into the hamburger menu at 780px -- account access shouldn't
   require an extra tap to discover.
   =================================================================== */
.header-auth { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }

/* [hidden] alone loses to .btn's own `display: inline-flex` and this
   rule's `display: flex` -- both are author-stylesheet rules of equal
   specificity to [hidden], and author styles beat the UA stylesheet
   regardless of order, so [hidden] needs to be restated explicitly
   here. Same pattern already used for .auth-modal-note[hidden] and
   .auth-modal-guest[hidden] above. */
.header-auth-login[hidden] { display: none; }

.header-auth-account { display: flex; align-items: center; gap: 8px; }
.header-auth-account[hidden] { display: none; }

.header-auth-link {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--color-ink);
  font-size: 14px;
  font-weight: 600;
  max-width: 140px;
}

.header-auth-link:focus-visible { outline: 2px solid var(--color-coral); outline-offset: 2px; border-radius: var(--radius-sm); }

.header-auth-avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--color-sage-tint);
  color: var(--color-sage-dark);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 700;
  flex-shrink: 0;
  overflow: hidden;
}

.header-auth-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

.header-auth-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.header-auth-logout {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 13px;
  color: var(--color-muted);
  padding: 4px 2px;
}

.header-auth-logout:hover { color: var(--color-ink); }
.header-auth-logout:focus-visible { outline: 2px solid var(--color-coral); outline-offset: 2px; border-radius: var(--radius-sm); }

@media (max-width: 480px) {
  .header-auth-name { display: none; }
  .header-auth-login { padding-left: 10px; padding-right: 10px; }
}

.site-search-panel {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(43, 36, 30, 0.5);
  z-index: 200;
  padding: 10vh 20px 20px;
}

.site-search-panel.is-open { display: block; }

.site-search-box {
  max-width: 640px;
  margin: 0 auto;
  background: var(--color-cream);
  border-radius: var(--radius-lg);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
  overflow: hidden;
}

.site-search-box-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 20px;
  border-bottom: 1px solid var(--color-border);
}

.site-search-box-header input {
  flex: 1;
  border: none;
  background: none;
  font-size: 16px;
  font-family: inherit;
  color: var(--color-ink);
  outline: none;
}

.site-search-close {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-muted);
  font-size: 13px;
  flex-shrink: 0;
}

.site-search-results {
  max-height: 60vh;
  overflow-y: auto;
  padding: 8px;
}

.site-search-result {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  text-decoration: none;
}

.site-search-result:hover { background: var(--color-card); }

.site-search-result-type {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-coral-dark);
}

.site-search-result-title { font-size: 15px; font-weight: 600; color: var(--color-ink); }
.site-search-result-desc { font-size: 13px; color: var(--color-secondary); line-height: 1.5; }

.site-search-empty {
  padding: 24px 14px;
  text-align: center;
  color: var(--color-muted);
  font-size: 14px;
}

/* ===================================================================
   Hero
   =================================================================== */

.hero {
  padding: 64px 0;
}

.hero .container {
  display: flex;
  align-items: center;
  gap: 48px;
}

.hero-copy { flex: 1; min-width: 0; }

.eyebrow {
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-coral-dark);
  font-weight: 600;
  margin-bottom: 14px;
}

.hero h1 {
  font-size: 42px;
  margin-bottom: 18px;
  max-width: 560px;
}

.hero-sub {
  font-size: 16px;
  color: var(--color-secondary);
  max-width: 420px;
  margin-bottom: 28px;
}

.hero-note {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--color-sage-dark);
  font-weight: 500;
  margin-top: 16px;
}

.hero-note .icon { width: 15px; height: 15px; color: var(--color-sage); }

.hero-visual {
  position: relative;
  flex: 0 0 480px;
  height: 480px;
}

.hero-blob {
  position: absolute;
  z-index: 0;
  border-radius: 50% 50% 45% 55% / 55% 45% 55% 45%;
}

.hero-blob-1 {
  top: -20px;
  left: -28px;
  width: 130px;
  height: 130px;
  background: var(--color-sage-tint);
  display: none;
}

.hero-blob-2 {
  bottom: -18px;
  right: 20px;
  width: 90px;
  height: 90px;
  background: var(--color-honey-tint);
  border-radius: 42% 58% 60% 40% / 48% 40% 60% 52%;
  display: none;
}

.hero-media {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Single soft sage halo behind the circle — perfectly concentric,
   thin, muted rim. Sized in px (106% of the video-frame's own
   dimensions at each breakpoint) rather than % of .hero-media, since
   .hero-media's box is wider than the circle on mobile — a percentage
   there would blow the rim out of proportion at smaller sizes. */
.hero-halo {
  display: block;
  position: absolute;
  z-index: 0;
  width: 487.6px;
  height: 487.6px;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: #E7ECDD;
  filter: blur(6px);
}

.hero-video-frame {
  position: relative;
  z-index: 1;
  width: 460px;
  height: 460px;
  max-width: 100%;
  max-height: 100%;
  background: var(--color-photo);
  border-radius: 50%;
  overflow: hidden;
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.12);
}

.hero-video-frame img,
.hero-video-frame video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center center;
  display: block;
}

.hero-video {
  cursor: pointer;
  filter: brightness(1.12) saturate(1.03);
}

@media (max-width: 780px) {
  .hero .container { flex-direction: column; }
  .hero h1 { font-size: 30px; }
  .hero-visual { width: 100%; flex-basis: auto; height: 340px; }
  .hero-video-frame { width: 300px; height: 300px; }
  .hero-halo { width: 318px; height: 318px; }
}

/* ===================================================================
   Maya intro video — hero play button, placeholder, lightbox, About
   =================================================================== */

.maya-play-btn {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.92);
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);
  transition: transform 0.15s ease;
}

.maya-play-btn:hover,
.maya-play-btn:focus-visible { transform: translate(-50%, -50%) scale(1.06); }

.maya-play-btn .icon { width: 20px; height: 20px; color: var(--color-coral-dark); margin-left: 3px; }

.maya-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  background: linear-gradient(135deg, var(--color-sage-tint), var(--color-honey-tint));
  color: var(--color-secondary);
  font-size: 13px;
  font-weight: 500;
  text-align: center;
  padding: 24px;
}

.maya-placeholder-icon { width: 36px; height: 36px; color: var(--color-sage-dark); fill: none; stroke: currentColor; stroke-width: 1.6; }

.maya-lightbox {
  position: fixed;
  inset: 0;
  background: rgba(20, 20, 20, 0.82);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 200;
  padding: 24px;
}

.maya-lightbox-inner { position: relative; width: 100%; max-width: 720px; }

.maya-lightbox-video { width: 100%; border-radius: 12px; display: block; }

.maya-lightbox-close {
  position: absolute;
  top: -40px;
  right: 0;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: none;
  background: rgba(255, 255, 255, 0.92);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}

.about-video-wrap {
  margin: 24px auto 32px;
  max-width: 420px;
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.12);
  background: var(--color-photo);
  aspect-ratio: 1 / 1;
}

.about-video-wrap video { width: 100%; height: 100%; display: block; object-fit: cover; filter: brightness(1.12) saturate(1.03); }

.about-video-wrap .maya-placeholder { border-radius: 0; }

/* ===================================================================
   Trust strip
   =================================================================== */

.trust-strip {
  background: var(--color-strip-bg);
  padding: 22px 0;
}

.trust-strip .container {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 36px;
}

.trust-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 500;
  color: var(--color-secondary);
}

.trust-item .icon { color: var(--color-sage); width: 18px; height: 18px; }

/* ===================================================================
   Sections
   =================================================================== */

.section { padding: 56px 0; }
.section-sm { padding: 40px 0; }

.section-head {
  margin-bottom: 28px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

.section-head-text h2 { font-size: 24px; margin-bottom: 6px; display: inline-flex; align-items: center; gap: 10px; }
.section-head-text p { font-size: 14px; color: var(--color-secondary); }

.accent-mark { color: var(--color-coral); width: 20px; height: 20px; flex-shrink: 0; }

.page-hero {
  padding: 48px 0 12px;
}

.page-hero h1 { font-size: 32px; margin-bottom: 8px; }
.page-hero p { font-size: 15px; color: var(--color-secondary); max-width: 520px; }

/* ===================================================================
   Guide cards + grid
   =================================================================== */

.guide-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

.guide-card {
  position: relative;
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 16px;
  display: block;
  transition: border-color 0.15s ease, transform 0.15s ease;
}

.guide-card:hover {
  border-color: var(--color-photo-border);
  transform: translateY(-2px);
}

.guide-card-cover {
  position: relative;
  height: 160px;
  background: var(--color-photo);
  border-radius: var(--radius-md);
  margin-bottom: 22px;
  overflow: hidden;
}

.guide-card-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }

.guide-card-cover .badge {
  position: absolute;
  top: 10px;
  left: 10px;
}

.guide-card-icon {
  position: absolute;
  top: 176px;
  left: 30px;
  transform: translateY(-50%);
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--color-card);
  border: 1px solid var(--color-border);
  display: flex;
  align-items: center;
  justify-content: center;
}

.guide-card-icon .icon { width: 16px; height: 16px; color: var(--color-coral); }

/* Static variant for cards with no cover image (e.g. the tools index) —
   the absolute-positioned .guide-card-icon assumes a cover sits above it,
   so cover-less cards use this inline version instead. */
.guide-card-icon.is-static {
  position: static;
  transform: none;
  margin-bottom: 14px;
}

.guide-card h3 {
  font-size: 16px;
  margin-bottom: 6px;
  color: var(--color-coral-dark);
}

.guide-card p {
  font-size: 13px;
  color: var(--color-secondary);
  line-height: 1.5;
  margin-bottom: 10px;
}

.guide-card-meta {
  font-size: 12px;
  font-weight: 500;
  color: var(--color-muted);
  display: flex;
  align-items: center;
  gap: 6px;
}

.guide-card-meta .icon { width: 14px; height: 14px; }

@media (max-width: 900px) {
  .guide-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 600px) {
  .guide-grid { grid-template-columns: 1fr; }
}

/* ===================================================================
   Tips / educational callout
   =================================================================== */

.tips-callout {
  display: flex;
  align-items: stretch;
  gap: 40px;
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 32px;
}

.tips-callout-photo {
  flex: 0 0 320px;
  border-radius: var(--radius-md);
  overflow: hidden;
}

.tips-callout-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }

.tips-callout-body { flex: 1; min-width: 0; }

.tips-callout-body h2 {
  font-size: 22px;
  margin: 6px 0 18px;
  max-width: 420px;
}

.tips-list {
  list-style: none;
  margin: 0 0 22px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.tips-list li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 14px;
  color: var(--color-secondary);
  line-height: 1.55;
}

.tips-list .icon { color: var(--color-sage); width: 17px; height: 17px; margin-top: 2px; flex-shrink: 0; }
.tips-list strong { color: var(--color-ink); font-weight: 600; }

@media (max-width: 780px) {
  .tips-callout { flex-direction: column; padding: 20px; gap: 20px; }
  .tips-callout-photo { flex-basis: 200px; }
}

/* ===================================================================
   Recently added row
   =================================================================== */

.recent-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

.recent-item {
  display: flex;
  gap: 14px;
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 12px;
  align-items: center;
}

.recent-item-cover {
  flex: 0 0 64px;
  width: 64px;
  height: 64px;
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.recent-item-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }

.recent-item-body { min-width: 0; }

.recent-item-tag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  font-weight: 600;
  color: var(--color-sage-dark);
  margin-bottom: 4px;
}

.recent-item-tag .icon { width: 12px; height: 12px; }

.recent-item h4 {
  font-size: 14px;
  font-weight: 600;
  margin: 0 0 4px;
  line-height: 1.3;
}

@media (max-width: 900px) {
  .recent-row { grid-template-columns: 1fr; }
}

/* ===================================================================
   Popular questions list
   =================================================================== */

.question-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.question-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 16px 20px;
  font-size: 15px;
  font-weight: 500;
  color: var(--color-ink);
  transition: border-color 0.15s ease;
}

.question-item:hover { border-color: var(--color-photo-border); }
.question-item .icon { width: 16px; height: 16px; color: var(--color-coral); flex-shrink: 0; }

/* ===================================================================
   Filter chips row
   =================================================================== */

.filter-row {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin: 20px 0 32px;
}

/* ===================================================================
   Guide download page
   =================================================================== */

.guide-page {
  max-width: 420px;
  margin: 0 auto;
  padding: 32px 24px 64px;
}

.guide-cover {
  width: 230px;
  height: 290px;
  margin: 0 auto 20px;
  background: var(--color-photo);
  border-radius: var(--radius-lg);
  box-shadow: 0 16px 32px -16px rgba(54, 47, 43, 0.28);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-muted);
  font-size: 12px;
  text-align: center;
  overflow: hidden;
}

.guide-cover img { width: 100%; height: 100%; object-fit: cover; }

.guide-page-body { text-align: center; }

.guide-page h1 {
  font-size: 24px;
  line-height: 1.25;
  margin: 16px 0 10px;
}

.guide-page .lede {
  font-size: 14px;
  color: var(--color-secondary);
  line-height: 1.55;
  margin-bottom: 16px;
}

.guide-meta {
  font-size: 12px;
  color: var(--color-muted);
  margin-bottom: 24px;
}

.lead-form-card {
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 20px;
  text-align: left;
}

.lead-form-card .form-title {
  font-size: 14px;
  font-weight: 600;
  margin-bottom: 12px;
}

.field {
  width: 100%;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  font-size: 14px;
  background: #FFFDF9;
  color: var(--color-ink);
  margin-bottom: 10px;
  display: block;
}

.field::placeholder { color: var(--color-muted); }

.field:focus {
  outline: none;
  border-color: var(--color-coral);
}

.field-error {
  font-size: 12px;
  color: var(--color-error);
  margin: -4px 0 10px;
  display: none;
}

.field-error.is-visible { display: block; }

.form-note {
  font-size: 11px;
  color: var(--color-muted);
  text-align: center;
  margin-top: 10px;
}

.form-success {
  display: none;
  text-align: center;
  padding: 12px 0 4px;
  font-size: 14px;
  font-weight: 500;
  color: var(--color-sage-dark);
}

.form-success.is-visible { display: block; }

.skip-form-link {
  display: block;
  text-align: center;
  font-size: 12px;
  color: var(--color-muted);
  margin-top: 12px;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.skip-form-link:hover { color: var(--color-secondary); }

/* ===================================================================
   Shop — "Recommended by Frolicy"
   =================================================================== */

.shop-intro-note {
  background: var(--color-sage-tint);
  border-radius: var(--radius-lg);
  padding: 18px 22px;
  font-size: 14px;
  color: var(--color-sage-dark);
  margin-top: 20px;
}

.shop-category { margin-bottom: 40px; }
.shop-category-head { margin-bottom: 16px; }
.shop-category-head h2 { font-size: 20px; margin-bottom: 4px; }
.shop-category-head p { font-size: 13px; color: var(--color-secondary); }

.shop-picks {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 14px;
}

.shop-pick {
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 16px;
}

.shop-pick h3 { font-size: 15px; margin-bottom: 6px; }
.shop-pick h3 a { color: var(--color-coral-dark); }
.shop-pick p { font-size: 13px; color: var(--color-secondary); line-height: 1.5; margin: 0; }

@media (max-width: 700px) {
  .shop-picks { grid-template-columns: 1fr; }
}

/* ===================================================================
   Chewy Picks — product grid (placeholder data until real affiliate
   catalog is supplied; see content/shop-chewy-products.json)
   =================================================================== */

.chewy-reel-slot {
  margin: 24px 0 32px;
}

.chewy-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

.chewy-card {
  position: relative;
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 16px;
  display: flex;
  flex-direction: column;
  transition: border-color 0.15s ease, transform 0.15s ease;
}

.chewy-card:hover {
  border-color: var(--color-photo-border);
  transform: translateY(-2px);
}

.chewy-card-thumb {
  position: relative;
  height: 160px;
  border-radius: var(--radius-md);
  margin-bottom: 16px;
  overflow: hidden;
}

.chewy-card-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

.chewy-card-thumb .badge {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 1;
  background: var(--color-card);
  color: var(--color-ink);
}

.chewy-card-thumb-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: linear-gradient(135deg, var(--color-sage-tint), var(--color-honey-tint));
  color: var(--color-secondary);
  font-size: 12px;
  font-weight: 500;
}

.chewy-card-thumb-placeholder .icon { width: 26px; height: 26px; color: var(--color-sage-dark); fill: none; stroke: currentColor; stroke-width: 1.6; }

/* Hover-to-play (desktop) / tap-to-play (mobile) product video preview.
   wireChewyCardVideo() in js/main.js injects this markup only into
   cards that carry a real data-video attribute — cards without one
   never get a <video> element and just show the static thumbnail. */
.chewy-card-video {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.chewy-card-video-play {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 2;
  transform: translate(-50%, -50%);
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.92);
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.16);
}

.chewy-card-video-play .icon { width: 15px; height: 15px; color: var(--color-coral-dark); margin-left: 2px; }

.chewy-card h3 { font-size: 15px; margin-bottom: 4px; color: var(--color-ink); }

/* Byline, e.g. "By the Frolicy team" — a <span>, not a <p>, so it
   doesn't pick up .chewy-card p's flex:1 and compete with the
   description for vertical growth. */
.chewy-card-author { display: block; font-size: 12px; color: var(--color-secondary); margin: 0 0 10px; }

/* Frolicy Picks — publish date, same treatment as the author byline
   above (span, not p, so it doesn't compete with the description for
   flex:1 growth space). */
.chewy-card-date { display: block; font-size: 12px; color: var(--color-secondary); margin: -2px 0 10px; }

/* Visual hierarchy per the brief: image/video -> title -> price ->
   description -> reviews (if present) -> Buy Now, in that exact
   order, Buy Now last as a full-width closing CTA. */
.chewy-card-price { display: block; font-size: 14px; font-weight: 600; color: var(--color-ink); margin-bottom: 10px; }

/* --color-muted fails WCAG AA (~3.9:1) against the card background at
   this size; --color-secondary passes (~7.5:1) while staying visually
   "quieter" than the resolved-price color above it. */
.chewy-card-price.is-pending { font-weight: 500; color: var(--color-secondary); }

.chewy-card p { font-size: 13px; color: var(--color-secondary); line-height: 1.5; margin: 0 0 14px; flex: 1; }

.chewy-buy-btn {
  min-height: 44px;
  width: 100%;
}

.chewy-buy-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.chewy-buy-btn:disabled:hover { opacity: 0.5; }

.chewy-card-rating {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  font-weight: 500;
  color: var(--color-honey-dark);
  margin-bottom: 8px;
}

.chewy-card-rating .icon { width: 13px; height: 13px; fill: currentColor; }

/* Explicit "not fabricated" placeholder state — never invent a star
   count or review number, this is what renders instead until a real
   rating exists. Uses --color-secondary, not --color-muted: muted
   fails WCAG AA (~3.9:1) at this size against the card background. */
.chewy-card-rating.is-pending { color: var(--color-secondary); font-style: italic; font-weight: 500; }

/* Only rendered when a real, relevant hub exists for that card's
   category — never a fabricated or generic "learn more" link. */
.chewy-card-related-link { display: block; font-size: 12px; font-weight: 500; color: var(--color-coral-dark); margin-bottom: 10px; }
.chewy-card-related-link:hover { text-decoration: underline; }

.chewy-card-review-snippet {
  font-size: 12px;
  font-style: italic;
  color: var(--color-secondary);
  line-height: 1.5;
  margin-bottom: 8px;
}

.chewy-affiliate-note {
  font-size: 12px;
  /* --color-secondary, not --color-muted: muted only clears ~3.9:1 at
     this size against the card background, which fails WCAG AA's
     4.5:1 for normal text. This status text (E-books' "Not yet
     available", Weekly Products' "Affiliate link — Frolicy may earn
     a commission") is real placeholder/disclosure copy, not
     decoration, so it needs to actually be readable. */
  color: var(--color-secondary);
  margin-top: 8px;
  text-align: center;
}

@media (max-width: 900px) {
  .chewy-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 600px) {
  .chewy-grid { grid-template-columns: 1fr; }
}

/* Generic "nothing to show yet" state, shown by a render script only
   when its data file is empty or fails to load; hidden by default in
   HTML. Currently used by js/render-weekly-products.js. */
.chewy-empty-state {
  text-align: center;
  font-size: 15px;
  color: var(--color-secondary);
  padding: 48px 16px;
}

/* ===================================================================
   Weekly Recommended Products — one product per row (shop.html).
   Reuses .chewy-buy-btn, .chewy-affiliate-note, .badge, and the
   image-load-fallback markup (.chewy-card-thumb-placeholder) from the
   card components above rather than duplicating them; everything
   below is new only because a row's shape (image left, content right,
   price/CTA anchored at the end) has no card equivalent to reuse.
   =================================================================== */

.product-rows { display: flex; flex-direction: column; gap: 20px; }

.product-row {
  display: flex;
  gap: 24px;
  padding: 24px;
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--color-border);
  border-radius: var(--radius-lg);
}

/* Category accent — a deliberate, meaning-carrying color per category
   (not decorative variety for its own sake): sage already reads as
   "calm" everywhere else on this site, honey as warm/food-adjacent,
   coral as energetic/playful. Reusing existing tokens only — no new
   colors introduced for this. */
.product-row[data-category="Calming"] { border-left-color: var(--color-sage); }
.product-row[data-category="Calming"] .badge { background: var(--color-sage-tint); color: var(--color-sage-dark); }
.product-row[data-category="Nutrition"] { border-left-color: var(--color-honey); }
.product-row[data-category="Nutrition"] .badge { background: var(--color-honey-tint); color: var(--color-honey-dark); }
.product-row[data-category="Enrichment"] { border-left-color: var(--color-coral); }
.product-row[data-category="Enrichment"] .badge { background: var(--color-coral-tint); color: var(--color-coral-dark); }

.product-row-cover {
  position: relative;
  flex-shrink: 0;
  width: 200px;
  aspect-ratio: 1 / 1;
  border-radius: var(--radius-md);
  overflow: hidden;
  display: block;
  background: var(--color-photo);
  border: 1px solid var(--color-photo-border);
}
.product-row-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.product-row-cover:focus-visible { outline: 2px solid var(--color-coral); outline-offset: 2px; }
.product-row-cover .badge { position: absolute; top: 10px; left: 10px; }

.product-row-content { flex: 1; display: flex; flex-direction: column; min-width: 0; }

.product-row-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 4px; }
.product-row-date { font-size: 12px; color: var(--color-secondary); }
.product-row-rating { font-size: 12px; font-weight: 500; color: var(--color-secondary); }
/* --color-secondary, not --color-muted: muted only clears ~3.9:1 at
   this size against the card background, which fails WCAG AA's 4.5:1
   for normal text — same fix already applied to .chewy-card-rating
   .is-pending above for the identical reason. */
.product-row-rating.is-pending { color: var(--color-secondary); font-style: italic; }

.product-row-title { font-size: 20px; font-weight: 700; margin: 0 0 8px; line-height: 1.3; color: var(--color-ink); }
.product-row-title a { color: inherit; text-decoration: none; }
.product-row-title a:hover { text-decoration: underline; text-decoration-color: var(--color-coral); }

.product-row-blurb { font-size: 14px; line-height: 1.6; color: var(--color-secondary); margin: 0 0 16px; max-width: 60ch; }

.product-row-buy { display: flex; align-items: center; gap: 16px; margin-top: auto; }
/* .chewy-buy-btn defaults to width:100% for its original vertical-card
   context; a horizontal row needs the button sized to its label
   instead, or it stretches to fill the entire remaining row width. */
.product-row-buy .chewy-buy-btn { width: auto; flex: 0 0 auto; }
.product-row-price { font-size: 18px; font-weight: 700; color: var(--color-ink); }
.product-row-price.is-pending { font-size: 13px; font-weight: 500; color: var(--color-secondary); }

.product-row .chewy-affiliate-note { text-align: left; margin: 8px 0 0; }

@media (max-width: 640px) {
  .product-row { flex-direction: column; border-left-width: 4px; }
  .product-row-cover { width: 100%; }
  .product-row-title { font-size: 18px; }
  .product-row-buy { flex-direction: column; align-items: stretch; gap: 10px; }
  .product-row-buy .chewy-buy-btn { width: 100%; min-height: 44px; }
}

/* ===================================================================
   E-book rows — one book per row (ebooks.html). Per
   ebook-row-layout-design.md. Reuses .chewy-buy-btn, .chewy-card-price,
   .chewy-card-author, .chewy-card-rating, .chewy-card-related-link,
   .chewy-affiliate-note, and .badge from the card components above —
   everything below is new only for the row shape itself (portrait
   cover left, content right, price/CTA anchored at the row's end).
   =================================================================== */

.ebook-rows { display: flex; flex-direction: column; gap: 20px; }

.ebook-row {
  display: flex;
  gap: 24px;
  padding: 24px;
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}

.ebook-row-cover {
  position: relative;
  flex-shrink: 0;
  width: 180px;
  aspect-ratio: 3 / 4;
  border-radius: var(--radius-md);
  overflow: hidden;
  display: block;
  background: var(--color-photo);
  border: 1px solid var(--color-photo-border);
}
.ebook-row-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ebook-row-cover .badge { position: absolute; top: 10px; left: 10px; }
.ebook-row-cover:focus-visible { outline: 2px solid var(--color-coral); outline-offset: 2px; }

.ebook-row-content { flex: 1; display: flex; flex-direction: column; min-width: 0; }

.ebook-row-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 4px; }
.ebook-row-category { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; color: var(--color-secondary); }

.ebook-row-title { font-size: 20px; font-weight: 700; margin: 0 0 4px; line-height: 1.3; }
.ebook-row-title a { color: var(--color-ink); text-decoration: none; }
.ebook-row-title a:hover { text-decoration: underline; text-decoration-color: var(--color-coral); }
.ebook-row-title a:focus-visible { outline: 2px solid var(--color-coral); outline-offset: 2px; }

.ebook-row-excerpt { font-size: 14px; line-height: 1.6; color: var(--color-secondary); margin: 10px 0 4px; max-width: 60ch; }
.ebook-row-excerpt-more { display: none; }
.ebook-row-excerpt.is-expanded .ebook-row-excerpt-more { display: inline; }

.ebook-row-readmore {
  align-self: flex-start;
  background: none;
  border: none;
  padding: 0;
  margin: 0 0 14px;
  font-size: 13px;
  font-weight: 600;
  color: var(--color-coral-dark);
  cursor: pointer;
  font-family: inherit;
}
.ebook-row-readmore:hover { text-decoration: underline; }
.ebook-row-readmore:focus-visible { outline: 2px solid var(--color-coral); outline-offset: 3px; border-radius: 3px; }

.ebook-row-buy { display: flex; align-items: center; gap: 16px; margin-top: auto; }
/* Same fix as .product-row-buy above — .chewy-buy-btn's default
   width:100% is correct for a vertical card, not a horizontal row. */
.ebook-row-buy .chewy-buy-btn { width: auto; flex: 0 0 auto; }

.ebook-row-details-link { font-size: 13px; font-weight: 600; color: var(--color-coral-dark); text-decoration: none; margin-left: auto; }
.ebook-row-details-link:hover { text-decoration: underline; }
.ebook-row-details-link:focus-visible { outline: 2px solid var(--color-coral); outline-offset: 2px; }

.ebook-row .chewy-affiliate-note { text-align: left; margin: 8px 0 0; }

@media (max-width: 640px) {
  .ebook-row { flex-direction: column; }
  .ebook-row-cover { width: 100%; }
  .ebook-row-title { font-size: 18px; }
  .ebook-row-buy { flex-direction: column; align-items: stretch; gap: 10px; }
  .ebook-row-buy .chewy-buy-btn { width: 100%; min-height: 44px; }
  .ebook-row-details-link { margin-left: 0; text-align: center; }
}

/* ===================================================================
   E-book detail page (pages/ebooks/*.html) — v17 redesign. A real
   product page, not a lead-magnet download page, so deliberately NOT
   reusing .guide-page's narrow centered layout — a wider header with
   the cover and purchase info side by side, matching the row's own
   left/right relationship rather than inventing a third pattern.
   =================================================================== */

/* max-width grew from 1200px (v27) to 1400px, but padding-left grew by
   exactly half that 200px increase (24px -> 124px) while padding-right
   stayed at 24px -- with margin: 0 auto splitting the leftover space
   evenly, that extra padding-left exactly cancels the leftward shift
   auto-centering would otherwise cause, so the cover's left edge stays
   pinned in place and the whole extra 200px of width shows up only on
   the right, pushing the video column further right without moving
   the cover. See ebooks-design-notes.md v28 for the arithmetic and its
   verified range (holds exactly at viewport widths >=1400px; below
   that the box just fills the viewport and the pinning approximates
   rather than matches exactly -- verified acceptable down to 1280px). */
.ebook-detail { max-width: 1400px; margin: 0 auto; padding: 40px 24px 64px 124px; }

/* Three-column layout: cover (left) and title (middle) start on the
   same row, since neither has anything placed above it in its own
   column -- that's what "cover starts the same line as title" means
   literally, and it's the same shared-row-alignment mechanism used
   for cover/video parallelism below, not a new technique. Left column
   continues below the cover with price, Buy Now, and reviews. Middle
   column continues below the title with author, then description,
   then the related-hub link -- physically between the cover and the
   video, left to right. Right column holds only the video, with no
   heading above it (the "Preview" label was removed in v28 so the
   video frame itself is the column's first child), which is why its
   own top lands exactly on that same shared row, not just close to it.

   Desktop wireframe:
     +-----------+  TRAINING                    +----------------+
     |           |  Start Calm: Raising a         | Preview          |
     |  [cover]  |  Confident Puppy in the         | [ video, 9:16,    |
     |           |  First 16 Weeks                 |   compact,         |
     +-----------+  Frolicy                        |   expands on       |
     |  $9.00     |  ---------------------------   |   click ]           |
     | [ Buy Now ]|  About this book                +----------------+
     | Not yet    |  <description text>
     |  available |  ---------------------------
     +-----------+  Related: hub link
     |  Reviews   |
     |  Not yet   |
     |  rated     |
     +-----------+

   All three columns are placed by grid-column alone (1, 2, 3) with no
   explicit grid-row -- default grid auto-placement puts anything
   without a row assignment into row 1, so .ebook-detail-left,
   .ebook-detail-middle, and .ebook-detail-right all start there
   together, the same way .ebook-detail-heading and the two columns
   shared row 2 in the previous version of this layout.

   DOM order is left, then middle, then right -- Buy Now (left) comes
   before the related link (middle) comes before Play trailer (right)
   in the markup, which is also their left-to-right visual order, so
   the keyboard TAB ORDER is Buy Now -> Related link -> Play trailer.
   That's a genuine change from every earlier version of this page
   (which all had Play trailer before Related link) -- it falls
   directly out of the video now being the last column, not a
   separate accessibility decision made on its own.

   Mobile (<=900px) collapses .ebook-detail-layout to plain block
   flow, so the three columns render in that same DOM order --
   .ebook-detail-left in full (cover, price, Buy Now, reviews), then
   .ebook-detail-middle in full (title, author, description, related),
   then .ebook-detail-right (video) -- see the wireframe in the
   @media block below. */
.ebook-detail-layout {
  display: grid;
  grid-template-columns: 240px 1fr 360px;
  column-gap: 64px;
}

.ebook-detail-left { grid-column: 1; display: flex; flex-direction: column; }
.ebook-detail-middle { grid-column: 2; display: flex; flex-direction: column; }
.ebook-detail-right { grid-column: 3; display: flex; flex-direction: column; }
/* Video is the only thing in the right column, so it's always this
   column's first (and only) child, but .ebook-detail-section's
   default margin-top: 40px -- meant for spacing between stacked
   sections -- would otherwise push it 40px below the shared row top,
   out of alignment with the cover and title. Zeroed here for the
   same reason it was zeroed for .ebook-detail-right in the previous
   version of this layout. */
.ebook-detail-right > .ebook-detail-section:first-child { margin-top: 0; }

.ebook-detail-cover {
  width: 240px;
  aspect-ratio: 3 / 4;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: 0 16px 32px -16px rgba(54, 47, 43, 0.28);
  margin-bottom: 20px;
}
/* object-position: top -- the source art (1587x2245, ~0.707 ratio) is
   proportionally taller than this 3:4 (0.75) box, so object-fit: cover
   has to crop ~20px of height somewhere. Default center position
   split that crop evenly top and bottom, clipping the "FROLICY"
   label printed near the top of the artwork; biasing to top means
   all of that crop comes off the bottom instead, where there's
   nothing meaningful to lose. */
.ebook-detail-cover img { width: 100%; height: 100%; object-fit: cover; object-position: top; display: block; }

.ebook-detail-price { font-size: 24px; font-weight: 700; color: var(--color-ink); margin-bottom: 12px; text-align: center; }
.ebook-detail-buy-row { display: flex; }
.ebook-detail-buy-row .chewy-buy-btn { width: 100%; min-height: 44px; }
.ebook-detail-left .chewy-affiliate-note { margin-top: 8px; }
.ebook-detail-left .ebook-detail-reviews-section { margin-top: 32px; }

.ebook-detail-category { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; color: var(--color-secondary); margin-bottom: 8px; }
.ebook-detail-title { font-size: 32px; font-weight: 700; line-height: 1.2; margin: 0 0 8px; text-wrap: balance; }
.ebook-detail-author { font-size: 15px; color: var(--color-secondary); }

.ebook-detail-section { margin-top: 40px; }
.ebook-detail-section h2 { font-size: 18px; font-weight: 700; margin: 0 0 12px; }
.ebook-detail-description { font-size: 16px; line-height: 1.7; color: var(--color-secondary); max-width: 65ch; }

/* Table of contents: reuses .ebook-detail-section's standard 40px
   margin-top like every other section in this column, so the gap
   above .ebook-detail-toc-frame matches the description-to-related
   gap exactly -- not a special-cased distance, the same rule applied
   again. The border-top/border-bottom frame is the "line above and
   below the list" from the reference layout; padding inside it (not
   margin) keeps those two rules a fixed, predictable distance from
   the list regardless of how many chapters or parts a given book has. */
.ebook-detail-toc-frame {
  border-top: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
  padding: 20px 0;
}
.ebook-detail-toc-part {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--color-secondary);
  margin: 20px 0 8px;
}
.ebook-detail-toc-part:first-child { margin-top: 0; }
.ebook-detail-toc-chapter { font-size: 15px; font-weight: 600; line-height: 1.6; color: var(--color-ink); margin: 0 0 4px; }
.ebook-detail-toc-extra { font-size: 14px; font-style: italic; color: var(--color-secondary); margin: 16px 0 0; }

/* Reviews: honest placeholder only -- .chewy-card-rating.is-pending
   ("Not yet rated") until real reviews exist. Never swap this for an
   invented star count or fabricated review text (CLAUDE.md section
   6) -- this section exists here, ready to hold real reviews the
   moment they exist, not to simulate them in the meantime.

   Two .ebook-detail-reviews-section blocks exist on this page by
   design, not duplication: the left-column one (near the buy box) is
   a compact summary whose heading is a same-page link down to
   #book-reviews, the full reviews section at the end of the middle
   column -- the standard "rating badge near purchase, full reviews
   further down" pattern. Both show the same honest "Not yet rated"
   placeholder today because there is only one real data source; that
   will stop being true the moment real review data exists, at which
   point the left one should likely show a star summary and the
   #book-reviews one the actual review list -- not a sign of the
   pattern being wrong today. */
.ebook-detail-reviews-section .chewy-card-rating { font-size: 14px; }
.ebook-detail-reviews-jump { color: inherit; text-decoration: none; }
.ebook-detail-reviews-jump:hover { text-decoration: underline; }
.ebook-detail-reviews-section .btn { margin-top: 12px; }

/* Review submission form + review list. Reuses the same field/error
   visual language as .auth-modal-field/.auth-modal-error below rather
   than inventing a second form style. */
.ebook-review-form-wrap { margin-top: 20px; max-width: 480px; }
.ebook-review-form-field { display: block; margin-bottom: 14px; }
.ebook-review-form-field label { display: block; font-size: 13px; font-weight: 600; margin-bottom: 6px; color: var(--color-ink); }
.ebook-review-form-field select,
.ebook-review-form-field textarea {
  width: 100%;
  padding: 10px 12px;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  font-family: var(--font-sans);
  font-size: 14px;
  box-sizing: border-box;
  resize: vertical;
}
.ebook-review-form-field input[type="file"] { font-size: 13px; }
.ebook-review-form-error { font-size: 13px; color: var(--color-coral-dark); margin: 0 0 12px; }
.ebook-review-form-error:empty { display: none; }

.ebook-review-list { margin-top: 24px; display: flex; flex-direction: column; gap: 24px; max-width: 640px; }
.ebook-review { border-top: 1px solid var(--color-border); padding-top: 20px; }
.ebook-review-header { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.ebook-review-avatar { width: 40px; height: 40px; border-radius: 50%; object-fit: cover; display: block; }
.ebook-review-avatar-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-sage);
  color: var(--color-cream);
  font-weight: 700;
  font-size: 16px;
}
.ebook-review-name { font-size: 14px; font-weight: 600; color: var(--color-ink); }
.ebook-review-stars { font-size: 13px; color: var(--color-coral-dark); letter-spacing: 1px; }
.ebook-review-body { font-size: 15px; line-height: 1.6; color: var(--color-ink); margin: 0; }

/* Shared login/create-account modal (auth-modal-*). UI-only: the two
   submit buttons are permanently `disabled`, with a plain-language
   note above each one ("Accounts are not live yet") rather than
   letting a click silently do nothing unexplained or, worse, faking
   a successful login. Same honest-placeholder principle as
   .chewy-card-rating.is-pending and the disabled Buy Now button
   elsewhere on this page -- never build something that LOOKS live
   before it is. See ebooks-design-notes.md v31. */
.auth-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(54, 47, 43, 0.5);
  display: grid;
  place-items: center;
  padding: 24px;
  z-index: 100;
}
.auth-modal-overlay[hidden] { display: none; }

.auth-modal {
  position: relative;
  background: var(--color-card);
  border-radius: var(--radius-lg);
  width: min(400px, 100%);
  padding: 32px;
  box-shadow: 0 24px 48px -12px rgba(0, 0, 0, 0.3);
}

.auth-modal-close {
  position: absolute;
  top: 16px;
  right: 16px;
  background: none;
  border: none;
  padding: 4px;
  color: var(--color-secondary);
  cursor: pointer;
  line-height: 0;
}
.auth-modal-close:hover { color: var(--color-ink); }

.auth-modal h2 { font-size: 20px; font-weight: 700; margin: 0 0 8px; }
.auth-modal-subtitle { font-size: 14px; color: var(--color-secondary); margin: 0 0 24px; }

.auth-modal-tabs { display: flex; gap: 16px; margin-bottom: 20px; border-bottom: 1px solid var(--color-border); }
.auth-modal-tab {
  background: none;
  border: none;
  padding: 8px 2px 12px;
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
  color: var(--color-secondary);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.auth-modal-tab.is-active { color: var(--color-ink); border-bottom-color: var(--color-coral); }

.auth-modal-panel[hidden] { display: none; }
.auth-modal-field { display: block; margin-bottom: 14px; }
.auth-modal-field label { display: block; font-size: 13px; font-weight: 600; margin-bottom: 6px; color: var(--color-ink); }
.auth-modal-field input {
  width: 100%;
  padding: 10px 12px;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  font-family: var(--font-sans);
  font-size: 14px;
  box-sizing: border-box;
}
.auth-modal-field input:focus-visible { outline: 2px solid var(--color-coral); outline-offset: 1px; }

.auth-modal-avatar-row { display: flex; align-items: center; gap: 12px; }

.auth-modal-avatar-preview,
.auth-modal-avatar-placeholder {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  flex-shrink: 0;
  object-fit: cover;
}

.auth-modal-avatar-preview[hidden] { display: none; }

.auth-modal-avatar-placeholder {
  background: var(--color-sage-tint);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
}

.auth-modal-field-avatar input[type="file"] { font-size: 13px; flex: 1; min-width: 0; }
.auth-modal-field-hint { font-size: 12px; color: var(--color-muted); margin: 6px 0 0; }

.auth-modal-note { font-size: 13px; color: var(--color-secondary); margin: 4px 0 16px; }
.auth-modal-note[hidden] { display: none; }
.auth-modal-error { font-size: 13px; color: var(--color-coral-dark); margin: 0 0 12px; min-height: 0; }
.auth-modal-error:empty { display: none; }

.auth-modal-success { font-size: 13px; color: var(--color-sage-dark); margin: 0 0 12px; min-height: 0; }
.auth-modal-success:empty { display: none; }

/* Shares .auth-modal-guest's plain-text-link look (background: none,
   underline, coral-dark) rather than duplicating it under a new name
   -- both "Forgot password?" and "Back to log in" reuse this one
   class instead of one each. */
.auth-modal-forgot-link {
  display: block;
  width: auto;
  background: none;
  border: none;
  padding: 0;
  margin: 0 0 16px;
  font-family: var(--font-sans);
  font-size: 13px;
  color: var(--color-coral-dark);
  text-decoration: underline;
  cursor: pointer;
}

.auth-modal-guest {
  display: block;
  width: 100%;
  text-align: center;
  margin-top: 16px;
  background: none;
  border: none;
  font-family: var(--font-sans);
  font-size: 14px;
  color: var(--color-coral-dark);
  text-decoration: underline;
  cursor: pointer;
  padding: 4px;
}
.auth-modal-guest[hidden] { display: none; }

/* Checkout modal -- wider than .auth-modal since it hosts Stripe's
   Embedded Checkout iframe, which needs real width to lay out payment
   fields comfortably. Same overlay/close/focus pattern as the auth
   modal on purpose, not reinvented. */
.checkout-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(54, 47, 43, 0.5);
  display: grid;
  place-items: center;
  padding: 24px;
  z-index: 100;
}
.checkout-modal-overlay[hidden] { display: none; }

.checkout-modal {
  position: relative;
  background: var(--color-card);
  border-radius: var(--radius-lg);
  width: min(560px, 100%);
  max-height: 90vh;
  overflow-y: auto;
  padding: 40px 24px 24px;
  box-shadow: 0 24px 48px -12px rgba(0, 0, 0, 0.3);
}

.checkout-modal-close {
  position: absolute;
  top: 16px;
  right: 16px;
  background: none;
  border: none;
  padding: 4px;
  color: var(--color-secondary);
  cursor: pointer;
  line-height: 0;
  z-index: 1;
}
.checkout-modal-close:hover { color: var(--color-ink); }
.checkout-modal-close:focus-visible { outline: 2px solid var(--color-coral-dark); outline-offset: 2px; }

/* Video: NOT autoplay, NOT hover-triggered — a deliberate, explicit
   click/Enter/Space swaps the poster <img> for a real <video controls>,
   per the e-book detail video IIFE in js/main.js. The poster is
   optional (a book's data-detail-video can exist before its poster
   art does); when present it's plain markup, not set via the CSS
   `poster` attribute, because it needs to be swappable back in after
   a collapse-to-poster the same way it started. Framed at 9:16 to
   match a real vertical trailer without letterboxing.

   Sized to read as a secondary, optional visual cue rather than
   competing with the cover/description for attention: starts compact
   (200px) and expands to 360px once a real <video> exists in the
   frame -- a fixed target, not 100%, because .ebook-detail-right is
   now a wide, unconstrained flex column (it used to be a fixed
   360px-wide grid track before v25, where 100% and 360px were the
   same number; now the right column can be 700px+ wide, and 100%
   there would blow the video up far past "secondary visual cue" into
   dominating the page). `:has()` detects the swap purely from markup —
   wireEbookDetailVideo() replaces the poster <img> with a <video>
   child on click, so this selector matches the instant that swap
   happens, no JS coordination needed. Browsers without :has() support
   simply keep the compact frame after clicking Play — video still
   plays, controls still work, it just doesn't grow; not a functional
   failure, just a missed visual flourish. */
.ebook-detail-video-frame {
  position: relative;
  width: 100%;
  max-width: 200px;
  aspect-ratio: 9 / 16;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-photo);
  border: 1px solid var(--color-photo-border);
  box-shadow: 0 14px 30px -10px rgba(54, 47, 43, 0.3);
  transition: max-width 0.25s ease;
}
.ebook-detail-video-frame:has(video) { max-width: 360px; }
.ebook-detail-video-frame img,
.ebook-detail-video-frame video { width: 100%; height: 100%; object-fit: cover; display: block; }

.ebook-detail-play-btn {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.94);
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
}
.ebook-detail-play-btn .icon { width: 22px; height: 22px; color: var(--color-coral-dark); margin-left: 3px; fill: currentColor; }
.ebook-detail-play-btn:focus-visible { outline: 2px solid var(--color-coral); outline-offset: 3px; }
.ebook-detail-play-btn[hidden] { display: none; }

.ebook-detail-related { font-size: 14px; font-weight: 500; color: var(--color-coral-dark); text-decoration: none; }
.ebook-detail-related:hover { text-decoration: underline; }

.ebook-detail-back-link { display: block; margin-bottom: 8px; }

/* Mobile wireframe (stacked, source order preserved):
     [ cover ]
     $9.00
     [ Buy Now ]
     Not yet available
     ------------------------
     Reviews
     Not yet rated
     ------------------------
     TRAINING
     Start Calm: Raising a Confident Puppy
     in the First 16 Weeks
     Frolicy
     ------------------------
     About this book
     <description>
     ------------------------
     Related: hub link
     ------------------------
     [ video frame ]
   .ebook-detail-layout drops the grid entirely so the browser just
   renders the three top-level children in DOM order — the whole left
   column (cover, price, Buy Now, reviews), then the whole middle
   column (title, author, description, related), then the right
   column (video) — no grid-area reassignment needed, which is exactly
   why the desktop grid never uses `order`.

   .ebook-detail's own padding-left (124px on desktop, see v28 comment
   above) is reset back to the same 24px as every other side here --
   that asymmetric padding exists purely to push the desktop video
   column further right without moving the desktop cover, and doing
   the same on mobile (where everything is a single centered column,
   not three side-by-side ones) would just shove the whole page off
   center for no reason. */
@media (max-width: 900px) {
  .ebook-detail { padding-left: 24px; }
  .ebook-detail-layout { display: block; }
  .ebook-detail-cover { width: 100%; max-width: 280px; margin: 0 auto 20px; }
  .ebook-detail-middle { margin-top: 40px; }
  .ebook-detail-right { margin-top: 40px; }
  .ebook-detail-video-frame { margin: 0 auto; }
}

@media (max-width: 640px) {
  .ebook-detail-title { font-size: 24px; }
}

.whats-inside {
  border-top: 1px solid var(--color-border);
  margin-top: 28px;
  padding-top: 20px;
  text-align: left;
}

.whats-inside .form-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--color-secondary);
  margin-bottom: 10px;
}

.whats-inside ul {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 13px;
  color: var(--color-secondary);
}

.whats-inside li {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 5px 0;
}

.whats-inside .icon { color: var(--color-sage); width: 16px; height: 16px; margin-top: 2px; }

/* Optional "Related: [book] (e-book) ->" line -- only the 3 guides with
   a genuine content overlap carry one (generate_guides.py's
   related_ebook_html()), so this rule sits unused on the other 27 guide
   pages rather than needing its own conditional wrapper in the template. */
.guide-related-link {
  display: block;
  margin-top: 14px;
  font-size: 14px;
  font-weight: 500;
  color: var(--color-coral-dark);
  text-decoration: none;
}
.guide-related-link:hover { text-decoration: underline; }

.back-to-library {
  text-align: center;
  margin-top: 28px;
  font-size: 13px;
  font-weight: 500;
  color: var(--color-secondary);
}

.back-to-library:hover { color: var(--color-ink); }

/* ===================================================================
   Instant-download (go/) page
   =================================================================== */

.go-page {
  min-height: 60vh;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 40px 24px;
}

.go-page p { color: var(--color-secondary); font-size: 14px; margin-top: 8px; }

/* ===================================================================
   Article page
   =================================================================== */

.article-page { padding-bottom: 64px; }

.article-meta {
  display: flex;
  align-items: center;
  gap: 16px;
  margin: 20px 0 12px;
}

.article-meta .guide-card-meta { display: inline-flex; }

.article-title {
  font-size: 32px;
  line-height: 1.25;
  margin-bottom: 24px;
  max-width: 680px;
}

.article-hero {
  border-radius: var(--radius-lg);
  overflow: hidden;
  margin-bottom: 28px;
  height: 320px;
}

.article-hero img { width: 100%; height: 100%; object-fit: cover; display: block; }

.article-intro {
  font-size: 17px;
  line-height: 1.65;
  color: var(--color-ink);
  margin-bottom: 8px;
}

.article-section { margin: 32px 0; }
.article-section h2 { font-size: 20px; margin-bottom: 10px; }
.article-section p { font-size: 15px; line-height: 1.7; color: var(--color-secondary); }

.article-cta {
  background: var(--color-honey-tint);
  border-radius: var(--radius-lg);
  padding: 22px 24px;
  margin: 40px 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
}

.article-cta p {
  font-size: 14px;
  color: var(--color-honey-dark);
  font-weight: 500;
  margin: 0;
  max-width: 480px;
}

.related-guides { margin-top: 44px; border-top: 1px solid var(--color-border); padding-top: 28px; }
.related-guides .form-title { font-size: 16px; margin-bottom: 16px; }

.related-guides-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
}

@media (max-width: 600px) {
  .article-hero { height: 200px; }
  .related-guides-grid { grid-template-columns: 1fr; }
  .article-title { font-size: 26px; }
}

/* ===================================================================
   Generic content page (about, shop, legal)
   =================================================================== */

.prose { max-width: 720px; margin: 0 auto; }
.prose h1 { font-size: 32px; margin-bottom: 20px; }
.prose h2 { font-size: 20px; margin: 32px 0 12px; }
.prose p { font-size: 15px; color: var(--color-secondary); line-height: 1.7; margin-bottom: 14px; }
.prose ul { color: var(--color-secondary); font-size: 15px; line-height: 1.7; padding-left: 20px; }

.about-photo {
  border-radius: var(--radius-lg);
  overflow: hidden;
  margin: 28px 0;
  height: 360px;
}

.about-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }

@media (max-width: 600px) {
  .about-photo { height: 220px; }
}

/* ===================================================================
   Topic hub pages
   =================================================================== */

.hub-hero {
  position: relative;
  padding: 72px 0;
  overflow: hidden;
}

.hub-hero-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.hub-hero-bg img { width: 100%; height: 100%; object-fit: cover; display: block; }

.hub-hero-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(54,47,43,0.15) 0%, rgba(54,47,43,0.55) 100%);
}

.hub-hero .container { position: relative; z-index: 1; }

.hub-hero-eyebrow {
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #FBF6EE;
  font-weight: 600;
  margin-bottom: 14px;
  opacity: 0.9;
}

.hub-hero h1 {
  font-size: 40px;
  color: #FFFDF9;
  max-width: 640px;
  margin-bottom: 14px;
}

.hub-hero-sub {
  font-size: 16px;
  color: #FBF6EE;
  max-width: 520px;
  opacity: 0.92;
}

.hub-hero-stats {
  display: flex;
  gap: 20px;
  margin-top: 22px;
  font-size: 13px;
  color: #FBF6EE;
  font-weight: 500;
}

@media (max-width: 700px) {
  .hub-hero { padding: 48px 0; }
  .hub-hero h1 { font-size: 28px; }
}

.hub-breadcrumb {
  font-size: 13px;
  color: var(--color-muted);
  margin: 18px 0 4px;
}

.hub-breadcrumb a { color: var(--color-coral-dark); text-decoration: none; }
.hub-breadcrumb a:hover { text-decoration: underline; }

.hub-why-matters {
  max-width: 720px;
}

.hub-why-matters h2 { font-size: 24px; margin-bottom: 14px; }
.hub-why-matters p { font-size: 15px; color: var(--color-secondary); line-height: 1.75; }

.roadmap-list {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.roadmap-step {
  display: flex;
  gap: 18px;
  align-items: flex-start;
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 20px 24px;
}

.roadmap-step-number {
  flex: 0 0 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--color-coral-tint);
  color: var(--color-coral-dark);
  font-weight: 700;
  font-size: 15px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.roadmap-step-body h3 { font-size: 16px; margin: 2px 0 6px; }
.roadmap-step-body p { font-size: 14px; color: var(--color-secondary); line-height: 1.6; margin: 0; }

.faq-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.faq-item {
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 18px 22px;
}

.faq-item h3 { font-size: 15px; margin: 0 0 8px; }
.faq-item p { font-size: 14px; color: var(--color-secondary); line-height: 1.65; margin: 0; }

.hub-products {
  background: var(--color-sage-tint);
  border-radius: var(--radius-lg);
  padding: 28px 32px;
}

.hub-products h2 { font-size: 20px; margin-bottom: 6px; }
.hub-products-note { font-size: 13px; color: var(--color-sage-dark); margin-bottom: 16px; }
.hub-products-list { list-style: none; margin: 0 0 16px; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.hub-products-shop-link {
  display: inline-block;
  font-size: 13px;
  font-weight: 600;
  color: var(--color-sage-dark);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.hub-products-shop-link:hover { color: var(--color-coral-dark); }
.hub-products-list li { font-size: 14px; color: var(--color-secondary); line-height: 1.6; padding-left: 22px; position: relative; }
.hub-products-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 7px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-sage);
}

.hub-seasonal {
  display: flex;
  align-items: center;
  gap: 16px;
  background: var(--color-honey-tint);
  border-radius: var(--radius-lg);
  padding: 20px 26px;
}

.hub-seasonal .icon { width: 28px; height: 28px; color: var(--color-honey-dark); flex-shrink: 0; }
.hub-seasonal p { font-size: 14px; color: var(--color-honey-dark); margin: 0; line-height: 1.6; }

.related-topics-row {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

/* ===================================================================
   Interactive tools — shared component library
   Every tool (checker, checklist, planner, decoder) is built from these
   same pieces, so a new tool never needs new CSS.
   =================================================================== */

.tool-hero {
  padding: 48px 0 40px;
  background: var(--color-sage-tint);
}

.tool-hero-icon {
  width: 44px;
  height: 44px;
  color: var(--color-sage-dark);
  background: var(--color-card);
  border-radius: var(--radius-md);
  padding: 10px;
  margin-bottom: 16px;
}

.tool-hero h1 { font-size: 32px; margin-bottom: 10px; max-width: 640px; }
.tool-hero p { font-size: 15px; color: var(--color-sage-dark); max-width: 520px; margin: 0; }

.tool-panel {
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 28px;
}

.tool-search-row {
  display: flex;
  gap: 10px;
  margin-bottom: 18px;
}

.tool-search-row .field { margin-bottom: 0; flex: 1; }

.tool-select-row {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 18px;
}

.tool-select-row select.field { flex: 1; min-width: 160px; margin-bottom: 0; cursor: pointer; }

.tool-result-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.tool-result-card {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 16px 18px;
  background: #FFFDF9;
}

.tool-verdict {
  flex: 0 0 auto;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 5px 10px;
  border-radius: 999px;
  white-space: nowrap;
}

.tool-verdict.is-safe { background: var(--color-sage-tint); color: var(--color-sage-dark); }
.tool-verdict.is-toxic { background: var(--color-coral-tint); color: var(--color-coral-dark); }
.tool-verdict.is-caution { background: var(--color-honey-tint); color: var(--color-honey-dark); }

.tool-result-body h3 { font-size: 15px; margin: 0 0 4px; }
.tool-result-body p { font-size: 13px; color: var(--color-secondary); margin: 0; line-height: 1.55; }

.tool-empty-state {
  text-align: center;
  color: var(--color-muted);
  font-size: 14px;
  padding: 24px 0;
}

.content-disclaimer {
  max-width: 720px;
  margin: 0 auto;
  padding: 12px 24px 4px;
  color: var(--color-muted);
  font-size: 11px;
  line-height: 1.5;
  text-align: left;
}
.content-disclaimer a { color: inherit; text-decoration: underline; }

.checklist-progress {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 18px;
  font-size: 13px;
  font-weight: 600;
  color: var(--color-sage-dark);
}

.checklist-progress-bar {
  flex: 1;
  height: 8px;
  background: var(--color-sage-tint);
  border-radius: 999px;
  overflow: hidden;
}

.checklist-progress-fill {
  height: 100%;
  background: var(--color-sage);
  border-radius: 999px;
  transition: width 0.25s ease;
  width: 0%;
}

.checklist-group { margin-bottom: 22px; }
.checklist-group h3 { font-size: 14px; color: var(--color-muted); text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 10px; }

.checklist-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  margin-bottom: 8px;
  cursor: pointer;
  background: #FFFDF9;
}

.checklist-item input[type="checkbox"] {
  width: 18px;
  height: 18px;
  accent-color: var(--color-coral);
  flex-shrink: 0;
  cursor: pointer;
}

.checklist-item span { font-size: 14px; color: var(--color-ink); }
.checklist-item.is-checked span { color: var(--color-muted); text-decoration: line-through; }

.planner-timeline {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.planner-milestone {
  display: flex;
  gap: 18px;
  position: relative;
  padding-bottom: 26px;
}

.planner-milestone:last-child { padding-bottom: 0; }

.planner-milestone-marker {
  flex: 0 0 12px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--color-coral);
  margin-top: 4px;
  position: relative;
}

.planner-milestone:not(:last-child) .planner-milestone-marker::after {
  content: "";
  position: absolute;
  top: 12px;
  left: 5px;
  width: 2px;
  height: calc(100% + 14px);
  background: var(--color-border);
}

.planner-milestone-body h3 { font-size: 15px; margin: 0 0 4px; }
.planner-milestone-body .planner-when { font-size: 12px; font-weight: 600; color: var(--color-coral-dark); text-transform: uppercase; letter-spacing: 0.03em; margin-bottom: 4px; }
.planner-milestone-body p { font-size: 14px; color: var(--color-secondary); margin: 0; line-height: 1.6; }

.tool-decoder-question {
  margin-bottom: 20px;
}

.tool-decoder-question label { display: block; font-size: 14px; font-weight: 600; margin-bottom: 8px; }
.tool-decoder-question .tool-choice-row { display: flex; gap: 8px; flex-wrap: wrap; }

.tool-choice-btn {
  border: 1px solid var(--color-border);
  background: #FFFDF9;
  border-radius: var(--radius-sm);
  padding: 9px 16px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  color: var(--color-secondary);
  font-family: var(--font-sans);
}

.tool-choice-btn.is-active {
  background: var(--color-coral);
  border-color: var(--color-coral);
  color: #FFFDF9;
  font-weight: 600;
}

.tool-verdict-panel {
  margin-top: 22px;
  padding: 20px 24px;
  border-radius: var(--radius-lg);
  display: none;
}

.tool-verdict-panel.is-visible { display: block; }
.tool-verdict-panel.is-good { background: var(--color-sage-tint); }
.tool-verdict-panel.is-warn { background: var(--color-honey-tint); }
.tool-verdict-panel.is-urgent { background: var(--color-coral-tint); border: 1px solid var(--color-coral); }
.tool-verdict-panel h3 { font-size: 16px; margin: 0 0 8px; }
.tool-verdict-panel p { font-size: 14px; margin: 0; line-height: 1.6; }

.hub-tools-callout {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  background: var(--color-coral-tint);
  border-radius: var(--radius-lg);
  padding: 22px 28px;
}

.hub-tools-callout-text h3 { font-size: 17px; margin: 0 0 4px; color: var(--color-coral-dark); }
.hub-tools-callout-text p { font-size: 13px; color: var(--color-coral-dark); margin: 0; opacity: 0.85; }

@media (max-width: 600px) {
  .tool-panel { padding: 20px; }
  .tool-search-row, .tool-select-row { flex-direction: column; }
}

/* ===================================================================
   Footer
   =================================================================== */

.site-footer {
  border-top: 1px solid var(--color-border);
  padding: 28px 0;
  margin-top: 40px;
}

.site-footer .container {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  font-size: 12px;
  color: var(--color-muted);
}

.footer-links { display: flex; gap: 18px; flex-wrap: wrap; }

/* ===================================================================
   Homepage: intent-based discovery ("What brings you here?")
   =================================================================== */

.intent-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 18px;
}

.intent-card {
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 22px 20px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.intent-card-emoji { font-size: 26px; line-height: 1; margin-bottom: 6px; }
.intent-card h3 { font-size: 16px; margin: 0 0 4px; color: var(--color-coral-dark); }
.intent-card p { font-size: 13px; color: var(--color-secondary); margin: 0 0 14px; }

.intent-card-links {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: auto;
}

.intent-card-links a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--color-ink);
  background: var(--color-strip-bg);
  border-radius: var(--radius-sm);
  padding: 9px 12px;
  transition: background 0.15s ease;
}

.intent-card-links a:hover { background: var(--color-coral-tint); color: var(--color-coral-dark); }
.intent-card-links a .icon { width: 14px; height: 14px; flex-shrink: 0; opacity: 0.6; }

@media (max-width: 900px) {
  .intent-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 600px) {
  .intent-grid { grid-template-columns: 1fr; }
}

/* ===================================================================
   Homepage: "Not sure what you need?" decision helper
   =================================================================== */

.decision-helper {
  background: var(--color-sage-tint);
  border-radius: var(--radius-xl);
  padding: 32px;
}

.decision-helper-head { margin-bottom: 18px; }
.decision-helper-head h2 { font-size: 22px; margin-bottom: 6px; color: var(--color-sage-dark); }
.decision-helper-head p { font-size: 14px; color: var(--color-secondary); }

.decision-options {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 4px;
}

.decision-option {
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
  color: var(--color-sage-dark);
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: 999px;
  padding: 10px 18px;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.decision-option:hover { border-color: var(--color-sage); }

.decision-option.is-active {
  background: var(--color-sage);
  border-color: var(--color-sage);
  color: #fff;
}

.decision-result {
  display: none;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid var(--color-border);
}

.decision-result.is-visible { display: flex; }

.decision-result p { font-size: 14px; color: var(--color-sage-dark); margin: 0; max-width: 460px; }

.footer-links a:hover { color: var(--color-ink); }

/* ===================================================================
   About / Our Story — Hank tribute hero
   ===================================================================
   Color note: pure --color-coral (#E8734A) measures ~2.8:1 against
   --color-cream — below the 3:1 floor WCAG requires even for large
   text, so it's used here only as a fill behind cream text (the
   primary button, the play button) and never as a foreground text
   color on the cream page background. --color-coral-dark measures
   ~5:1 against cream, comfortably AA, so every piece of coral-family
   *text* on this page (inline emphasis, the "That's Frolicy." line,
   the outline button's border+label) uses coral-dark instead — same
   coral family, still passes the "AA contrast" requirement this
   section was built to. */
.about-hero { padding: 56px 0 72px; }
.about-hero-inner { text-align: center; }

/* Mobile-first: .about-hero-grid is plain block flow, so
   .about-copy-main (title through "That's Frolicy.") and
   .about-hero-frame simply stack in DOM order -- text first, video
   second. At >=901px it becomes a real 2-column grid, text left /
   video right, matching the request without ever touching `order`:
   DOM order already IS text-then-video, so the grid just places each
   item into the column its source position naturally lands in.
   Keeping DOM order in sync with visual order this way is the same
   principle used throughout this site's e-book detail page (see
   ebooks-design-notes.md) -- it's also why the video button now comes
   after the headline in tab order, not before, on every breakpoint,
   not just desktop where it's visually true. */
.about-hero-grid { display: block; }
@media (min-width: 901px) {
  .about-hero-grid { display: grid; grid-template-columns: 1fr 380px; gap: 48px; align-items: start; }
  /* Qualified with the .about-hero-grid ancestor (not just the bare
     class) specifically so these outrank .about-copy-main and
     .about-hero-frame's own base rules further down the file --
     equal-specificity selectors fall back to source order, and the
     base rules are declared later, so a bare-class override here was
     silently losing regardless of this media query matching. Caught
     via computed-style inspection (frame margin-top read 40px here
     even though this rule says 0) rather than assumed correct. */
  .about-hero-grid .about-copy-main { text-align: left; margin: 0; max-width: none; }
  .about-hero-grid .about-hero-frame { margin: 0; }
}

/* Frame reserves the 9:16 box before either the poster <img> or the
   swapped-in <video> loads, so nothing shifts on load -- height is
   capped per spec (min(78vh, 720px)) and width follows automatically
   from aspect-ratio, the same "cap one dimension, derive the other"
   approach used for the ebook cover elsewhere on this site. */
/* width, not height, is the driven dimension -- deriving width from a
   height cap (e.g. height: min(78vh, 720px)) computes a width that
   can exceed a narrow-but-tall mobile viewport (short vh cap still
   multiplies out to more than 375px wide), overflowing the page.
   Capping width by both the container (100%) and the vh-derived
   ceiling, then letting aspect-ratio derive height from that, keeps
   the box within whichever limit is smaller in either direction. At
   desktop this same formula still applies correctly with no changes
   needed -- "100%" there resolves against the 380px grid column
   instead of the full page width, so the frame is naturally capped
   by its column on typical screens. */
.about-hero-frame {
  position: relative;
  width: min(100%, calc(min(78vh, 720px) * 9 / 16));
  aspect-ratio: 9 / 16;
  margin: 40px auto 0;
  border-radius: 16px;
  overflow: hidden;
  background: var(--color-border);
  box-shadow: 0 20px 48px -16px rgba(54, 47, 43, 0.32);
}
.about-hero-frame img,
.about-hero-frame video { width: 100%; height: 100%; object-fit: cover; display: block; }

.about-hero-play-btn {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 76px;
  height: 76px;
  border-radius: 50%;
  background: var(--color-coral);
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 14px 32px rgba(54, 47, 43, 0.4);
  transition: transform 0.15s ease;
}
.about-hero-play-btn:hover { transform: translate(-50%, -50%) scale(1.06); }
.about-hero-play-btn:focus-visible { outline: 3px solid var(--color-coral-dark); outline-offset: 4px; }
.about-hero-play-btn .icon { width: 30px; height: 30px; color: var(--color-cream); fill: currentColor; stroke: none; margin-left: 4px; }

.about-hero-inner h1 { font-size: clamp(28px, 5vw, 40px); font-weight: 700; line-height: 1.25; color: var(--color-ink); margin: 0 0 28px; }
.about-hero-inner p { font-size: 17px; line-height: 1.6; color: var(--color-ink); margin: 0 0 20px; }
.about-emphasis { font-style: italic; font-weight: 600; color: var(--color-coral-dark); }
/* .about-hero-inner .about-standout, not just .about-standout --
   the generic .about-hero-inner p rule above is a class+element
   selector (specificity 0,1,1), which outranks a bare single-class
   selector (0,1,0) regardless of source order, silently overriding
   this rule's font-size and color. Matching that specificity with an
   extra ancestor class here, rather than relying on declaration
   order, is what actually wins the cascade -- caught by inspecting
   the computed style (17px ink) instead of trusting the source. */
.about-hero-inner .about-standout { font-size: clamp(24px, 4vw, 32px); font-weight: 700; color: var(--color-coral-dark); margin: 32px 0; }

.about-copy-main { max-width: 640px; margin: 0 auto; }
.about-copy-rest { max-width: 680px; margin: 56px auto 0; }

.about-cta-row { display: flex; justify-content: center; gap: 16px; margin-top: 40px; flex-wrap: wrap; }
.btn-outline-coral { background: transparent; color: var(--color-coral-dark); border: 1.5px solid var(--color-coral-dark); }
.btn-outline-coral:hover { background: rgba(177, 74, 38, 0.06); }
.about-cta-row .btn:focus-visible { outline: 3px solid var(--color-coral-dark); outline-offset: 3px; }

.about-memory-note { font-size: 14px; font-style: italic; color: var(--color-secondary); text-align: center; margin: 48px auto 0; }

@media (max-width: 640px) {
  .about-cta-row { flex-direction: column; align-items: stretch; }
  .about-cta-row .btn { width: 100%; }
  .about-hero-play-btn { width: 64px; height: 64px; }
  .about-hero-play-btn .icon { width: 24px; height: 24px; }
}

/* ===================================================================
   Profile page (profile.html, js/profile.js) -- mobile-first: base
   rules are the narrow-viewport layout (stacked avatar+name, full-
   width sections), widened at 640px rather than the other way around.
   =================================================================== */
.profile-page { padding: 40px 0 80px; }

.profile-signed-out { max-width: 480px; margin: 40px auto; text-align: center; }
.profile-signed-out h1 { margin: 0 0 12px; }
.profile-signed-out p { color: var(--color-secondary); margin: 0 0 24px; }

/* ===================================================================
   Reset password page (reset-password.html, js/reset-password.js) --
   same centered-card sizing as .profile-signed-out above, just left-
   aligned since it holds a form rather than a single CTA.
   =================================================================== */
.reset-password-page { padding: 40px 0 80px; }
.reset-password-card { max-width: 400px; margin: 40px auto; }
.reset-password-card h1 { margin: 0 0 12px; font-size: 24px; }
.reset-password-card p { color: var(--color-secondary); margin: 0 0 24px; }

.profile-signed-in { max-width: 680px; margin: 0 auto; }

.profile-header {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 16px;
  padding-bottom: 32px;
  margin-bottom: 32px;
  border-bottom: 1px solid var(--color-border);
}

.profile-avatar {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: var(--color-sage-tint);
  color: var(--color-sage-dark);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 28px;
  font-weight: 700;
  overflow: hidden;
  flex-shrink: 0;
}

.profile-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

.profile-header-text h1 { margin: 0 0 6px; font-size: 24px; }

.profile-email { display: flex; flex-direction: column; align-items: center; gap: 4px; margin: 0; font-size: 14px; color: var(--color-secondary); }

.profile-private-badge {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-muted);
  background: var(--color-strip-bg);
  padding: 3px 8px;
  border-radius: var(--radius-sm);
}

.profile-section { margin-bottom: 40px; }
.profile-section h2 { font-size: 18px; margin: 0 0 16px; }
.profile-section-empty { color: var(--color-secondary); font-size: 14px; margin: 0; }
.profile-section-empty[hidden] { display: none; }
.profile-section-empty a { color: var(--color-coral-dark); font-weight: 600; }

.profile-review-list,
.profile-purchase-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.profile-review-item { border: 1px solid var(--color-border); border-radius: var(--radius-md); padding: 16px; background: var(--color-card); }
.profile-review-item-header { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 8px; margin-bottom: 8px; }
.profile-review-item-title { font-weight: 600; font-size: 15px; }
.profile-review-item-title a { color: var(--color-ink); }
.profile-review-item-title a:hover { color: var(--color-coral-dark); }
.profile-review-item-body { font-size: 14px; line-height: 1.6; color: var(--color-secondary); margin: 0 0 8px; }
.profile-review-item-date { font-size: 12px; color: var(--color-muted); }

.profile-purchase-item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 14px 16px;
  background: var(--color-card);
}
.profile-purchase-item-title { font-weight: 600; font-size: 14px; margin-right: auto; }
.profile-purchase-item-title a { color: var(--color-ink); }
.profile-purchase-item-title a:hover { color: var(--color-coral-dark); }
.profile-purchase-item-date { font-size: 12px; color: var(--color-muted); flex-shrink: 0; }
.profile-purchase-download-error { font-size: 12px; color: var(--color-coral-dark); flex-basis: 100%; }
.profile-purchase-download-error:empty { display: none; }

@media (min-width: 640px) {
  .profile-header { flex-direction: row; text-align: left; }
  .profile-header-text h1 { font-size: 28px; }
  .profile-email { flex-direction: row; }
}
