/* CIDA Egypt — cinematic INNER PAGES.
 *
 * cinematic.css holds the atmosphere and the home film. This file holds the
 * composition every other page is built from: a band hero, body copy laid in
 * movements on the obsidian ground, full-bleed interludes between them, and
 * the reveal system that lifts a block as it enters.
 *
 * Two rules govern everything below.
 *
 * 1. NOTHING IS HIDDEN WITHOUT JAVASCRIPT. Every hidden state is scoped to
 *    `.js:not(.no-motion)`, a class cinematic.js sets on <html> only once it is
 *    running and motion is allowed. With scripts blocked, slow, or with
 *    prefers-reduced-motion set, the finished page is what paints first.
 *
 * 2. THE SEAM IS AN ALPHA MASK, NOT A COLOUR. The page ground is #ambient,
 *    which tweens between tones as you scroll, so a photograph faded to a
 *    hard-coded near-black would leave a visible rectangle the moment the
 *    ground moved off that value. Masking the image to transparent lets the
 *    live ground show through instead, and the joins stay invisible whatever
 *    colour the page is currently breathing.
 *
 * Logical properties throughout — the Arabic mirror is correct by
 * construction, not by a second stylesheet.
 */

:root {
  /* Motion register for the page layer. Slow and weighted: the brief asks for
     seconds, not milliseconds, and these are the values the whole file uses.
     Nothing here is decorative-fast; a reveal that finishes in 300ms reads as
     a web page, one that takes 1.6s reads as a camera settling. */
  --cine-ease:          cubic-bezier(0.22, 1, 0.36, 1);
  --cine-reveal:        1.6s;   /* block lift + fade */
  --cine-reveal-delay:  0.12s;
  --cine-stagger:       0.14s;  /* per sibling inside a reveal group */
  --cine-band:          2.4s;   /* photographic bands settling */
  --cine-settle:        3s;     /* the hero's own scale settle */
}

/* ---------------------------------------------------------------------------
 * The page ground.
 *
 * Sections must NOT paint their own background — #ambient is the ground, and
 * an opaque section would hide the very layer that is being tweened. The old
 * inner-page markup carried data-surface="register", which flipped these pages
 * onto the light bone palette AND painted over the atmosphere. Both are gone.
 * ------------------------------------------------------------------------- */

.content--cinematic,
.movement,
.pagehero,
.interlude { background: transparent; }

/* ---------------------------------------------------------------------------
 * Hero band.
 *
 * The same composition as the home hero at a shorter height, so an inner page
 * is recognisably the same film without pretending to be the opening shot.
 * The image is the page's LCP and is never faded in from nothing: the settle
 * keyframe ends at the natural state and uses animation-fill-mode: backwards,
 * so the pre-animation frame IS the finished frame.
 * ------------------------------------------------------------------------- */

.pagehero {
  position: relative;
  display: grid;
  min-block-size: min(62svh, 34rem);
  max-block-size: 44rem;
  overflow: clip;
  margin-block-end: clamp(1rem, 4vw, 3rem);
}

