/* ========== DYNA CATALOG + DETAIL PAGES ==========
   Inherits CSS vars + nav/footer/theme from styles.css.
   ================================================= */

.page-dyna,
.page-detail{
  position:relative;z-index:1;
  /* --content-top clears the fixed nav + ticker; see the layout tokens at the
     top of styles.css. Never restate the top value at a breakpoint. */
  padding:var(--content-top) 4rem 6rem;
  max-width:1320px;margin:0 auto;
}

/* ---------- COMPACT HERO ---------- */
.dyna-hero{
  position:relative;
  text-align:center;
  padding:2.5rem 0 1.25rem;
  margin-bottom:1rem;
  overflow:hidden;
}
.dyna-hero .hero-orb{
  position:absolute;
  border-radius:50%;
  pointer-events:none;
  filter:blur(110px);
  opacity:0.09;
}
.dyna-hero .hero-orb-1{
  width:480px;height:480px;
  background:radial-gradient(circle,var(--gold),transparent 70%);
  top:-240px;right:-140px;
}
.dyna-hero .hero-orb-2{
  width:360px;height:360px;
  background:radial-gradient(circle,var(--gold),transparent 70%);
  bottom:-220px;left:-120px;
  opacity:0.05;
}
.dyna-hero-inner{
  position:relative;
  z-index:1;
  max-width:760px;
  margin:0 auto;
}
.dyna-hero .section-tag{
  display:inline-block;
  font-family:'DM Mono',monospace;
  font-size:0.72rem;letter-spacing:0.25em;text-transform:uppercase;
  color:var(--gold);
  padding:0.35rem 0.9rem;
  border:1px solid var(--border);
  border-radius:100px;
  margin-bottom:1.5rem;
}
.dyna-hero h1{
  font-family:'Cormorant Garamond',serif;
  font-weight:300;
  font-size:clamp(2.6rem,5vw,4.4rem);
  line-height:1.05;
  color:var(--heading);
  letter-spacing:-0.01em;
}
.dyna-hero h1 em{
  font-style:italic;color:var(--gold);font-weight:400;
}
.dyna-hero .page-sub{
  margin:1.5rem auto 0;
  max-width:620px;
  color:var(--muted);
  font-size:1.05rem;line-height:1.7;
}
.strength-chips{
  list-style:none;
  padding:0;
  margin:2rem auto 0;
  display:flex;
  flex-wrap:wrap;
  justify-content:center;
  gap:0.6rem;
}
.strength-chips li{
  display:inline-flex;
  align-items:center;
  gap:0.5rem;
  padding:0.45rem 0.95rem;
  font-family:'DM Mono',monospace;
  font-size:0.7rem;letter-spacing:0.16em;text-transform:uppercase;
  color:var(--text);
  background:var(--bg2);
  border:1px solid var(--border);
  border-radius:100px;
  transition:border-color 0.25s,color 0.25s;
}
.strength-chips li::before{
  content:'';
  width:6px;height:6px;border-radius:50%;
  background:var(--gold);
  box-shadow:0 0 8px var(--gold);
}
.strength-chips li:hover{border-color:var(--gold);color:var(--heading)}

/* ---------- INDICATOR GRID ---------- */
.ind-grid{
  padding:0;
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(340px,1fr));
  gap:1.75rem;
}
.ind-card{
  position:relative;
  display:flex;flex-direction:column;
  background:var(--bg2);
  border:1px solid var(--border);
  border-radius:14px;
  overflow:hidden;
  text-decoration:none;
  color:inherit;
  transition:transform 0.35s ease,border-color 0.35s ease,box-shadow 0.35s ease;
}
.ind-card:hover{
  transform:translateY(-4px);
  border-color:var(--gold);
  box-shadow:0 18px 40px -20px rgba(0,0,0,0.55);
}
.ind-card.featured{
  border:2px solid var(--gold);
  box-shadow:0 0 32px -4px rgba(201,168,76,0.4),0 18px 44px -22px rgba(201,168,76,0.35);
}
.ind-card.featured:hover{
  box-shadow:0 0 40px -2px rgba(201,168,76,0.55),0 22px 52px -20px rgba(201,168,76,0.5);
}
/* Light mode: the dark-mode gold+glow loses contrast on cream backgrounds,
   so we thicken the ring, add a faint gold tint, and use a warmer shadow. */
