/* HEZ - coming soon. Single static page, no build step, no JavaScript.
 * Order: font faces, design tokens, reset, page.
 */

/* --- Font Face: General Sans (CDN) --- */
@font-face {
  font-family: 'General Sans';
  src: url('https://cdn.fontshare.com/wf/XNSTRDQX7BAWZ3DZZPIFMK2OZQGTXO46/VXTQ55TYTCF52CQIRPKX7BT7GMOCIZDE/IZWX6NDNHLM2P633B3N3KFOPJXCTK4FX.woff2') format('woff2');
  font-weight: 200;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'General Sans';
  src: url('https://cdn.fontshare.com/wf/XNSTRDQX7BAWZ3DZZPIFMK2OZQGTXO46/XKJIHAXHNCAIZKMZXEZECFAJYJNWBYHP/CYEFH5FF42IYURJUBUQOXOQGPW6GKQCN.woff2') format('woff2');
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'General Sans';
  src: url('https://cdn.fontshare.com/wf/XNSTRDQX7BAWZ3DZZPIFMK2OZQGTXO46/ZCVWKRFXFO6IIZDPFRXJKPDTYA63RYVI/JA237QCL52E65G4YUVZHWKQOJVN2RDOR.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'General Sans';
  src: url('https://cdn.fontshare.com/wf/XNSTRDQX7BAWZ3DZZPIFMK2OZQGTXO46/CQFFEGXM565HRFMSFH3HNRQVNUWNV5HQ/77YE7PKCBDYQXENW4LKMYPWF34BVWMTB.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'General Sans';
  src: url('https://cdn.fontshare.com/wf/XNSTRDQX7BAWZ3DZZPIFMK2OZQGTXO46/P26YD55MZGGV4P5RDAZDRKJLF7VWZ6I4/NQXFG7RRWRYDO4QI7CMWQE6M3IWYSGPY.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

/* ==================== DESIGN TOKENS ==================== */

/* Hallmark · genre: editorial · theme: Atelier
 * Portable token system for HÊZ.
 * Palette is sampled from the campaign photograph, not invented:
 * the paper values are the studio wall, the accent is the burgundy
 * at the model's neckline. Anchor hue 64 (warm).
 * axes — paper band: light · display style: grotesk-sans · accent hue: warm
 */
:root {
  /* --- Colour ------------------------------------------------------ */
  /* Sampled: wall #DED4C7 / #CFBEAF, ink #1E1710, accent from #793727 */
  --color-paper: oklch(87% 0.021 72);
  --color-paper-2: oklch(81% 0.028 64);
  --color-paper-3: oklch(72% 0.038 66);
  --color-rule: oklch(40% 0.028 62);
  --color-ink-2: oklch(31% 0.025 62);
  --color-ink: oklch(21% 0.017 67);
  --color-accent: oklch(43% 0.13 33);
  --color-accent-ink: oklch(96% 0.012 75);
  --color-focus: oklch(48% 0.16 35);

  /* Worst-case contrast over the photograph's brightest 2 %:
     ink 9.0:1 · ink-2 6.7:1 · rule 3.4:1 — all AA or better. */

  /* --- Type -------------------------------------------------------- */
  --font-display: "Switzer", ui-sans-serif, system-ui, -apple-system, sans-serif;
  --font-body: "General Sans", ui-sans-serif, system-ui, -apple-system, sans-serif;

  /* 1.25 major third, 16 px base */
  --text-xs: 0.64rem;
  --text-sm: 0.8rem;
  --text-base: 1rem;
  --text-md: 1.25rem;
  --text-lg: 1.5625rem;
  --text-xl: 1.9531rem;
  --text-2xl: 2.4414rem;
  --text-3xl: 3.0518rem;
  --text-4xl: 3.8147rem;
  --text-display: clamp(2.75rem, 5vw + 1rem, 5.25rem);
  --text-display-s: clamp(2.25rem, 3.5vw + 1rem, 3.75rem);

  /* --- Space (4 pt) ------------------------------------------------ */
  --space-3xs: 0.125rem;
  --space-2xs: 0.25rem;
  --space-xs: 0.5rem;
  --space-sm: 0.75rem;
  --space-md: 1rem;
  --space-lg: 1.5rem;
  --space-xl: 2.5rem;
  --space-2xl: 4rem;
  --space-3xl: 6rem;
  --space-4xl: 9rem;

  --page-gutter: clamp(1.25rem, 4.5vw, 4.5rem);

  /* --- Motion ------------------------------------------------------ */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in: cubic-bezier(0.7, 0, 0.84, 0);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --dur-micro: 120ms;
  --dur-short: 220ms;
  --dur-long: 420ms;
  --dur-entrance: 1400ms;

  /* --- Rules & depth ----------------------------------------------- */
  --rule-hair: 1px;
  --radius-none: 0;

  --z-base: 1;
  --z-raised: 10;
  --z-dropdown: 100;
  --z-sticky: 200;
  --z-modal: 400;
  --z-toast: 500;
  --z-tooltip: 600;
}


/* ==================== RESET ==================== */

/* --- Modern reset -------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: "kern" 1;
  text-rendering: optimizeLegibility;
  /* clip, never hidden — preserves position: sticky/fixed on descendants */
  overflow-x: clip;
}

body {
  font-family: var(--font-body);
  font-weight: 400;
  font-size: var(--text-base);
  line-height: 1.6;
  color: var(--color-ink);
  background-color: var(--color-paper);
  min-height: 100dvh;
  overflow-x: clip;
}

img,
picture,
video,
canvas,
svg {
  display: block;
  max-width: 100%;
}

input,
button,
textarea,
select {
  font: inherit;
  color: inherit;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  cursor: pointer;
  border: none;
  background: none;
}

ul,
ol {
  list-style: none;
}

/* --- Focus (never animated — keyboard users need it instantly) ------ */
:focus {
  outline: none;
}

:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 3px;
}

::selection {
  background-color: var(--color-accent);
  color: var(--color-accent-ink);
}

/* --- Reduced motion ------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 150ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 150ms !important;
  }
}


/* ==================== PAGE ==================== */

/* Hallmark · genre: editorial · macrostructure: Photographic · theme: Atelier
 * tone: luxury · anchor hue: 64 (warm) · enrichment: none (real photography)
 * nav: N9 edge-aligned minimal · cta: C2 inline form · footer: Ft2 inline single line
 * contrast verified against the photograph itself, darkest-3rd-percentile,
 * 1024→2560 desktop and 320/375/414 phone: every text region ≥ 4.5:1.
 */

/* ------------------------------------------------------------------ */
/* Page shell                                                          */
/* ------------------------------------------------------------------ */

.page {
  position: relative;
  width: 100%;
  min-height: 100svh;
  min-height: 100dvh;
  overflow: clip;
  background-color: var(--color-paper-2);
  isolation: isolate;
}

/* ---- The photograph ---- */

.plate {
  position: absolute;
  inset: 0;
  z-index: var(--z-base);
  overflow: clip;
}

/* <picture> is a plain wrapper with auto height; without this the img's
   height:100% has no definite parent to resolve against and falls back to
   the photograph's intrinsic aspect ratio. */
.plate picture {
  display: block;
  width: 100%;
  height: 100%;
}

.photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* The model's shoes sit on the very bottom edge of the frame and the top of
     the frame is empty wall. Anchoring the bottom means any vertical crop --
     which happens on any viewport wider than the photo's 1.79:1 -- is taken
     off the blank top instead of off her feet. */
  object-position: center bottom;
  /* settles from a slight over-zoom — the only spatial move on the page */
  transform: scale(1.06);
  opacity: 0;
  animation: plate-settle var(--dur-entrance) var(--ease-out) forwards;
}

@keyframes plate-settle {
  to {
    transform: scale(1);
    opacity: 1;
  }
}

/* Legibility veil. Phone only — on desktop the wall is genuinely empty and
   the photograph is left untouched. Two stops of the paper hue, no decoration. */
.veil {
  position: absolute;
  inset: 0;
  pointer-events: none;
  /* Only the lower floor is lifted, and only on phones, so the form and the
     footer have a ground. The top two-thirds of the photograph is untouched. */
  background: linear-gradient(
    to bottom,
    transparent 0%,
    transparent 30%,
    color-mix(in srgb, var(--color-paper) 46%, transparent) 58%,
    color-mix(in srgb, var(--color-paper) 62%, transparent) 100%
  );
  opacity: 0;
  animation: veil-in var(--dur-entrance) var(--ease-out) forwards;
}

@keyframes veil-in {
  to {
    opacity: 1;
  }
}

/* ---- Content grid ---- */

.content {
  position: relative;
  z-index: var(--z-raised);
  display: grid;
  grid-template-rows: auto 1fr auto;
  min-height: 100svh;
  min-height: 100dvh;
  padding: clamp(1.1rem, 2.4vh, 2rem) var(--page-gutter);
  gap: var(--space-lg);
  color: var(--color-ink);
}

/* ------------------------------------------------------------------ */
/* Entrance — one orchestrated sequence, staggered by DOM index         */
/* ------------------------------------------------------------------ */

.wordmark,
.social,
.lede,
.signup,
.foot {
  opacity: 0;
  transform: translateY(10px);
  animation: rise var(--dur-long) var(--ease-out) forwards;
}

/* Masthead first. */
.wordmark,
.social {
  animation-delay: calc(160ms + var(--i, 0) * 90ms);
}

/* Then the headline (see .lineInner). Supporting copy only after the headline
   has landed — previously the lede finished at 1.21s and the headline at 1.61s,
   which led the eye to the wrong thing first. */
.lede,
.signup,
.foot {
  animation-duration: 380ms;
  animation-delay: calc(1150ms + var(--i, 0) * 90ms);
}

@keyframes rise {
  to {
    opacity: 1;
    transform: none;
  }
}

/* ------------------------------------------------------------------ */
/* N9 · masthead — wordmark hard-left, one link hard-right              */
/* ------------------------------------------------------------------ */

.masthead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
}

