/* =========================================================================
   CODEX NATURALIS PROJECT PAGE — page-specific styles.
   Reuses tokens, .btn, .stack-badge and .section-head from ../style.css.
   Everything here is unique to this page and leans into one identity: an
   illuminated codex. The portfolio's cool forest/paper system stays intact;
   the "rulebook" layer adds warm parchment plates, gold illumination, engraved
   kingdom symbols and a blackletter drop-cap, used with restraint.

   Order: cross-cutting utilities (base background, cross-doc transition, the
   shared readability veil, codex tokens), then one block per section top to
   bottom as they appear on screen.
   ========================================================================= */

/* ============================================================
   TOKENS — codex-only, layered on top of the portfolio's
   ============================================================ */
:root {
  /* Gold + blackletter are the codex's only signature, reserved for the hero
     wordmark and the overview drop-cap. Everything else uses the site's own
     forest/paper tokens so the page reads as part of the portfolio. */
  --gold:      #a97e2f;
  --gold-rgb:  169, 126, 47;
  --font-black: "UnifrakturCook", "Archivo", serif;
}

/* Base surface + horizontal-overflow containment (see DormMate note: keep the
   top of the tree clip-free so the sticky bar sticks on every engine). */
html:has(> .cx-body) { overflow-x: visible; scrollbar-gutter: stable; }
.cx-body { background: var(--paper); overflow-x: visible; }

/* ---------- Cross-document transition from the portfolio ----------
   Exactly what DormMate and CTRL-V do, and for the same reason: the browser
   owns the animation, so it also plays it in reverse on a Back traversal.
   The portfolio's Codex card links here as a plain navigation; opting in on
   both documents lets the card's emblem morph into this hero's emblem through
   the shared `codex-cover` name. Browsers without cross-document View
   Transitions just navigate normally.

   This page used to opt OUT and hand-roll the round trip with fullscreen
   clones and a sessionStorage handshake. It broke in three ways the browser's
   own transition cannot: the ← link pushed a history entry instead of going
   back, the head script that armed the intro ran before the flag was written
   whenever the page had been prerendered, and the Back button never triggered
   the return half at all. */
@view-transition { navigation: auto; }
.cx-hero__logo { view-transition-name: codex-cover; }
::view-transition-old(codex-cover),
::view-transition-new(codex-cover) { animation-duration: 0.5s; }

/* The emblem floats on a loop, and a transform still running while the browser
   measures the snapshot lands the morph a few percent off its target. Hold it
   still for the length of the transition; it resumes on its own after. */
:root:active-view-transition .cx-hero__logo { animation: none; }

/* ---------- Readability veil under floating text ----------
   Same site-wide technique: a soft feathered paper wash under text that floats
   directly over the dot-field background. Applied to every bare-background text
   block. NOT applied to the parchment plates / client panels (they carry their
   own opaque surface). */
