/* ==========================================================================
   Charades — landing page.
   Loaded only by index.php, on top of style.css. The game screens never pay
   for any of this.

   Register is brand, not product: design IS the deliverable here. So the rules
   are different from the app — one dominant idea per fold, display type pushed
   far past app scale, and two sections that go fully drenched in colour.

   The imagery is the game itself. Every "screenshot" on this page is built
   from the real components in style.css — the same .word-card, .scores and
   .timer the product ships — dealing real card combinations. Nothing here is a
   picture of the product; it IS the product, running.
   ========================================================================== */

.land {
  --gutter: clamp(1.25rem, 5vw, 4rem);
  --section-y: clamp(5rem, 13vh, 9rem);
  display: block;
  max-width: none;
  padding: 0;
  gap: 0;
}

.land section { padding-block: var(--section-y); }
.wrap {
  width: 100%;
  max-width: 76rem;
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.wrap-narrow { max-width: 52rem; }

/* Display type for the landing only. The app tops out at 2.75rem because it is
   a tool; a marketing surface that stayed there would read as timid. */
.land h2 {
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 6vw, 4.5rem);
  font-weight: 800;
  letter-spacing: -0.045em;
  line-height: 0.98;
  text-wrap: balance;
}
.land .lead {
  font-size: clamp(1.125rem, 1.9vw, 1.5rem);
  line-height: 1.5;
  color: var(--fg-soft);
  max-width: 46ch;
  /* balance, not pretty — see the note in style.css. These are two- and
     three-line paragraphs, and pretty leaves the last line stranded. */
  text-wrap: balance;
}

/* ============================================================== nav ======= */

.land-nav {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s4);
  padding: var(--s3) var(--gutter);
  background: rgba(18, 16, 16, 0.72);
  backdrop-filter: blur(14px);
  box-shadow: inset 0 -1px 0 var(--rule);
}
.land-nav .wordmark { font-size: var(--t-base); }
.land-nav .seg { padding: 2px; }
.land-nav .seg-opt { min-height: 2.25rem; font-size: var(--t-sm); padding-inline: var(--s3); }

/* ============================================================= hero ======= */

/*
   Three children — text, the dealing card, the join form — placed rather than
   stacked, so the reading order can differ by width.

   On a phone the card comes BEFORE the form: a landing page should show you the
   thing before it asks you for anything. On desktop the card moves to its own
   column and the text and form stack beside it, which puts both above the fold.
*/
.hero {
  display: grid;
  gap: clamp(var(--s5), 5vw, var(--s7));
  grid-template-areas: "text" "stage" "join";
  padding-block: clamp(2rem, 6vh, 4rem) var(--section-y);
}
.hero-text  { grid-area: text; }
.deal-stage { grid-area: stage; }
.hero-join  { grid-area: join; }

@media (min-width: 62rem) {
  .hero {
    grid-template-columns: 1.05fr 0.95fr;
    grid-template-areas: "text stage" "join stage";
    align-items: center;
    padding-block: clamp(3rem, 8vh, 6rem) var(--section-y);
  }
  .hero-text { align-self: end; }
  .hero-join { align-self: start; }
}

.hero-title {
  font-family: var(--font-display);
  /* Ceiling held at 5.5rem. Past that the page is shouting, not designing. */
  font-size: clamp(2.75rem, 7vw, 5.5rem);
  font-weight: 800;
  letter-spacing: -0.05em;
  line-height: 0.94;
  text-wrap: balance;
  margin-bottom: var(--s4);
}
.hero-lead {
  font-size: clamp(1.125rem, 1.9vw, 1.4rem);
  line-height: 1.5;
  color: var(--fg-soft);
  max-width: 40ch;
  text-wrap: balance;
}
.hero-note { font-size: var(--t-sm); color: var(--fg-faint); margin-top: var(--s3); }

/* The join block. On a landing page the primary action belongs in the hero, so
   this is the CTA and the front door at the same time — a returning family
   never scrolls, and a first-time visitor gets the pitch underneath. */
.join-card {
  padding: var(--s5);
  border-radius: var(--r-xl);
  background: var(--bg-raised);
  box-shadow: var(--edge), var(--shadow-md);
  display: flex;
  flex-direction: column;
  gap: var(--s4);
}
.join-card .code-entry input { min-height: 4rem; font-size: var(--t-xl); }