.wordmark {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

/* The wordmark PNG is used as a mask so the logo renders in exact token ink
   rather than the artwork's flat black. */
.wordmarkMark {
  display: block;
  width: clamp(64px, 7.5vw, 104px);
  aspect-ratio: 560 / 313;
  background-color: var(--color-ink);
  -webkit-mask-image: url("/images/hez-wordmark-mask.png");
  mask-image: url("/images/hez-wordmark-mask.png");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: left center;
  mask-position: left center;
  transition: background-color var(--dur-short) var(--ease-out);
}

.social {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  min-height: 44px;
  padding-block: var(--space-2xs);
  font-size: var(--text-sm);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--color-ink);
}

.socialLabel {
  position: relative;
  padding-bottom: 2px;
  background-image: linear-gradient(var(--color-ink), var(--color-ink));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% var(--rule-hair);
  transition: background-size var(--dur-short) var(--ease-out);
}

.socialGlyph {
  font-size: 0.95em;
  transition: transform var(--dur-short) var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .social:hover .socialLabel {
    background-size: 100% var(--rule-hair);
  }

  .social:hover .socialGlyph {
    transform: translate(2px, -2px);
  }
}

/* ------------------------------------------------------------------ */
/* The type block                                                      */
/* ------------------------------------------------------------------ */