.cx-hero__eyebrow,
.cx-hero__title,
.cx-hero__tagline,
.cx-hero__spec,
.cx-overview__label,
.cx-overview__lead,
.cx-overview__text,
.cx-elements__intro,
.cx-group__title,
.cx-group__lead,
.cx-notes,
.cx-interfaces__intro,
.cx-demo__caption,
.cx-bom,
.cx-ledger,
.cx-footer {
  position: relative;
}
.cx-hero__eyebrow::before,
.cx-hero__title::before,
.cx-hero__tagline::before,
.cx-hero__spec::before,
.cx-overview__label::before,
.cx-overview__lead::before,
.cx-overview__text::before,
.cx-elements__intro::before,
.cx-group__title::before,
.cx-group__lead::before,
.cx-notes::before,
.cx-interfaces__intro::before,
.cx-demo__caption::before,
.cx-bom::before,
.cx-ledger::before,
.cx-footer::before {
  content: "";
  position: absolute;
  inset: -0.6rem -0.9rem;
  z-index: -1;
  background: var(--veil);
  pointer-events: none;
  -webkit-mask-image: radial-gradient(115% 130% at 50% 50%, #000 52%, transparent 100%);
  mask-image: radial-gradient(115% 130% at 50% 50%, #000 52%, transparent 100%);
}

/* ============================================================
   TOP BAR
   ============================================================ */
.cx-top {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1.25rem var(--gutter);
  background: var(--veil);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
}
.cx-back {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--forest);
}
.cx-top-github { color: var(--graphite); font-family: var(--font-mono); font-size: 0.78rem; }
.cx-top-github:hover { color: var(--forest); }

main.cx-main { max-width: 1180px; margin: 0 auto; padding: 0 var(--gutter); }

.cx-section-head { padding: 0; }

/* Anchor targets clear the sticky top bar instead of tucking under it */
.cx-elements, .cx-interfaces, .cx-demo, .cx-build { scroll-margin-top: 5rem; }

/* ============================================================
   HERO — editorial title block left, the emblem as the thesis right
   ============================================================ */
.cx-hero {
  position: relative;
  padding: clamp(2.5rem, 7vh, 4.5rem) 0 clamp(3rem, 8vh, 5rem);
  min-height: 80vh;
  display: grid;
  grid-template-columns: 1.02fr 0.98fr;
  align-items: center;
  gap: clamp(2rem, 5vw, 4rem);
}
.cx-hero__intro { position: relative; z-index: 2; max-width: 34rem; }

.cx-hero__eyebrow {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--forest);
  width: fit-content;
}
.cx-hero__title {
  margin: 1.1rem 0 0.5rem;
  font-family: var(--font-display);
  font-variation-settings: "wdth" 118;
  font-weight: 800;
  font-size: clamp(2.8rem, 8vw, 5.2rem);
  line-height: 0.88;
  letter-spacing: -0.01em;
  color: var(--forest);
}
/* "Naturalis" set in illuminated blackletter, gold, the single type risk */
.cx-hero__title-sub {
  display: inline-block;
  margin-top: 0.15em;
  font-family: var(--font-black);
  font-weight: 700;
  font-size: clamp(2.2rem, 6vw, 4rem);
  line-height: 1;
  letter-spacing: 0.01em;
  color: var(--gold);
  -webkit-text-stroke: 0.4px rgba(120, 92, 32, 0.35);
}
.cx-hero__tagline {
  font-size: 1.08rem;
  color: var(--graphite);
  max-width: 42ch;
  margin-top: 0.6rem;
}

.cx-hero__spec {
  margin-top: 1.6rem;
  display: grid;
  gap: 0.55rem;
  width: fit-content;
}
.cx-hero__spec > div {
  display: grid;
  grid-template-columns: 5rem 1fr;
  gap: 0.9rem;
  align-items: baseline;
}
.cx-hero__spec dt {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--forest);
}
.cx-hero__spec dd { font-size: 0.95rem; color: var(--ink); }

.cx-hero__cta { margin-top: 2rem; display: flex; gap: 1rem; flex-wrap: wrap; }

/* Emblem: the diamond cover art, floating over a slow gold halo */
.cx-hero__emblem {
  position: relative;
  justify-self: center;
  width: min(100%, 400px);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
}
.cx-hero__halo {
  position: absolute;
  inset: 6%;
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 45%, rgba(var(--gold-rgb), 0.30), transparent 62%),
    conic-gradient(from 0deg, rgba(var(--gold-rgb), 0.16), rgba(27, 67, 50, 0.14), rgba(var(--gold-rgb), 0.16), rgba(27, 67, 50, 0.14), rgba(var(--gold-rgb), 0.16));
  filter: blur(14px);
  animation: cx-spin 40s linear infinite;
}
.cx-hero__logo {
  position: relative;
  width: 100%;
  height: auto;
  filter: drop-shadow(0 24px 40px rgba(var(--forest-rgb), 0.32));
  animation: cx-float 7s ease-in-out infinite;
}
@keyframes cx-spin { to { transform: rotate(360deg); } }
@keyframes cx-float {
  0%, 100% { transform: translateY(0) rotate(-0.6deg); }
  50%      { transform: translateY(-14px) rotate(0.6deg); }
}