html[data-theme="light"] .ind-card.featured{
  border-width:3px;
  background:linear-gradient(180deg,rgba(122,93,14,0.09),rgba(122,93,14,0.03) 55%,transparent);
  box-shadow:0 0 28px -2px rgba(122,93,14,0.5),0 14px 32px -14px rgba(122,93,14,0.55);
}
html[data-theme="light"] .ind-card.featured:hover{
  box-shadow:0 0 38px 0 rgba(122,93,14,0.65),0 20px 44px -16px rgba(122,93,14,0.7);
}
.ind-featured-badge,.ind-soon-badge{
  position:absolute;
  top:0.9rem;right:0.9rem;
  z-index:2;
  display:inline-block;
  padding:0.32rem 0.7rem;
  font-family:'DM Mono',monospace;
  font-size:0.62rem;font-weight:700;letter-spacing:0.22em;text-transform:uppercase;
  /* This chip is dark in *both* themes — it floats over a chart screenshot, not
     over the page — so it takes fixed colours rather than theme tokens. The
     light-mode gold is tuned for cream and would go nearly invisible here. */
  color:#E8C97A;
  background:rgba(10,14,26,0.78);
  border:1px solid #C9A84C;
  border-radius:100px;
  backdrop-filter:blur(4px);
  pointer-events:none;
}
/* "Coming soon": the same floating chip as Featured, in neutral slate rather
   than gold — gold is a curation signal and this is a state, not a compliment.
   It shows when an indicator has no links.txt entry, so it appears the moment a
   folder is dropped in and clears itself the day the script URL is added; there
   is no slug list to remember. It shares Featured's top-right slot, and the two
   would overlap — a coming-soon indicator has nothing to feature yet, so the
   collision is unreachable rather than handled. */
.ind-soon-badge{
  color:#C3D0E6;
  border-color:#7C8DB0;
}
/* Tier badge. Solid blue so it reads as a product-tier fact, clearly distinct
   from the outlined gold Featured badge (a curation choice). Sits top-left;
   Featured sits top-right, so both can show at once.
   Uses --accent-deep, not --accent: this is 0.62rem uppercase mono, far below
   WCAG's large-text threshold, so #fff on the lighter --accent came to 3.85:1. */
.ind-pro-badge{
  position:absolute;
  top:0.9rem;left:0.9rem;
  z-index:2;
  display:inline-block;
  padding:0.32rem 0.7rem;
  font-family:'DM Mono',monospace;
  font-size:0.62rem;font-weight:700;letter-spacing:0.22em;text-transform:uppercase;
  color:#fff;
  background:var(--accent-deep);
  border:1px solid var(--accent-deep);
  border-radius:100px;
  box-shadow:0 4px 14px -4px rgba(44,102,224,0.6);
  pointer-events:none;
}
html[data-theme="light"] .ind-pro-badge{
  box-shadow:0 4px 14px -4px rgba(42,98,214,0.5);
}
.ind-thumb{
  aspect-ratio:16/9;
  overflow:hidden;
  background:var(--bg3);
  border-bottom:1px solid var(--border);
}
/* <picture> is inline by default, which would collapse the img's height:100%
   against an auto-height box. Make it fill the 16/9 frame instead. */
.ind-thumb picture{display:block;width:100%;height:100%}
.ind-thumb img{
  width:100%;height:100%;object-fit:cover;
  transition:transform 0.6s ease,filter 0.6s ease;
  filter:saturate(0.92);
}
.ind-card:hover .ind-thumb img{
  transform:scale(1.04);
  filter:saturate(1.05);
}
.ind-body{
  padding:1.4rem 1.5rem 1.6rem;
  display:flex;flex-direction:column;gap:0.75rem;
  flex:1;
}
/* Every property this box renders is named here, including margin-bottom, which
   the class did not previously declare. The card title used to be an <h3> and
   inherited 0.75rem from styles.css's bare `h3` rule; promoting it to <h2> for
   the heading-order fix would have swapped in `h2`'s 1.25rem and quietly opened
   the gap to the blurb by half a rem on all 21 cards. The value is pinned to
   what the page already rendered, and the rule now hangs off the class alone —
   so the tag can change again without moving the layout. */