.stage {
  align-self: stretch;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  /* the message and the action stay one block, low in the thumb zone */
  justify-content: flex-end;
  max-width: 34rem;
  min-width: 0;
}

.display {
  margin: 0 0 var(--space-lg);
  font-family: var(--font-display);
  font-weight: 300;
  font-style: normal;
  text-transform: uppercase;
  font-size: clamp(1.9rem, 8.5vw, 2.6rem);
  /* caps have no descenders, so the line box must not go below 1.0 or the
     cap-tops of line two collide with line one (slop-test gate 55) */
  line-height: 1.15;
  letter-spacing: 0.05em;
  color: var(--color-ink);
  text-wrap: balance;
  overflow-wrap: anywhere;
  min-width: 0;
}

/* Each line rises out from behind its own edge. */
.line {
  display: block;
  overflow: hidden;
  /* the mask box must clear the descenders ("g", "r") or overflow clips them */
  padding-bottom: 0.06em;
  margin-bottom: -0.06em;
}

.lineInner {
  display: block;
  transform: translateY(110%);
  animation: line-up 700ms var(--ease-out) forwards;
  animation-delay: calc(380ms + var(--i, 0) * 120ms);
}

@keyframes line-up {
  to {
    transform: none;
  }
}

.lede {
  margin: 0 0 var(--space-xl);
  max-width: min(32ch, 85vw);
  text-wrap: balance;
  font-size: var(--text-base);
  font-weight: 300;
  line-height: 1.55;
  color: var(--color-ink);
}