.pagehero__media {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  animation: band-settle var(--cine-settle) var(--cine-ease) backwards;

  /* The bottom edge dissolves into the live ground rather than ending on a
     line. 7% is enough to kill the cut and small enough that the text zone —
     which sits well above it — keeps the full weight of the scrim. */
  mask-image: linear-gradient(to bottom, #000 0%, #000 93%, transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 93%, transparent 100%);
}
@keyframes band-settle { from { scale: 1.06; } }

/* Slow drift as the hero leaves. Scroll-driven CSS only: a browser without
   animation-timeline gets a perfect static crop and nothing is JS-dependent. */
@supports (animation-timeline: scroll()) {
  .pagehero__media {
    animation:
      band-settle var(--cine-settle) var(--cine-ease) backwards,
      band-drift linear both;
    animation-timeline: auto, scroll(root block);
    animation-range: normal, 0 100svh;
  }
  @keyframes band-drift {
    from { translate: 0 0; }
    to   { translate: 0 5%; }
  }
}

.pagehero__scrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(to top,
      rgb(11 14 20 / 0.92) 0%,
      rgb(11 14 20 / 0.80) 22%,
      rgb(11 14 20 / 0.48) 46%,
      rgb(11 14 20 / 0.14) 68%,
      rgb(11 14 20 / 0)    86%),
    linear-gradient(to right,
      rgb(11 14 20 / 0.58) 0%,
      rgb(11 14 20 / 0.28) 36%,
      rgb(11 14 20 / 0)    62%),
    linear-gradient(to bottom,
      rgb(11 14 20 / 0.66) 0%,
      rgb(11 14 20 / 0)    20%);
  /* Fades out with the photograph so the two dissolve together. */
  mask-image: linear-gradient(to bottom, #000 0%, #000 93%, transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 93%, transparent 100%);
}
/* One line flips the corner bias for the RTL reading eye. */
[dir="rtl"] .pagehero__scrim { transform: scaleX(-1); }

/*
 * Aligned to .wrap, not to the viewport edge.
 *
 * The home hero is edge-biased because nothing follows it on the same axis.
 * An inner-page title does have something following it — the body copy — and a
 * title that starts 80px from the edge above a paragraph that starts 170px
 * from it reads as two designs stacked. Same max-width and same inline padding
 * as .wrap means the H1 and the first sentence share one optical margin at
 * every viewport width, and in both directions.
 */
.pagehero__content {
  position: relative;
  align-self: end;
  inline-size: 100%;
  max-inline-size: 72rem;
  margin-inline: auto;
  padding-inline: 1.5rem;
  padding-block-end: clamp(3rem, 9svh, 5.5rem);
  display: grid;
  justify-items: start;
}

.pagehero__crumbs {
  margin-block-end: 1rem;
  animation: band-rise 1.2s var(--cine-ease) 0.1s backwards;
}
.pagehero__crumbs a { color: var(--bone-200); text-decoration: none; }
.pagehero__crumbs a:hover { color: var(--gold-300); text-decoration: underline; }
.pagehero__crumbs li + li::before { color: var(--bone-400); }

.pagehero__eyebrow {
  color: var(--gold-300);
  margin: 0 0 .75rem;
  animation: band-rise 1.3s var(--cine-ease) 0.2s backwards;
}

.pagehero .pagehero__title {
  font-size: var(--text-display-2, var(--text-display-3));
  line-height: var(--lh-display, 1.08);
  color: var(--bone-100);
  margin: 0;
  max-inline-size: 20ch;
  text-wrap: balance;
  animation: band-rise 1.5s var(--cine-ease) 0.3s backwards;
}

.pagehero .pagehero__lede {
  color: var(--bone-200);
  font-size: var(--text-body-lg);
  max-inline-size: 56ch;
  margin: 1.125rem 0 0;
  animation: band-rise 1.4s var(--cine-ease) 0.44s backwards;
}

@keyframes band-rise { from { opacity: 0; translate: 0 18px; } }

/* ---------------------------------------------------------------------------
 * Interlude — a full-bleed band between two movements of copy.
 *
 * Masked at BOTH edges, so it has no top or bottom line at all: the photograph
 * emerges out of the page ground and dissolves back into it.
 * ------------------------------------------------------------------------- */

.interlude { margin-block: clamp(1rem, 4vw, 3rem); }

.interlude__media {
  position: relative;
  margin: 0;
  block-size: min(52svh, 30rem);
  overflow: clip;
}

.interlude__media picture { display: contents; }

.interlude__media img {
  display: block;
  inline-size: 100%;
  block-size: 112%;             /* headroom for the drift below */
  object-fit: cover;
  mask-image: linear-gradient(to bottom,
    transparent 0%, #000 16%, #000 84%, transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom,
    transparent 0%, #000 16%, #000 84%, transparent 100%);
}

@supports (animation-timeline: view()) {
  .interlude__media img {
    animation: interlude-drift linear both;
    animation-timeline: view();
    animation-range: entry 0% exit 100%;
  }
  @keyframes interlude-drift {
    from { translate: 0 -8%; }
    to   { translate: 0 0; }
  }
}

/* Lit rather than flown in: the band arrives by coming up to full exposure
   over 2.4s. Hidden state only under JS with motion allowed. */
.js:not(.no-motion) .interlude__media img {
  opacity: .55;
  scale: 1.04;
  transition: opacity var(--cine-band) var(--cine-ease),
              scale var(--cine-band) var(--cine-ease);
}
.js:not(.no-motion) .interlude.is-seen .interlude__media img { opacity: 1; scale: 1; }

/* ---------------------------------------------------------------------------
 * Movements — the body copy between the bands.
 * ------------------------------------------------------------------------- */

/* The movements own the vertical rhythm; the article adds none of its own, or
   the last block and the footer end up separated by two paddings and a
   margin — a hole the eye reads as the page having stopped early. */
.content--cinematic { padding-block: 0; }

.movement { padding-block: clamp(3.5rem, 9vw, 7rem); position: relative; }
.movement:first-child { padding-block-start: clamp(1.5rem, 4vw, 3rem); }
.movement:last-child { padding-block-end: clamp(3rem, 7vw, 5rem); }

/* A hairline gold rule opens each movement after the first — the cadence that
   tells the eye a new argument has started without a heavy divider. */
.movement + .interlude + .movement > .wrap::before {
  content: "";
  display: block;
  inline-size: 4rem;
  block-size: 1px;
  background: linear-gradient(to right, var(--gold-metal), transparent);
  margin-block-end: clamp(1.5rem, 4vw, 2.5rem);
}
[dir="rtl"] .movement + .interlude + .movement > .wrap::before {
  background: linear-gradient(to left, var(--gold-metal), transparent);
}

/* The coda: what a reader of this page can do next. Wider measure than prose
   because it is an invitation, not an argument. */
.movement--coda h2 {
  font-size: var(--text-display-3);
  color: var(--bone-100);
  margin-block: 0 1rem;
  max-inline-size: 20ch;
  text-wrap: balance;
}
.movement--coda .lede { max-inline-size: 54ch; }
.movement__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 1.25rem;
  margin-block-start: 2rem;
}

/* Prose on the obsidian ground. The tokens are already dark — body carries
   data-surface="cinematic" — so this only sets rhythm and the link register. */
.content--cinematic .prose { max-inline-size: 68ch; color: var(--text-secondary); }
.content--cinematic .prose > :first-child { margin-block-start: 0; }
.content--cinematic .prose h2 {
  color: var(--bone-100);
  font-size: var(--text-display-3);
  margin-block: 2.75rem 1rem;
  max-inline-size: 22ch;
  text-wrap: balance;
}
.content--cinematic .prose > h2:first-child { margin-block-start: 0; }
.content--cinematic .prose h3 {
  color: var(--bone-100);
  font-size: var(--text-heading-2);
  margin-block: 2rem .625rem;
}
.content--cinematic .prose p { margin-block: 0 1.25em; }
.content--cinematic .prose li { margin-block-end: .5em; }
.content--cinematic .prose strong { color: var(--text-primary); }
.content--cinematic .prose a {
  color: var(--gold-300);
  text-decoration-color: color-mix(in srgb, var(--gold-metal) 55%, transparent);
  text-underline-offset: 3px;
  transition: color var(--dur-quick) var(--cine-ease);
}
.content--cinematic .prose a:hover { color: var(--gold-200); text-decoration-color: currentColor; }
.content--cinematic .prose blockquote {
  margin-inline: 0;
  padding-inline-start: 1.5rem;
  border-inline-start: 2px solid color-mix(in srgb, var(--gold-metal) 45%, transparent);
  color: var(--bone-200);
}

/* ---------------------------------------------------------------------------
 * The reveal system.
 *
 * One attribute, `data-reveal`, on anything that should lift as it enters.
 * cinematic.js adds `.is-seen` once and never removes it — scrolling back up
 * never re-hides content that has already been read.
 *
 * `[data-reveal-group]` staggers its children: cinematic.js writes
 * --reveal-index on each one, and the delay falls out of it. That keeps the
 * cadence in CSS where it can be tuned, and the counting in JS where it is one
 * line.
 * ------------------------------------------------------------------------- */

.js:not(.no-motion) [data-reveal] {
  opacity: 0;
  translate: 0 26px;
  transition:
    opacity var(--cine-reveal) var(--cine-ease) var(--reveal-delay, var(--cine-reveal-delay)),
    translate var(--cine-reveal) var(--cine-ease) var(--reveal-delay, var(--cine-reveal-delay));
}
.js:not(.no-motion) [data-reveal].is-seen { opacity: 1; translate: 0 0; }

.js:not(.no-motion) [data-reveal-group] > [data-reveal] {
  --reveal-delay: calc(var(--cine-reveal-delay) + var(--reveal-index, 0) * var(--cine-stagger));
}

/* ---------------------------------------------------------------------------
 * Forms and registries on the cinematic ground.
 *
 * These blocks used to sit on the light register surface. They now inherit the
 * dark tokens from <body>; what is left is giving them a plate to sit on so a
 * form does not float unanchored over a photograph's afterglow.
 * ------------------------------------------------------------------------- */

.plate {
  background: color-mix(in srgb, var(--surface-raised) 82%, transparent);
  border: 1px solid var(--border);
  backdrop-filter: blur(12px);
  padding: clamp(1.5rem, 4vw, 2.5rem);
  max-inline-size: 44rem;
}
.plate--wide { max-inline-size: none; }
/* The lookup is two fields; a plate three times their width around them reads
   as a form that lost most of itself. */
.verify .plate { max-inline-size: 33rem; }
.plate > :first-child { margin-block-start: 0; }
.plate > :last-child { margin-block-end: 0; }

.movement .verify__form,
.movement .apply__form { margin-block-start: 1.5rem; }

/* Route cards on /apply. The gold edge on hover is the only colour change —
   the lift is what carries the affordance. */
.content--cinematic .apply__routes { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.25rem; }
.content--cinematic .apply__routes a {
  /* border-strong, deliberately: this outline IS the clickable target and is
     the only thing marking where the card begins, so it is a UI component
     boundary under WCAG 1.4.11 and needs 3:1. The decorative --border token
     would look better here and would fail. */
  border-color: var(--border-strong);
  background: color-mix(in srgb, var(--surface-raised) 62%, transparent);
  transition:
    border-color var(--dur-base) var(--cine-ease),
    background-color var(--dur-base) var(--cine-ease),
    translate var(--dur-base) var(--cine-ease);
}
.content--cinematic .apply__routes a:hover {
  border-color: var(--gold-metal);
  background: color-mix(in srgb, var(--surface-raised) 88%, transparent);
  translate: 0 -3px;
}
.content--cinematic .apply__routes h2 { margin-block: 0 .5rem; font-size: var(--text-heading-2); color: var(--bone-100); }
.content--cinematic .apply__routes p { margin: 0; color: var(--text-secondary); }

/* ---------------------------------------------------------------------------
 * Narrow screens: the hero gives back height, the bands give back drama.
 * ------------------------------------------------------------------------- */

@media (max-width: 40rem) {
  .pagehero { min-block-size: min(56svh, 26rem); }
  .interlude__media { block-size: min(38svh, 18rem); }
}

/* ---------------------------------------------------------------------------
 * Reduced motion: the finished page, instantly.
 *
 * Every keyframe above ends at the natural state, so switching them off IS the
 * design. motion.css already collapses transition durations globally; these
 * rules remove the entrance animations and the scroll-driven drift, which it
 * does not reach.
 * ------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .pagehero__media,
  .pagehero__crumbs,
  .pagehero__eyebrow,
  .pagehero__title,
  .pagehero__lede,
  .interlude__media img { animation: none; }

  .interlude__media img { opacity: 1; scale: 1; }
}

.no-motion .pagehero__media,
.no-motion .pagehero__crumbs,
.no-motion .pagehero__eyebrow,
.no-motion .pagehero__title,
.no-motion .pagehero__lede,
.no-motion .interlude__media img { animation: none; }

/* Printing a photograph of a room helps nobody read a standard. */
@media print {
  .pagehero__media, .pagehero__scrim, .interlude { display: none; }
  .pagehero { min-block-size: 0; }
  .pagehero__content { padding: 0; }
}
