/* /christmas-house — spec 073 part B, B-T05. This page's own stylesheet,
   never main.css (plan.md's trade-off table). It reuses main.css's shared
   tokens (--ink, --font, --radius, .btn, .field/.hint/.error from
   field-copy.js's buildField(), and the .layer / .plate-canvas pair /make
   and /personalize already ship) rather than redeclaring them.

   First-cut styling only — Luke and the orchestrator reshape this over
   `npm run dev` (spec 073 "Read this first"). Nothing here is load-bearing
   for a requirement; the structure and the motion contract are. */

.christmas-house-page {
  max-width: 1180px;
  margin: 0 auto;
  padding: 8px 24px 96px;
}

.ch-intro {
  max-width: 640px;
  margin: 0 0 32px;
}

.ch-intro h1 {
  margin: 0 0 12px;
  font-family: var(--font-display);
  font-size: clamp(1.8rem, 4vw, 2.6rem);
  line-height: 1.1;
}

.ch-lede {
  margin: 0;
  font-size: 1.1rem;
  line-height: 1.6;
  color: var(--ink);
}

.ch-placeholder-note {
  margin: 0 0 28px;
  padding: 12px 16px;
  border-radius: var(--radius);
  background: #fff4d6;
  border: 2px solid #e8c460;
  font-size: 0.95rem;
  line-height: 1.5;
}

.ch-name-field {
  max-width: 360px;
  margin: 0 0 36px;
}

.ch-chooser {
  margin: 0 0 40px;
}

.ch-chooser-heading {
  margin: 0 0 14px;
  font-family: var(--font-display);
  font-size: 1.3rem;
}

.ch-chooser-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 12px;
  max-width: 720px;
}

.ch-chooser-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 8px;
  min-height: 56px;
  border: 3px solid transparent;
  border-radius: var(--radius);
  background: #fff;
  cursor: pointer;
  transition:
    border-color 300ms ease,
    transform 300ms ease;
}

.ch-chooser-tile:hover {
  transform: translateY(-2px);
}

.ch-chooser-tile[aria-pressed='true'] {
  border-color: var(--ink);
}

.ch-chooser-tile img {
  width: 72px;
  height: 90px;
  object-fit: cover;
  border-radius: calc(var(--radius) / 2);
}

.ch-chooser-label {
  font-size: 0.85rem;
  text-align: center;
  line-height: 1.3;
}

.ch-chooser-note {
  margin: 16px 0 0;
  font-size: 0.85rem;
  color: var(--ink);
  opacity: 0.75;
}

.ch-scenes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 28px;
}

.ch-scene {
  margin: 0;
}

/* `.plate-canvas` (main.css) reserves position/overflow/container-type; the
   aspect-ratio here is set inline per scene from the manifest's own canvas
   (JS), since the cover's box (800x1000) differs from the interior plates'
   (1000x1000) — WEB_BUILD_GUIDE.md §3's CLS budget: the box is final before
   any image, placeholder or real, ever paints into it. */
.ch-plate {
  background: #1a1a1a;
}

/* Every mounted background/shadow/subject layer starts hidden;
   `createCompositeController` (B-R7) reveals the background, its shadow (when
   the role declares one) and the resting subject together once every image
   this scene depends on has decoded, then a child switch cross-fades to a
   different already-decoded subject — the shadow itself never toggles per
   child, since it is a role-level layer like the background, not one of the
   six subjects. 360ms pairs with make-stack-swap.js's
   own default (docs/motion-principles.md).

   Scoped to the declared scene layers, never the bare `.layer` class, so
   unrelated positioned content cannot accidentally inherit the cross-fade. */
.ch-plate .ch-layer-bg,
.ch-plate .ch-layer-shadow,
.ch-plate .ch-layer-occluder,
.ch-plate .ch-layer-subject {
  opacity: 0;
  object-fit: cover;
  transition: opacity 360ms ease;
}

.ch-plate .ch-layer-bg.is-visible,
.ch-plate .ch-layer-shadow.is-visible,
.ch-plate .ch-layer-occluder.is-visible,
.ch-plate .ch-layer-subject.is-visible {
  opacity: 1;
}

.ch-caption {
  margin: 10px 2px 0;
  font-size: 0.95rem;
  line-height: 1.55;
  color: var(--ink);
}

@media (prefers-reduced-motion: reduce) {
  .ch-plate .ch-layer-bg,
  .ch-plate .ch-layer-shadow,
  .ch-plate .ch-layer-occluder,
  .ch-plate .ch-layer-subject,
  .ch-chooser-tile {
    transition: none;
  }
}

.ch-candidate-controls {
  margin: 0 0 28px;
  padding: 16px;
  border: 2px solid #5b6a72;
  border-radius: var(--radius);
  background: #eef5f7;
}

.ch-candidate-controls[hidden],
.ch-candidate-stack[hidden],
.ch-candidate-layer[hidden] {
  display: none;
}

.ch-candidate-controls h2 {
  margin: 0 0 8px;
  font-size: 1.1rem;
}
.ch-candidate-controls label {
  display: block;
  margin-bottom: 8px;
}
.ch-candidate-controls p {
  margin: 8px 0 0;
}

.ch-candidate-stack {
  position: absolute;
  inset: 0;
  z-index: 50;
  pointer-events: none;
}

.ch-candidate-layer {
  position: absolute;
  display: block;
  max-width: none;
  object-fit: fill;
}