.signup {
  width: 100%;
  max-width: 26rem;
}

/* ------------------------------------------------------------------ */
/* Ft2 · one line, hairline above                                      */
/* ------------------------------------------------------------------ */

.foot {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-md);
  /* kept off the figure — full-bleed across the model drops below 4.5:1 */
  width: 100%;
  padding-top: var(--space-sm);
  border-top: var(--rule-hair) solid
    color-mix(in srgb, var(--color-rule) 42%, transparent);
  font-size: var(--text-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-ink);
}

.status {
  display: inline-flex;
  align-items: center;
  gap: 0.7em;
  margin: 0;
  white-space: nowrap;
}

/* the page's only block of accent — a 5 px square */
.statusMark {
  width: 5px;
  height: 5px;
  flex: none;
  background-color: var(--color-accent);
}

.caption {
  /* On a phone the footer row runs straight across her shoe, so the plate
     caption is desktop-only; the status line carries the footer alone. */
  display: none;
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-sm);
  letter-spacing: 0.01em;
  text-transform: none;
  color: var(--color-ink);
  white-space: nowrap;
}

/* ------------------------------------------------------------------ */
/* C2 · inline form-as-CTA  (styles consumed by EmailForm)              */
/* ------------------------------------------------------------------ */

.formWrapper,
.subscribeForm {
  width: 100%;
}

.formLabel {
  display: block;
  margin-bottom: var(--space-sm);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-ink);
}

.inputRow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-sm);
  border-bottom: var(--rule-hair) solid var(--color-ink);
  transition: border-color var(--dur-short) var(--ease-out);
}

.emailField {
  min-width: 0;
  min-height: 44px;
  padding: var(--space-xs) 0;
  border: none;
  outline: none;
  background: none;
  font-size: var(--text-base);
  font-weight: 300;
  letter-spacing: 0.01em;
  color: var(--color-ink);
}

.emailField::placeholder {
  color: var(--color-ink-2);
  opacity: 1;
}

.emailField:focus-visible {
  outline: none;
}

/* focus moves to the rule, so the ring never boxes the whole row */
.inputRow:focus-within {
  border-bottom-color: var(--color-focus);
  border-bottom-width: 2px;
}

/* error outranks focus: a field that failed validation keeps saying so while
   the cursor is still in it (:focus-within alone is 0,2,0 and would win). */
.inputRow.inputError,
.inputRow.inputError:focus-within {
  border-bottom-color: var(--color-accent);
  border-bottom-width: 2px;
}