.ind-title{
  font-family:'Cormorant Garamond',serif;
  font-weight:400;
  font-size:1.55rem;line-height:1.2;
  color:var(--heading);
  letter-spacing:-0.005em;
  margin-bottom:0.75rem;
}
.ind-blurb{
  color:var(--muted);
  font-size:0.93rem;line-height:1.65;
  display:-webkit-box;
  -webkit-line-clamp:3;
  line-clamp:3;
  -webkit-box-orient:vertical;
  overflow:hidden;
}
/* The card is an <article>, not an <a>, because it now carries two
   destinations. The title anchor stretches across the whole card so the card
   still behaves like one big click target, and .ind-tv lifts itself above that
   overlay so it wins the hit test inside its own box. Keeping the card an <a>
   and nesting the TradingView link inside it would be invalid HTML. */
.ind-card-link{
  color:inherit;
  text-decoration:none;
}
.ind-card-link::after{
  content:'';
  position:absolute;inset:0;
  z-index:1;
}
/* Keyboard parity: the stretched link's visible text is just the title, so the
   card itself has to show the focus state. */
.ind-card:focus-within{border-color:var(--gold)}
/* The site-wide ring in styles.css would draw a second one around the title text
   itself, inside the card ring below — two boxes for one focus. This link's
   indicator is the ::after overlay, so the element's own ring is turned off. It
   is a deliberate suppression, not the outline:none that #19 exists to prevent:
   the ring immediately below replaces it, drawn around the whole click target
   rather than the four words the anchor happens to wrap. */
.ind-card-link:focus-visible{outline:none}
.ind-card-link:focus-visible::after{
  outline:2px solid var(--gold);
  outline-offset:-4px;
  border-radius:12px;
}

.ind-actions{
  margin-top:auto;
  display:flex;align-items:center;justify-content:space-between;
  gap:0.75rem;flex-wrap:wrap;
}
.ind-cta{
  font-family:'DM Mono',monospace;
  font-size:0.72rem;letter-spacing:0.2em;text-transform:uppercase;
  color:var(--gold);
  transition:letter-spacing 0.3s ease;
}
.ind-card:hover .ind-cta{letter-spacing:0.28em}
/* Outbound link to the TradingView script. Deliberately quieter than the gold
   "Read more" — the detail page is the page we want read first. */
.ind-tv{
  position:relative;z-index:2;
  flex-shrink:0;
  padding:0.45rem 0.9rem;
  font-family:'DM Mono',monospace;
  font-size:0.66rem;letter-spacing:0.14em;text-transform:uppercase;
  color:var(--text);
  text-decoration:none;
  border:1px solid var(--border);
  border-radius:100px;
  transition:border-color 0.25s,color 0.25s,background 0.25s;
}
.ind-tv:hover,
.ind-tv:focus-visible{
  border-color:var(--gold);
  color:var(--gold);
  background:rgba(201,168,76,0.08);
}

/* ---------- DETAIL PAGE ---------- */
.page-detail{max-width:880px}

.detail-back,
.detail-footer-cta a{
  display:inline-flex;align-items:center;
  font-family:'DM Mono',monospace;
  font-size:0.75rem;letter-spacing:0.2em;text-transform:uppercase;
  color:var(--muted);
  text-decoration:none;
  transition:color 0.25s;
}
.detail-back:hover,
.detail-footer-cta a:hover{color:var(--gold)}

.detail-back{margin-bottom:2.5rem}