/* ============================================================
   OVERVIEW — floating statement with an illuminated drop-cap
   ============================================================ */
.cx-overview {
  max-width: 68ch;
  padding: var(--section-gap) 0 clamp(2rem, 6vh, 4rem);
}
.cx-overview__label {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--forest);
  margin-bottom: 1.1rem;
}
.cx-overview__lead {
  font-size: clamp(1.2rem, 2.2vw, 1.65rem);
  line-height: 1.5;
  font-weight: 400;
}
.cx-overview__lead strong { font-weight: 700; }
/* Illuminated initial: blackletter, gold, dropped into the lead paragraph */
.cx-overview__lead::first-letter {
  float: left;
  font-family: var(--font-black);
  font-weight: 700;
  font-size: 3.6em;
  line-height: 0.72;
  padding: 0.06em 0.12em 0 0;
  color: var(--gold);
  -webkit-text-stroke: 0.5px rgba(120, 92, 32, 0.4);
}
.cx-overview__text {
  margin-top: 1.2rem;
  color: var(--graphite);
  line-height: 1.6;
  max-width: 62ch;
}

/* ============================================================
   THE ELEMENTS — kingdoms, treasures, the card tableau
   Uses the site's own language: forest mono eyebrows, cool veil tiles
   (var(--line) + blur) and a hairline list. No parchment, no gold here.
   The codex's colour comes only from the real card and icon art.
   ============================================================ */
.cx-elements { padding: 0 0 var(--section-gap); }
.cx-elements__intro {
  color: var(--graphite);
  max-width: 56ch;
  margin: -1.5rem 0 1rem;
}

.cx-group { margin-top: clamp(3rem, 7vw, 5rem); }
.cx-group__title {
  font-family: var(--font-display);
  font-variation-settings: "wdth" 110;
  font-weight: 800;
  font-size: clamp(1.5rem, 3.2vw, 2.1rem);
  line-height: 1.08;
  color: var(--forest);
  width: fit-content;
}
.cx-group__lead {
  margin-top: 0.8rem;
  max-width: 60ch;
  color: var(--graphite);
  line-height: 1.55;
}

/* ---------- Kingdoms + treasures share one cool veil tile ---------- */
.cx-kingdoms,
.cx-treasures {
  margin-top: 2rem;
  display: grid;
  gap: 1rem;
}
.cx-kingdoms { grid-template-columns: repeat(4, 1fr); }
.cx-treasures { grid-template-columns: repeat(3, 1fr); }

.cx-kingdom,
.cx-treasure {
  text-align: center;
  padding: 1.75rem 1.1rem 1.5rem;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--veil);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: transform 0.3s var(--ease-soft), border-color 0.3s var(--ease-soft), box-shadow 0.3s var(--ease-soft);
}
.cx-kingdom:hover,
.cx-treasure:hover {
  transform: translateY(-4px);
  border-color: rgba(var(--forest-rgb), 0.5);
  box-shadow: 0 16px 30px -22px rgba(var(--forest-rgb), 0.6);
}
.cx-kingdom__disc,
.cx-treasure__icon {
  width: 72px; height: 72px;
  margin: 0 auto 1rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--paper-raise);
  border: 1px solid var(--line);
}
.cx-kingdom__disc img,
.cx-treasure__icon img {
  width: 42px; height: 42px;
  object-fit: contain;
}
.cx-kingdom__name,
.cx-treasure__name {
  display: block;
  font-family: var(--font-display);
  font-variation-settings: "wdth" 100;
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--ink);
}
.cx-kingdom__latin,
.cx-treasure__latin {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.64rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--forest);
  margin: 0.35rem 0 0.65rem;
}
.cx-kingdom__flavor,
.cx-treasure__flavor {
  display: block;
  font-size: 0.84rem;
  line-height: 1.45;
  color: var(--graphite);
}

/* ---------- The card tableau: real cards floating on the dot-field ----------
   No surface behind them, so the corner overlap reads on its own. The image
   is a transparent PNG with the inter-card shadows baked in. */