.subscribeBtn {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  min-height: 44px;
  padding: var(--space-xs) 0 var(--space-xs) var(--space-sm);
  background: none;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--color-ink);
  transition: color var(--dur-micro) var(--ease-out),
    opacity var(--dur-micro) var(--ease-out);
}

.btnGlyph {
  transition: transform var(--dur-short) var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .subscribeBtn:hover:not(:disabled) {
    color: var(--color-accent);
  }

  .subscribeBtn:hover:not(:disabled) .btnGlyph {
    transform: translateX(3px);
  }
}

.subscribeBtn:active:not(:disabled) .btnGlyph {
  transform: translateX(1px);
}

.subscribeBtn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.feedbackArea {
  margin-top: var(--space-sm);
  min-height: 1.35rem;
  font-size: var(--text-sm);
  font-weight: 400;
}

.successMsg,
.errorMsg {
  margin: 0;
  color: var(--color-ink);
  /* replaces framer-motion's AnimatePresence fade — plays on mount */
  animation: msg-in 250ms var(--ease-out) both;
}

@keyframes msg-in {
  from {
    opacity: 0;
    transform: translateY(4px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.errorMsg {
  color: var(--color-accent);
}

.visuallyHidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Short phones (iPhone SE and similar) have no clear band left once the
   headline and lede are placed -- the lede lands on the model's face. Those
   screens get a stronger wash; taller phones keep the photograph clean. */
@media (max-width: 60rem) and (max-height: 700px) {
  .veil {
    background: linear-gradient(
      to bottom,
      transparent 0%,
      color-mix(in srgb, var(--color-paper) 56%, transparent) 32%,
      color-mix(in srgb, var(--color-paper) 58%, transparent) 100%
    );
  }
}

/* ------------------------------------------------------------------ */
/* ≥ 60rem — the landscape crop, type hung on the empty wall            */
/* ------------------------------------------------------------------ */

@media (min-width: 60rem) {
  /* the wall carries the type unaided; no veil at all */
  .veil {
    display: none;
  }

  .content {
    gap: var(--space-xl);
  }

  .stage {
    align-self: center;
    /* right edge = gutter + this, held inside the contrast-safe 46 % */
    max-width: min(34rem, calc(44vw - var(--page-gutter)));
    flex: none;
  }

  /* the wall is one clear field — the block reads as a single unit again */
  .signup {
    margin-top: 0;
  }

  .display {
    font-size: clamp(2.5rem, 4.2vw, 3.5rem);
    margin-bottom: var(--space-xl);
  }

  .lede {
    font-size: var(--text-md);
    max-width: 44ch;
    margin-bottom: var(--space-2xl);
  }

  .foot {
    /* stays clear of the figure — past ~60% the model drops contrast to 3.1:1 */
    max-width: 60%;
  }

  .caption {
    display: block;
  }

  .formLabel {
    margin-bottom: var(--space-md);
  }
}

@media (min-width: 90rem) {
  /* caps are wide: the column grows with the type so the lines stay crisp.
     Still inside the contrast-safe 46 %. */
  .stage {
    max-width: min(40rem, calc(44vw - var(--page-gutter)));
  }
}

/* ------------------------------------------------------------------ */
/* Coarse pointers                                                     */
/* ------------------------------------------------------------------ */

@media (pointer: coarse) {
  .social,
  .subscribeBtn,
  .wordmark {
    min-height: 48px;
  }
}

/* ------------------------------------------------------------------ */
/* Reduced motion — spatial motion collapses to a crossfade             */
/* ------------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
  .photo {
    transform: none;
    animation: veil-in 150ms linear forwards;
  }

  .lineInner {
    transform: none;
    animation: none;
  }

  .wordmark,
  .social,
  .lede,
  .signup,
  .foot {
    transform: none;
    animation: veil-in 150ms linear forwards;
  }

  .socialGlyph,
  .btnGlyph {
    transition: none;
  }

  .successMsg,
  .errorMsg {
    animation: veil-in 150ms linear both;
  }
}
