/*
  ============================================================================
  The holding page — everything that is NOT the hero.
  ============================================================================

  This site is the hero component and nothing else: no header, no nav, no
  sheets, no footer. css/tokens.css and css/hero.css are byte-for-byte
  copies of the main site's, so the hero looks and behaves exactly as it
  does there. This file contains only what has to differ, and each rule
  below says which assumption of the full site it is undoing.

  Load order matters: this file comes last so it wins on equal specificity.
*/

:root {
  /*
    There is no header here, so the hero is the whole screen rather than
    the screen minus a header. --hero-h in tokens.css is
    calc(100vh - var(--header-h)), and custom properties substitute at
    computed-value time, so zeroing the header is enough — the hero's
    height follows automatically and tokens.css stays an untouched copy.
  */
  --header-h: 0px;

  /* How far the hero is taken down when the message arrives. */
  --veil: 0.78;

  /*
    The one loose thread in the copied tokens.

    tokens.css line ~192 declares
        --frost-img: url("../assets/logo/rafik-mark-blur-s22.svg")
    which is the pre-blurred mark painted behind the main site's sheets.
    That asset is not shipped here and does not need to be: the variable is
    only ever read by .panel[data-frost], and this page has no panels — so
    the URL is never resolved and never requested. Confirmed: the page
    fetches seven resources and that file is not among them.

    It is neutralised anyway, because a dead reference pointing OUT of a
    folder that is meant to be self-contained is a trap for whoever adds
    the next element. Overriding it here rather than editing tokens.css
    keeps that file a byte-for-byte copy, which is what makes re-copying it
    after a hero retune safe.
  */
  --frost-img: none;
}

/*
  100dvh, with 100vh declared first as the fallback.

  This page must be exactly one screen with nothing to scroll to, and on
  iOS Safari 100vh is the height with the browser chrome RETRACTED — so a
  100vh page is taller than the visible area on first paint and the phone
  offers a scroll that reveals nothing. dvh is the visible height. Older
  browsers ignore the second declaration and keep the first.
*/
:root { --hero-h: 100vh; }
@supports (height: 100dvh) {
  :root { --hero-h: 100dvh; }
}

html, body {
  height: 100%;
  /*
    Nothing scrolls. Safe here in a way it is not on the main site, where
    overflow on html/body silently disables position:sticky for every
    descendant — the hero below is deliberately relative, not sticky, so
    there is no sticky left to break.
  */
  overflow: hidden;
}

/*
  The hero stops being sticky.

  On the full site it pins under the header while the first sheet climbs
  over it. Here there is no header, nothing to climb, and nowhere to
  scroll, so pinning would be machinery with no purpose — and it is what
  makes the `overflow: hidden` above safe.
*/
.hero-1.sheet {
  position: relative;
  top: auto;
  height: var(--hero-h);
  min-height: 0;
  border-bottom: 0;
}

/*
  ---- The veil ----

  "Darkens it significantly at the end." Deliberately NOT the hero's own
  black plate (.hero-1.sheet::after): that plate is already spoken for
  twice — it runs the opening fade, and then the 24-second ambient breathe
  in css/hero.css. Driving it from here too would put two things on one
  property, which is the failure this project has hit before and now has a
  standing rule against.

  It covers the MARK as well as the photograph, and that is the whole
  point of where it sits in the document. The first version veiled only
  the photo (a child of .hero-1__photo, which is its own stacking context)
  and it failed on measurement: the mark's strokes keep their absolute
  lightness while everything around them drops, so the signature becomes
  the brightest thing on screen and the ember line lands on top of it.
  Measured, that version: 2.21:1 worst case at 1440x900, against a 3:1
  floor. Not a tuning problem — the wrong element was being darkened.

  So it is a direct child of .hero-1 placed AFTER .hero-1__mark-wrap:
  z-index 1 ties with the mark and later-in-document wins, which puts it
  over photo (0) and mark (1) and under content (2). The room and the
  signature go down together, the message alone stays up.
*/
.holding__veil {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: var(--ground);
  opacity: 0;
  pointer-events: none;
}
.is-holding .holding__veil {
  opacity: var(--veil);
  transition: opacity 1100ms cubic-bezier(0.33, 0, 0.2, 1);
}