.cx-tableau__stage {
  display: flex;
  justify-content: center;
  padding: clamp(1rem, 3vw, 2rem) 0 0;
}
.cx-tableau__stage img {
  width: 100%;
  max-width: 760px;
  height: auto;
  filter: drop-shadow(0 24px 40px rgba(var(--forest-rgb), 0.24));
  animation: cx-float 8s ease-in-out infinite;
}

/* Card notes: a hairline-ruled list, matching the site's list aesthetic */
.cx-notes {
  position: relative;
  margin: 2rem auto 0;
  max-width: 760px;
  border-top: 1px solid var(--line);
}
.cx-notes__row {
  display: grid;
  grid-template-columns: 8rem 1fr;
  gap: 1rem;
  padding: 1rem 0.25rem;
  border-bottom: 1px solid var(--line);
}
.cx-notes__row dt {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--forest);
}
.cx-notes__row dd {
  margin: 0;
  color: var(--graphite);
  line-height: 1.5;
  font-size: 0.92rem;
}

/* ============================================================
   TWO WAYS TO PLAY — GUI / TUI diptych
   ============================================================ */
.cx-interfaces { padding: 0 0 var(--section-gap); }
.cx-interfaces__intro {
  color: var(--graphite);
  max-width: 58ch;
  margin: -1.5rem 0 2.5rem;
}
.cx-interfaces__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
}
.cx-client {
  position: relative;
  border: 1px solid var(--line);
  border-radius: 24px;
  padding: 2rem clamp(1.5rem, 3vw, 2.25rem) 2.25rem;
  display: flex;
  flex-direction: column;
  background: var(--veil);
  backdrop-filter: blur(10px) saturate(1.1);
  -webkit-backdrop-filter: blur(10px) saturate(1.1);
}
.cx-client__badges { display: flex; gap: 0.5rem; margin-bottom: 1.1rem; }
.cx-client__accent-badge { color: var(--forest); border-color: var(--forest); }
.cx-client__title {
  font-family: var(--font-display);
  font-variation-settings: "wdth" 105;
  font-weight: 800;
  font-size: clamp(1.5rem, 3vw, 2rem);
  line-height: 1.08;
}
.cx-client__desc { color: var(--graphite); max-width: 42ch; margin-top: 0.9rem; }

.cx-client__shot {
  margin-top: 1.6rem;
  border-radius: 14px;
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--forest-deep);
}
.cx-client__shot img { display: block; width: 100%; height: 100%; object-fit: cover; }
.cx-client__shot--gui { aspect-ratio: 16 / 10; }
.cx-client__shot--gui img { object-position: center; }
.cx-client__shot--tui { aspect-ratio: 16 / 10; background: #0c0c0c; }
.cx-client__shot--tui img { object-fit: cover; object-position: top center; }

.cx-tui-modes {
  list-style: none;
  margin: 1.25rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.cx-tui-modes li {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.4rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: rgba(var(--forest-rgb), 0.04);
  font-size: 0.68rem;
  color: var(--graphite);
}
.cx-tui-modes__name {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--forest);
}

/* ============================================================
   DEMO — a manuscript window around the gameplay video
   ============================================================ */
.cx-demo { padding: 0 0 var(--section-gap); }
.cx-demo__frame {
  position: relative;
  border-radius: 18px;
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--forest-deep);
  box-shadow: 0 26px 60px -34px rgba(var(--forest-rgb), 0.7);
}
.cx-demo__video { display: block; width: 100%; height: auto; }
.cx-demo__caption {
  margin: 1.25rem auto 0;
  width: fit-content;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  color: var(--graphite);
  text-align: center;
}

/* ============================================================
   UNDER THE HOOD — parts list + shipped ledger
   ============================================================ */