.detail-header{margin-bottom:3rem}
.detail-tier,.detail-soon{
  display:inline-block;
  margin-bottom:1rem;
  padding:0.34rem 0.75rem;
  font-family:'DM Mono',monospace;
  font-size:0.66rem;font-weight:700;letter-spacing:0.22em;text-transform:uppercase;
  color:#fff;
  background:var(--accent-deep); /* same reason as .ind-pro-badge */
  border-radius:100px;
}
/* Outlined, not filled: it sits beside the solid DYNA Pro chip and must read as
   a second, lesser fact about the same thing rather than a second tier. */
.detail-soon{
  margin-left:0.5rem;
  color:var(--muted);
  background:none;
  border:1px solid var(--border);
}
.detail-title{
  font-family:'Cormorant Garamond',serif;
  font-weight:300;
  font-size:clamp(2.2rem,4.5vw,3.6rem);
  line-height:1.08;
  color:var(--heading);
  letter-spacing:-0.01em;
  margin-bottom:2rem;
}
/* The "how do I get this" row. Rendered twice — under the title and again in
   the footer — so a reader who scrolled the whole page still has a way out
   that isn't back to the catalog. */
.detail-cta-row{
  display:flex;flex-wrap:wrap;gap:0.85rem;
  margin-bottom:2rem;
}
.btn-tv,
.detail-footer-cta .btn-tv{
  display:inline-block;
  padding:0.85rem 1.9rem;
  background:var(--gold);
  color:var(--bg);
  border:1px solid var(--gold);
  border-radius:100px;
  font-family:'DM Mono',monospace;
  font-size:0.75rem;font-weight:500;
  letter-spacing:0.16em;text-transform:uppercase;
  text-decoration:none;
  transition:background 0.25s,border-color 0.25s;
}
.btn-tv:hover,
.detail-footer-cta .btn-tv:hover{
  background:var(--gold-light);
  border-color:var(--gold-light);
}
/* Matches .btn-primary: on the cream light-mode background the gold fill needs
   white text, not --bg. */