/* --- the dealing card ---------------------------------------------------- */
/*
   A real .word-card, tilted on a glow, dealing a fresh subject + situation
   every few seconds. It is the product's whole idea in one object, so it is
   the hero image.
*/
.deal-stage {
  position: relative;
  display: grid;
  place-items: center;
  min-height: clamp(15rem, 34vh, 30rem);
  perspective: 1400px;
}
.deal-stage::before {
  content: "";
  position: absolute;
  width: 78%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(242, 106, 27, 0.30), transparent 66%);
  filter: blur(22px);
}
.deal-card {
  position: relative;
  width: min(100%, 23rem);
  transform: rotate(-2.5deg);
}
/* Two more of the deck behind the top card, so it reads as a stack. */
.deal-card::after,
.deal-card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: var(--r-xl);
  background: #E7DCCB;
}
.deal-card::before { transform: rotate(4deg) translateY(6px); opacity: 0.5; }
.deal-card::after  { transform: rotate(2deg) translateY(3px); opacity: 0.75; }
.deal-card .word-card { min-height: clamp(15rem, 30vh, 19rem); }

/* ============================================================= deck ======= */

.deck-figure {
  display: grid;
  gap: var(--s3);
  margin-top: clamp(var(--s6), 6vh, var(--s7));
}
@media (min-width: 48rem) {
  .deck-figure { grid-template-columns: 1fr auto 1fr; align-items: stretch; }
}

.deck-col {
  position: relative;
  overflow: hidden;
  padding: var(--s5) var(--s4);
  border-radius: var(--r-lg);
  background: var(--bg-raised);
  box-shadow: var(--edge);
  text-align: center;
}
.deck-col .label { display: block; margin-bottom: var(--s3); }
/* The cycling word. Fixed height so the row never jumps as words change. */
.deck-word {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 3.4vw, 2.5rem);
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 1.05;
  min-height: 2.2em;
  display: grid;
  place-items: center;
}
.deck-col.subject .deck-word { color: var(--fg); }
.deck-col.situation .deck-word { color: var(--c-accent-hi); }

.deck-times {
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 3vw, 2.25rem);
  font-weight: 800;
  color: var(--fg-faint);
  padding: var(--s2);
}

/* No accent stripe down the side — that treatment is decoration pretending to
   be structure. The emphasis comes from size and colour instead. */
.deck-aside {
  margin-top: clamp(var(--s5), 4vh, var(--s6));
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 2.4vw, 1.75rem);
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.25;
  color: var(--c-accent-hi);
  max-width: 30ch;
  text-wrap: balance;
}

/* =========================================================== screens ====== */

.screens {
  display: grid;
  gap: clamp(var(--s5), 5vw, var(--s7));
  margin-top: clamp(var(--s6), 6vh, var(--s7));
  align-items: center;
}
@media (min-width: 54rem) {
  .screens { grid-template-columns: 1.6fr 1fr; }
}
.screen-label { display: block; margin-bottom: var(--s3); }

/* Device frames. Deliberately plain — the point is the board inside, not a
   glossy bezel illustration. */
.mock-tv {
  border-radius: var(--r-lg);
  background: var(--c-bg-deep);
  box-shadow: inset 0 0 0 1px var(--rule), var(--shadow-lg);
  padding: clamp(var(--s4), 3vw, var(--s6));
  /* Sized by its contents, not by a fixed 16:10 — the board is fluid, and
     pinning the frame's ratio cropped the scoreboard off the bottom at some
     widths. The column proportions already make it read as a TV. */
  min-height: clamp(16rem, 26vw, 22rem);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(var(--s2), 1.5vw, var(--s4));
}
.mock-tv .tv-actor { font-size: clamp(1.25rem, 3.2vw, 2.25rem); }
.mock-tv .tv-pack  { font-size: clamp(0.8rem, 1.6vw, 1.1rem); }
.mock-tv .tv-meta  { font-size: clamp(0.65rem, 1.1vw, 0.85rem); }
.mock-tv .timer    { max-width: clamp(5rem, 13vw, 8rem); }
.mock-tv .timer .timer-num { font-size: clamp(1.5rem, 4vw, 2.5rem); }
.mock-tv .score .score-pts { font-size: clamp(1.75rem, 4.5vw, 3rem); }
.mock-tv .score .score-team { font-size: clamp(0.65rem, 1.2vw, 0.9rem); }
.mock-tv .score { padding: var(--s3); }

.mock-phone {
  max-width: 17rem;
  margin-inline: auto;
  padding: var(--s3);
  border-radius: calc(var(--r-xl) + var(--s2));
  background: var(--c-bg-deep);
  box-shadow: inset 0 0 0 1px var(--rule), var(--shadow-lg);
}
.mock-phone .word-card { min-height: 13rem; padding: var(--s5) var(--s4); }
.mock-phone .word-card .word { font-size: clamp(1.75rem, 6vw, 2.25rem); }