/*
  ---- The message ----

  It sits in the hero's own content column, in the slot the scroll cue
  occupies on the full site — the place the eye is already going, and
  already aligned to the hero's left margin and rhythm. No new layout
  system, no centred block fighting the mark's strokes for the middle of
  the frame.
*/
.holding__note {
  margin-bottom: var(--space-4);
  opacity: 0;
  transform: translateY(0.6rem);
}
.is-holding .holding__note {
  opacity: 1;
  transform: none;
  /*
    Starts 400ms into the veil rather than after it. The message should
    arrive as the room goes down, not queue behind it — waiting for the
    darkening to finish reads as two separate events.
  */
  transition:
    opacity 700ms cubic-bezier(0.16, 0.84, 0.3, 1) 400ms,
    transform 700ms cubic-bezier(0.16, 0.84, 0.3, 1) 400ms;
}

/*
  Ember, as asked, and the brand value is kept rather than lightened to
  buy contrast. tokens.css records that ember is a label colour — around
  4:1 on the deep tones — and not a running-copy colour, which is exactly
  what this is: three words, set large, letterspaced, over a hero taken
  down to 22% of its brightness. The contrast is measured against real
  rendered pixels at three viewports, not assumed; the figures are in the
  README.
*/
.holding__status {
  font-family: var(--font-mono);
  font-size: clamp(1.05rem, 0.82rem + 1.15vw, 1.9rem);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
  line-height: 1.2;
  /*
    Bold is a legibility decision, not a stylistic one. WCAG counts text as
    "large" — and so lowers the contrast floor from 4.5:1 to 3:1 — at 24px
    regular OR 18.66px bold. This line is ~18.8px on a 390px phone, which
    clears the bold threshold and misses the regular one, so weight is what
    keeps the phone case honest rather than a bigger size that would wrap
    "UNDER CONSTRUCTION" onto two lines at that width.
  */
  font-weight: 700;
}

/*
  The second line is bone, not ember.

  Two weights of the same accent read as one thing gone wrong rather than
  as a hierarchy, and this line is longer and set smaller — which is
  exactly the case tokens.css warns off ember for. Bone also lets the
  ember line stay the single brightest note on the screen.
*/
/*
  --step-meta is 11px. That is the right size for a caption sitting beside
  a screenful of other content, and the wrong size here: these two lines
  are most of what the page has to say, so they are set a step up. Scaled
  rather than fixed, so the phone does not get the desktop's compromise.
*/
.holding__sub {
  margin-top: 0.6em;
  font-family: var(--font-mono);
  font-size: clamp(0.78rem, 0.72rem + 0.28vw, 0.95rem);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text);
}

.holding__link {
  margin-top: var(--space-3);
  font-family: var(--font-mono);
  font-size: clamp(0.78rem, 0.72rem + 0.28vw, 0.95rem);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text);

  /*
    Underlined, not colour-only. The rule against relying on colour alone
    to carry meaning applies to "this is a link" as much as to anything
    else, and on a page with exactly one link there is no context to infer
    it from.

    text-decoration rather than border-bottom, because the 44px tap target
    below is built from the box and a border would be pinned to the bottom
    of that box — leaving the rule floating ~15px under the words, reading
    as a divider rather than as a link. An underline is drawn on the TEXT,
    so the target can grow without dragging it along.
  */
  text-decoration: underline;
  /*
    Not --rule-strong (16% white): that is a hairline value for dividing
    panels, and at 1px under 15px type it is effectively invisible — the
    link read as plain text. This is the one link on the page, so the
    underline has to actually carry "clickable" on its own.
  */
  text-decoration-color: rgba(237, 233, 224, 0.55);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.45em;

  /* Comfortable target on a phone without drawing a visible box. */
  display: inline-flex;
  align-items: center;
  min-height: 44px;

  transition: color var(--motion-fast) var(--ease-standard),
              text-decoration-color var(--motion-fast) var(--ease-standard);
}
.holding__link:hover,
.holding__link:focus-visible {
  color: var(--accent);
  text-decoration-color: var(--accent);
}
.holding__link .arrow {
  margin-left: 0.6em;
  /* Decorative: the link already reads as a link and names its destination. */
  transition: transform var(--motion-fast) var(--ease-standard);
}
.holding__link:hover .arrow,
.holding__link:focus-visible .arrow { transform: translateX(0.2em); }

/*
  With motion reduced, base.css collapses every transition to ~0ms, so the
  veil and the message land instantly instead of animating. That is the
  correct outcome and needs no rule — but the opening sequence is skipped
  entirely in that case (js/holding.js), which would otherwise leave the
  page on the hero with no message at all. The script handles it by
  applying the holding state immediately; this note exists so the
  connection between the two files is not lost.
*/