.cx-build { padding: 0 0 var(--section-gap); }
.cx-bom {
  list-style: none;
  margin: 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.cx-bom__row {
  display: grid;
  grid-template-columns: auto minmax(8rem, 0.8fr) 1.9fr;
  gap: 1rem 1.5rem;
  align-items: center;
  padding: 1.5rem 0.75rem;
  transition: background-color 0.25s var(--ease-soft);
}
.cx-bom__row + .cx-bom__row { border-top: 1px solid var(--line); }
.cx-bom__row:hover { background: rgba(var(--forest-rgb), 0.04); }
.cx-bom__no {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  color: var(--forest);
  opacity: 0.55;
  transition: opacity 0.25s var(--ease-soft);
}
.cx-bom__row:hover .cx-bom__no { opacity: 1; }
.cx-bom__name {
  font-family: var(--font-display);
  font-variation-settings: "wdth" 105;
  font-weight: 700;
  font-size: 1.15rem;
  line-height: 1.1;
}
.cx-bom__role {
  display: block;
  margin-top: 0.35rem;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--graphite);
}
.cx-bom__desc { color: var(--graphite); max-width: 56ch; line-height: 1.55; }
.cx-bom__coverage { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; }
.cx-bom__coverage li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.6rem; }
.cx-cov__area {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--forest);
  min-width: 5.5rem;
}
.cx-cov__val { font-family: var(--font-mono); font-size: 0.85rem; color: var(--ink); }

/* Shipped ledger */
.cx-ledger { margin-top: 3rem; }
.cx-ledger__title {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--forest);
  margin-bottom: 1.25rem;
}
/* Hairline-ruled rows, not boxes, matching the parts list above */
.cx-ledger__list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--line);
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  column-gap: 2.5rem;
}
.cx-ledger__item {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.85rem 0.25rem;
  border-bottom: 1px solid var(--line);
  font-size: 0.94rem;
  color: var(--ink);
}
.cx-ledger__mark {
  display: grid;
  place-items: center;
  width: 1.4rem; height: 1.4rem;
  flex-shrink: 0;
  border-radius: 50%;
  font-size: 0.72rem;
  font-weight: 700;
}
.cx-ledger__item.is-done .cx-ledger__mark { background: var(--forest); color: var(--paper); }
.cx-ledger__item.is-partial .cx-ledger__mark {
  background: transparent;
  color: var(--forest);
  border: 1px solid rgba(var(--forest-rgb), 0.45);
}
.cx-ledger__item.is-partial { color: var(--graphite); }
.cx-ledger__tag {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--graphite);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.15em 0.55em;
}

/* ============================================================
   FOOTER
   ============================================================ */
.cx-footer {
  padding: 2.5rem var(--gutter) 3rem;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--graphite);
  border-top: 1px solid var(--line);
}
.cx-footer a { color: var(--forest); }

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 900px) {
  .cx-hero {
    grid-template-columns: 1fr;
    text-align: center;
    min-height: 0;
    gap: 1.5rem;
  }
  .cx-hero__intro { max-width: none; }
  .cx-hero__eyebrow,
  .cx-hero__spec { margin-inline: auto; }
  .cx-hero__cta { justify-content: center; }
  .cx-hero__tagline { max-width: 52ch; margin-inline: auto; }
  .cx-hero__emblem { order: -1; width: min(72%, 300px); }
  .cx-kingdoms { grid-template-columns: repeat(2, 1fr); }
  .cx-treasures { grid-template-columns: 1fr; gap: 1rem; }
  .cx-interfaces__grid { grid-template-columns: 1fr; }
  .cx-ledger__list { grid-template-columns: 1fr; column-gap: 0; }
}

@media (max-width: 520px) {
  .cx-notes__row { grid-template-columns: 1fr; gap: 0.3rem; }
}

@media (max-width: 620px) {
  .cx-bom__row { grid-template-columns: auto 1fr; row-gap: 0.8rem; }
  .cx-bom__desc { grid-column: 1 / -1; }
}

@media (max-width: 440px) {
  .cx-kingdoms { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  .cx-hero__halo, .cx-hero__logo, .cx-tableau__stage img { animation: none; }
  .cx-kingdom, .cx-treasure { transition: none; }
}