html[data-theme="light"] .btn-tv,
html[data-theme="light"] .detail-footer-cta .btn-tv{color:#fff}

.btn-tv-alt,
.detail-footer-cta .btn-tv-alt{
  display:inline-block;
  padding:0.85rem 1.9rem;
  background:transparent;
  color:var(--text);
  border:1px solid var(--border);
  border-radius:100px;
  font-family:'DM Mono',monospace;
  font-size:0.75rem;
  letter-spacing:0.16em;text-transform:uppercase;
  text-decoration:none;
  transition:border-color 0.25s,color 0.25s;
}
.btn-tv-alt:hover,
.detail-footer-cta .btn-tv-alt:hover{
  border-color:var(--gold);
  color:var(--gold);
}

/* One line explaining why the Pro CTA says "Request" and not "Open". */
.detail-cta-row + .detail-tier-note{
  margin-top:-1.25rem;
  margin-bottom:2rem;
  font-size:0.88rem;line-height:1.65;
  color:var(--muted);
  max-width:56ch;
}

.detail-shot{
  border:1px solid var(--border);
  border-radius:14px;
  overflow:hidden;
  background:var(--bg3);
}
.detail-shot picture{display:block}
.detail-shot img{
  display:block;width:100%;height:auto;
}
/* The whole screenshot is the zoom trigger (#16). */
.detail-shot-zoom{
  display:block;
  position:relative;
  cursor:zoom-in;
}
/* Inward, unlike the site-wide ring. .detail-shot clips its overflow and this
   link fills it corner to corner, so the shared 3px *outward* offset would be
   clipped away to nothing — the one control on the page whose focus state would
   silently not exist. Same shape as the catalog card's ring, one radius inside
   the 14px container. */
.detail-shot-zoom:focus-visible{
  outline:2px solid var(--gold);
  outline-offset:-4px;
  border-radius:13px;
}
/* Always visible, not revealed on hover: touch has no hover, and an affordance
   that only appears to mouse users tells every phone reader the image is inert.
   Fixed literals rather than theme tokens for the same reason .ind-featured-badge
   uses them — this chip floats over a chart screenshot, not over the page, so
   the cream-tuned light-mode gold would be nearly invisible on it. Colour-only
   transition, and nothing arrives from an invisible resting state, so the
   reduced-motion block below needs no entry for it. */
.detail-shot-hint{
  position:absolute;right:0.85rem;bottom:0.85rem;
  padding:0.4rem 0.8rem;
  border-radius:100px;
  background:rgba(5,8,15,0.82);
  border:1px solid rgba(201,168,76,0.45);
  color:#E8C97A;
  font-family:'DM Mono',monospace;
  font-size:0.66rem;letter-spacing:0.12em;
  backdrop-filter:blur(6px);
  transition:background 0.25s,border-color 0.25s,color 0.25s;
  pointer-events:none;
}
.detail-shot-zoom:hover .detail-shot-hint,
.detail-shot-zoom:focus-visible .detail-shot-hint{
  background:rgba(5,8,15,0.92);
  border-color:#C9A84C;
  color:#fff;
}

/* Prose rendered from BBCode */
.detail-prose{color:var(--text)}
.detail-prose > * + *{margin-top:1.2rem}
.detail-prose p{
  font-size:1.02rem;line-height:1.8;color:var(--text);
}
.detail-prose h2{
  font-family:'Cormorant Garamond',serif;
  font-weight:400;
  font-size:1.7rem;line-height:1.2;
  color:var(--heading);
  letter-spacing:-0.005em;
  margin-top:2.5rem;
  padding-top:1.75rem;
  border-top:1px solid var(--border);
}
.detail-prose h2:first-child{
  margin-top:0;padding-top:0;border-top:0;
}
.detail-prose ul{
  padding-left:1.25rem;
  display:flex;flex-direction:column;gap:0.6rem;
}
.detail-prose li{
  font-size:1rem;line-height:1.75;color:var(--text);
}
.detail-prose li::marker{color:var(--gold)}
.detail-prose strong{color:var(--heading);font-weight:500}
.detail-prose em{color:var(--muted);font-style:italic}
.detail-prose a{color:var(--gold);text-decoration:none;border-bottom:1px dotted var(--gold)}
.detail-prose a:hover{border-bottom-style:solid}
.detail-prose code{
  font-family:'DM Mono',monospace;
  font-size:0.88em;
  padding:0.1em 0.36em;
  color:var(--gold-light);
  background:var(--bg3);
  border:1px solid var(--border);
  border-radius:4px;
}
/* Light mode: gold-light on a cream chip drops well below body-text contrast,
   so fall back to --text. The mono font and chip already read as code. */
html[data-theme="light"] .detail-prose code{color:var(--text)}

.detail-footer-cta{
  margin-top:4rem;
  padding-top:2rem;
  border-top:1px solid var(--border);
  display:flex;align-items:center;flex-wrap:wrap;
  gap:1rem;
}

/* ---------- ERROR STATE ---------- */
.detail-error{
  text-align:center;
  padding:4rem 0;
}
.detail-error h1{
  font-family:'Cormorant Garamond',serif;
  font-weight:300;
  font-size:2.4rem;
  color:var(--heading);
  margin-bottom:1rem;
}
.detail-error p{
  color:var(--muted);
  max-width:460px;
  margin:0 auto 2rem;
}
.detail-error .btn-outline,
.detail-footer-cta .btn-outline{
  display:inline-block;
  padding:0.75rem 1.5rem;
  border:1px solid var(--border);
  border-radius:100px;
  color:var(--text);
  text-decoration:none;
  font-family:'DM Mono',monospace;
  font-size:0.75rem;letter-spacing:0.2em;text-transform:uppercase;
  transition:border-color 0.25s,color 0.25s;
}
.detail-error .btn-outline:hover,
.detail-footer-cta .btn-outline:hover{
  border-color:var(--gold);
  color:var(--gold);
}

/* ---------- SCREENSHOT POPOVER ---------- */
/* Opened by script.js over the .detail-shot-zoom anchor. The anchor works on
   its own with JS off, so nothing here may be load-bearing for that path.

   The image keeps its natural size (max-width:none, against the site-wide
   img{max-width:100%}) and the box scrolls. Fitting it to the viewport would
   show a ~2900px capture at about the size it already has on the page.
   overscroll-behavior:contain stops a scroll that reaches the edge of the box
   from continuing into the page behind it, which is the whole scroll lock this
   needs and is one line instead of a body class. */
.shot-modal{
  /* fit-content, not auto: a modal <dialog> is position:fixed, and `auto` let it
     stretch to the full viewport — the close button then sat in the corner of
     the *screen* rather than the corner of the image. */
  width:fit-content;height:fit-content;
  max-width:100vw;max-height:100vh;
  margin:auto;
  padding:0;
  border:none;
  background:none;
  overflow:visible;
}
.shot-modal::backdrop{
  background:rgba(6,9,17,0.88);
  backdrop-filter:blur(3px);
}
.shot-modal-scroll{
  max-width:min(96vw,2900px);
  max-height:92vh;
  overflow:auto;
  overscroll-behavior:contain;
  border:1px solid var(--border);
  border-radius:14px;
  background:var(--bg3);
}
.shot-modal-scroll img{
  display:block;
  max-width:none;   /* deliberate: overrides the global img{max-width:100%} */
}
.shot-modal-close{
  position:absolute;
  top:0.6rem;right:0.6rem;
  z-index:2;
  width:2.25rem;height:2.25rem;
  display:grid;place-items:center;
  font-family:'DM Mono',monospace;
  font-size:0.95rem;line-height:1;
  color:var(--text);
  background:var(--bg2);
  border:1px solid var(--border);
  border-radius:100px;
  cursor:pointer;
}
.shot-modal-close:hover{color:var(--gold);border-color:var(--gold)}

/* ---------- RESPONSIVE ---------- */
@media (max-width:1200px){
  .page-dyna,.page-detail{padding-inline:2.5rem;padding-bottom:5rem}
}
@media (max-width:900px){
  .page-dyna,.page-detail{padding-inline:1.25rem;padding-bottom:4rem}
  .ind-grid{grid-template-columns:1fr;gap:1.25rem}
  .dyna-hero{padding:2rem 0 0.75rem;margin-bottom:0.75rem}
  .strength-chips{margin-top:1.5rem}
  .detail-header{margin-bottom:2rem}
  .detail-title{margin-bottom:1.5rem}
  .detail-back{margin-bottom:1.5rem}
  /* Full-bleed CTAs on phones — these are the only actions on the page that
     lead anywhere new, and thumb-sized targets beat tidy pills. */
  .detail-cta-row{flex-direction:column;gap:0.7rem}
  .detail-cta-row .btn-tv,
  .detail-cta-row .btn-tv-alt{text-align:center}
  .detail-footer-cta{flex-direction:column;align-items:stretch}
  .detail-footer-cta .btn-tv,
  .detail-footer-cta .btn-outline{text-align:center}
}
/* After the 900px block, not before it: narrower conditions come last so they
   win at equal specificity. */
@media (max-width:640px){
  /* At 390px the full chip is 31% of the image's width and buries the price
     scale it sits over. The glyph stays — on touch there is no hover, so it is
     the only thing saying the image opens at all — and the dimensions go, since
     the link's accessible name carries them anyway and they are the half a
     phone reader is least likely to act on. */
  .detail-shot-hint{
    right:0.5rem;bottom:0.5rem;
    padding:0.35rem 0.5rem;
    font-size:0.7rem;
  }
  .detail-shot-dims{display:none}
}

/* ── Reduced motion ── */
/* The universal rule at the foot of styles.css has already removed every
   duration on this page. What survives it is a hover state that displaces the
   card 4px and zooms its screenshot — no longer animated, but still the effect
   a reduced-motion user asked not to get, and now delivered as a snap rather
   than a glide. The gold border and the shadow carry the affordance without it.
   These live here rather than in styles.css because dyna.css loads second: at
   equal specificity the rules above would otherwise win. */
@media(prefers-reduced-motion:reduce){
  .ind-card:hover{transform:none}
  .ind-card:hover .ind-thumb img{transform:none}
}