/* ============================================================ packs ======= */
/*
   Category names at size, moving. A grid of ten identical tiles would be the
   card-grid reflex; a marquee makes the breadth the point and lets "Cosas de
   antes" land as a surprise in the middle of it.
*/
.marquee {
  position: relative;
  overflow: hidden;
  padding-block: var(--s3);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.marquee + .marquee { margin-top: var(--s2); }
.marquee-track {
  display: flex;
  width: max-content;
  gap: var(--s5);
  animation: marquee 42s linear infinite;
}
.marquee.reverse .marquee-track { animation-direction: reverse; }
.marquee-track span {
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 5vw, 3.5rem);
  font-weight: 800;
  letter-spacing: -0.04em;
  color: transparent;
  -webkit-text-stroke: 1px var(--rule-strong);
  white-space: nowrap;
}
/* Every fourth name is solid, so the row has rhythm instead of uniform outline. */
.marquee-track span:nth-child(4n) {
  color: var(--fg);
  -webkit-text-stroke: 0;
}
.marquee-track span.hot {
  color: var(--c-accent);
  -webkit-text-stroke: 0;
}
@keyframes marquee { to { transform: translateX(-50%); } }

/* ============================================================ twist ======= */
/* The one drenched fold. The surface IS the colour here. */

.band {
  background: var(--c-accent);
  color: #16110C;
}
.band h2 { color: inherit; }
/* 0.85, not the 0.72 that looked right: over this orange, 0.72 measures 3.8:1
   and fails body text. Dimming ink on a saturated ground eats contrast much
   faster than it looks like it should. */
.band .lead { color: rgba(22, 17, 12, 0.85); }

.twist-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3) var(--s5);
  margin-top: clamp(var(--s5), 5vh, var(--s6));
  list-style: none;
  padding: 0;
}
.twist-list li {
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 3.4vw, 2.5rem);
  font-weight: 800;
  letter-spacing: -0.04em;
  line-height: 1;
  text-transform: uppercase;
}
/* Alternating weight gives the list rhythm; 0.65 is the floor that still clears
   3:1 for large text on this orange. */
.twist-list li:nth-child(even) { color: rgba(22, 17, 12, 0.65); }

/* ======================================================== bilingual ======= */

.band-teal {
  background: var(--c-team-b-dim);
  box-shadow: inset 0 1px 0 var(--rule);
}
/* The muted body colour only clears 4.8:1 on this teal. Lifted so the band
   holds the same reading standard as every other surface. */
.band-teal .lead { color: rgba(246, 241, 234, 0.88); }
.bi-pair {
  display: grid;
  gap: var(--s3);
  margin-top: clamp(var(--s5), 5vh, var(--s6));
  max-width: 34rem;
}
@media (min-width: 40rem) { .bi-pair { grid-template-columns: 1fr 1fr; } }
.bi-chip {
  padding: var(--s4) var(--s5);
  border-radius: var(--r-lg);
  background: rgba(0, 0, 0, 0.25);
  box-shadow: var(--edge);
}
.bi-chip .label { display: block; margin-bottom: var(--s2); }
.bi-chip b {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 4vw, 2.25rem);
  font-weight: 800;
  letter-spacing: -0.035em;
  color: var(--c-team-b);
}

/* ============================================================== CTA ======= */

.land-cta { text-align: center; }
.land-cta .wrap { display: grid; justify-items: center; gap: var(--s4); }
.land-cta .join-card { width: min(100%, 26rem); text-align: left; margin-top: var(--s4); }

.land-footer {
  padding: var(--s6) var(--gutter) calc(var(--s6) + env(safe-area-inset-bottom, 0px));
  box-shadow: inset 0 1px 0 var(--rule);
  color: var(--fg-faint);
  font-size: var(--t-sm);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3);
  align-items: center;
  justify-content: space-between;
}

/* =========================================================== reveal ======= */
/*
   Content is visible by default. The hidden start only exists once JS has run
   and confirmed it can reveal again — otherwise a headless render, a blocked
   script or a background tab ships a blank page.
*/
.js-reveal .reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 620ms var(--ease-expo), transform 620ms var(--ease-expo);
}
.js-reveal .reveal.in { opacity: 1; transform: none; }
.js-reveal .reveal-2 { transition-delay: 90ms; }
.js-reveal .reveal-3 { transition-delay: 180ms; }

/* The card swap. Out and back in, so a new combination reads as dealt rather
   than as text quietly changing. */
.deal-card.swapping .word-card {
  animation: none;
  opacity: 0;
  transform: translateY(10px) scale(0.97);
  transition: opacity 180ms var(--ease), transform 180ms var(--ease);
}
.deck-word.swapping { opacity: 0; transition: opacity 160ms var(--ease); }
.deck-word { transition: opacity 260ms var(--ease); }

@media (prefers-reduced-motion: reduce) {
  .marquee-track { animation: none; transform: none; }
  .marquee { -webkit-mask-image: none; mask-image: none; }
  .marquee-track { flex-wrap: wrap; width: auto; justify-content: center; }
  .js-reveal .reveal { opacity: 1; transform: none; transition: none; }
  .deal-card.swapping .word-card, .deck-word.swapping { opacity: 1; transform: none; }
}
