/* ==========================================================================
   WELV pre-order site: site styles. Load AFTER /assets/css/base.css.

   base.css is a Tailwind v4 build. Almost every rule in it sits inside
   @layer, and this file is unlayered, so a rule here wins over those rules
   whatever their specificity. One exception to keep in mind: an !important
   inside a layer beats an !important here. The clone-detection beacon in the
   original bundle was such a declaration (body background !important), which
   is why it was cut out of base.css instead of being overridden.
   ========================================================================== */


/* --------------------------------------------------------------------------
   1. FONTS: Newsreader (serif) and Hanken Grotesk (sans), SIL Open Font
   License 1.1, self-hosted. The files are Google Fonts' Latin files;
   Newsreader is cut with fonttools to the weights below (roman 340-370,
   italic 320, the optical-size axis kept). OFL-Newsreader.txt and
   OFL-HankenGrotesk.txt sit next to them. base.css still names its own
   faces (--font-sans: "AkkuratLL", --font-serif: "Editorial New"); the
   tokens below replace them.
   Each face takes the weights the rules ask for and draws its own: serif
   200 and 300 draw 370, serif italic 320, sans 300 draws 260, sans 400
   draws 400, sans 700 draws 600. size-adjust draws Newsreader 5% smaller,
   which keeps the page's line breaks.
   -------------------------------------------------------------------------- */

@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 370;
  src: url('/assets/fonts/Newsreader-latin.woff2') format('woff2');
  font-display: swap;
  size-adjust: 95%;
}

@font-face {
  font-family: 'Newsreader';
  font-style: italic;
  font-weight: 320;
  src: url('/assets/fonts/Newsreader-Italic-latin.woff2') format('woff2');
  font-display: swap;
  size-adjust: 95%;
}

@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 260;
  src: url('/assets/fonts/HankenGrotesk-latin.woff2') format('woff2');
  font-display: swap;
}

@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 330 600;
  src: url('/assets/fonts/HankenGrotesk-latin.woff2') format('woff2');
  font-display: swap;
}

/* The masked email on /reserve (j•••@gmail.com): Hanken draws U+2022 as a square, so the dot
   comes from Newsreader. These two faces must stay after the Hanken faces above. */
@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 260;
  src: url('/assets/fonts/Newsreader-latin.woff2') format('woff2');
  unicode-range: U+2022;
}

@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 330 600;
  src: url('/assets/fonts/Newsreader-latin.woff2') format('woff2');
  unicode-range: U+2022;
}

/* The app's own faces, used only inside the drawn app screens (.ap and .chart in site.css), so the
   phone never reads as part of the page. DM Sans and DM Serif Display, SIL Open Font License 1.1,
   from Google Fonts, cut to the Latin characters the screens use (DM Sans keeps its weight axis). */
@font-face {
  font-family: 'DM Sans';
  font-style: normal;
  font-weight: 400 500;
  src: url('/assets/fonts/DMSans-app-subset.woff2') format('woff2');
  font-display: swap;
}

@font-face {
  font-family: 'DM Serif Display';
  font-style: normal;
  font-weight: 400;
  src: url('/assets/fonts/DMSerifDisplay-app-subset.woff2') format('woff2');
  font-display: swap;
}

/* Stand-ins while the faces above load (font-display: swap): Georgia and Arial, scaled to
   Newsreader's and Hanken Grotesk's average width on this page's own copy and given their ascent
   and descent, so a headline breaks the same way before and after the swap. Measured in Chromium;
   where Georgia or Arial is missing (Android) the stack falls through as before. Newsreader's
   optical size makes it narrower at the page's 22-40px sizes than in large display, so its
   stand-ins are tuned there (no line moves at 390 and 1440 wide); Chrome scales ascent and
   descent by size-adjust, so they are Newsreader's box divided by it. */
@font-face {
  font-family: 'Newsreader Fallback';
  font-style: normal;
  font-weight: 1 1000;
  src: local('Georgia');
  size-adjust: 88%; ascent-override: 79.34%; descent-override: 28.6%; line-gap-override: 0%;
}
@font-face {
  font-family: 'Newsreader Fallback';
  font-style: italic;
  font-weight: 1 1000;
  src: local('Georgia Italic'), local('Georgia-Italic');
  size-adjust: 78%; ascent-override: 89.52%; descent-override: 32.27%; line-gap-override: 0%;
}
@font-face {
  font-family: 'Hanken Grotesk Fallback';
  font-style: normal;
  font-weight: 330 1000;
  src: local('Arial'), local('ArialMT');
  size-adjust: 100.2%; ascent-override: 99.8%; descent-override: 30.24%; line-gap-override: 0%;
}
@font-face {
  font-family: 'Hanken Grotesk Fallback';
  font-style: normal;
  font-weight: 1 329;
  src: local('Arial'), local('ArialMT');
  size-adjust: 99.1%; ascent-override: 100.91%; descent-override: 30.58%; line-gap-override: 0%;
}
/* the shell's font tokens and classes (base.css names its own faces, then a generic family)
   with the stand-ins behind them; the web fonts stay first */
:root {
  --font-sans: "Hanken Grotesk", "Hanken Grotesk Fallback", sans-serif;
  --font-serif: "Newsreader", "Newsreader Fallback", serif;
  font-family: "Hanken Grotesk", "Hanken Grotesk Fallback", sans-serif;
}
.font-sans { font-family: "Hanken Grotesk", "Hanken Grotesk Fallback", sans-serif; }
.font-serif { font-family: "Newsreader", "Newsreader Fallback", serif; }
/* the 24px paragraphs in the "What you have now" tabs (font-thin): lighter than the headings */
.font-serif.font-thin { font-variation-settings: 'wght' 340; }
/* serif words inside the mirrored sans headings (block 8, the slider) inherit tracking-tight
   (-0.025em); Newsreader keeps 0.4 of it, as every serif rule below does */
.tracking-tight .font-serif.italic { letter-spacing: -0.01em; }


/* --------------------------------------------------------------------------
   2. CANVAS: the page colour, not white, shows on overscroll and
   rubber-band scrolling. html carries it; body stays transparent so it does
   not paint a second, different layer.
   -------------------------------------------------------------------------- */

html { background-color: #f7f1e8; }
body { background: transparent; }

/* Keyboard focus and in-page jumps (/#reserve) stop clear of the sticky header and, on phones,
   of the sticky reserve button (WCAG 2.2, 2.4.11). */
html { scroll-padding-top: 104px; }
@media (max-width: 767.98px) { html { scroll-padding-top: 112px; scroll-padding-bottom: 96px; } }


/* --------------------------------------------------------------------------
   2b. TIER AND SHIPPING VERSIONS. The server marks <html> with data-tier
   (founding | standard: after member #100) and data-ship (open | closed:
   after the December 25 cut-off); counter.js refreshes them. A line written
   twice shows only the version that matches; with no mark the founding,
   open version shows.
     <span data-tier-only="founding">…</span><span data-tier-only="standard">…</span>
     <span data-ship-only="open">…</span><span data-ship-only="closed">…</span>
   -------------------------------------------------------------------------- */

html[data-tier="standard"] [data-tier-only="founding"],
html:not([data-tier="standard"]) [data-tier-only="standard"],
html[data-ship="closed"] [data-ship-only="open"],
html:not([data-ship="closed"]) [data-ship-only="closed"] { display: none !important; }


/* --------------------------------------------------------------------------
   2c. FOCUS in the shell (header, block 8, slider, footer): the house ring in
   place of the browser's blue one. Dark ink with a thin ground-coloured halo,
   so it also reads over the dark cards and photos; light ink on the graphite
   footer.
   -------------------------------------------------------------------------- */

:is([data-cy="header"], [data-cy="home-features"], [data-cy="home-membership"]) :focus-visible {
  outline: 2px solid #1b1d1a; outline-offset: 3px; box-shadow: 0 0 0 3px rgb(247 241 232 / .9);
}
[data-cy="footer"] :focus-visible { outline: 2px solid #f3efe9; outline-offset: 3px; border-radius: 2px; }

/* The footer's postal line (copy-deck §17): 13 px in light ink, 8.7:1 on the graphite footer. */
.welv-footer-address { font-size: 13px; line-height: 18px; letter-spacing: .005em; color: rgb(243 239 233 / .74); }


/* --------------------------------------------------------------------------
   3. GROUND: the sandstone ground under six radial glows, exactly as the
   original paints it (clone3 index.html L271@12715). There the wrapper is
   data-cy="radialGradientBG_div" with "relative min-h-full bg-sandstone-200",
   and its six first children are "absolute w-full h-full top-0 left-0
   pointer-events-none" with these gradients as inline styles. Each glow is
   sized from the whole wrapper, which in the original runs from the
   membership heading down to the last block (the hero sits outside it).

   Markup. Keep the glows first and in this order; later ones paint over
   earlier ones:
     <div class="welv-ground">
       <div class="welv-ground__glow welv-ground__glow--cream-1" aria-hidden="true"></div>
       <div class="welv-ground__glow welv-ground__glow--blue-1" aria-hidden="true"></div>
       <div class="welv-ground__glow welv-ground__glow--cream-2" aria-hidden="true"></div>
       <div class="welv-ground__glow welv-ground__glow--blue-2" aria-hidden="true"></div>
       <div class="welv-ground__glow welv-ground__glow--neutral" aria-hidden="true"></div>
       <div class="welv-ground__glow welv-ground__glow--gold" aria-hidden="true"></div>
       ...sections...
     </div>
   As in the original, the glows are positioned, so they paint over later
   content that is not positioned itself (and under content that is).
   -------------------------------------------------------------------------- */

.welv-ground {
  position: relative;
  min-height: 100%;
  background-color: #f7f1e8;
}

.welv-ground__glow,
.welv-ground__glow--cream-1,
.welv-ground__glow--blue-1,
.welv-ground__glow--cream-2,
.welv-ground__glow--blue-2,
.welv-ground__glow--neutral,
.welv-ground__glow--gold {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.welv-ground__glow--cream-1 { background-image: radial-gradient(circle at 20% 20%, rgba(234, 220, 207, 1) 0px, transparent 20%); }
.welv-ground__glow--blue-1  { background-image: radial-gradient(circle at 0% 40%, rgba(182, 207, 221, 0.5) 0px, transparent 20%); }
.welv-ground__glow--cream-2 { background-image: radial-gradient(circle at 20% 55%, rgba(243, 235, 225, 1) 0px, transparent 20%); }
.welv-ground__glow--blue-2  { background-image: radial-gradient(circle at 99% 27%, rgba(181, 228, 254, 0.5) 0px, transparent 20%); }
.welv-ground__glow--neutral { background-image: radial-gradient(ellipse at 45% 55%, rgba(213, 195, 171, 0.4) 0px, transparent 60%); }
.welv-ground__glow--gold    { background-image: radial-gradient(circle at 50% 85%, rgba(255, 182, 72, 0.3) 0px, transparent 20%); }


/* --------------------------------------------------------------------------
   4. GROUND COMPOSITIONS for future sections: clone3 shared/welv-blocks.css
   lines 1277-1303 (the ground block), where A was on .wb-b02/04/05/09 and B on
   .wb-b03/06/07/10. The same palette re-composed per section, so a long
   section does not stretch one set of glows: A is warm left with a cool
   right edge, B is a cool left edge with gold low and right. Every glow
   fades out before the section's top and bottom, so stacked sections show
   no seam. --wb-ground, position and z-index come from clone3's .wb base:
   the stacking lifts the section above the .welv-ground glows, which would
   otherwise tint it.
   -------------------------------------------------------------------------- */

.ground-a,
.ground-b {
  --wb-ground: #f7f1e8;
  position: relative;
  z-index: 1;
  background-color: var(--wb-ground);
}

.ground-a {
  background-image:
    radial-gradient(52% 40% at 14% 44%, rgb(234 220 207 / 0.95) 0%, rgb(234 220 207 / 0.5) 45%, rgb(234 220 207 / 0) 100%),
    radial-gradient(30% 26% at 100% 30%, rgb(181 228 254 / 0.42) 0%, rgb(181 228 254 / 0.2) 45%, rgb(181 228 254 / 0) 100%),
    radial-gradient(64% 36% at 52% 62%, rgb(213 195 171 / 0.34) 0%, rgb(213 195 171 / 0.16) 45%, rgb(213 195 171 / 0) 100%);
}
.ground-b {
  background-image:
    radial-gradient(30% 38% at 0% 46%, rgb(182 207 221 / 0.45) 0%, rgb(182 207 221 / 0.22) 45%, rgb(182 207 221 / 0) 100%),
    radial-gradient(48% 36% at 30% 56%, rgb(243 235 225 / 1) 0%, rgb(243 235 225 / 0.55) 45%, rgb(243 235 225 / 0) 100%),
    radial-gradient(42% 26% at 58% 72%, rgb(255 182 72 / 0.22) 0%, rgb(255 182 72 / 0.1) 45%, rgb(255 182 72 / 0) 100%),
    radial-gradient(60% 40% at 70% 40%, rgb(213 195 171 / 0.28) 0%, rgb(213 195 171 / 0.13) 45%, rgb(213 195 171 / 0) 100%);
}


/* --------------------------------------------------------------------------
   5. HERO: copied verbatim from clone3 shared/welv-blocks.css lines
   1181-1236 (hero text) and 1242-1266 (short-screen fixes). The hero markup
   keeps the .wh-* classes and data-cy="landing-page-compound-hero".
   -------------------------------------------------------------------------- */

/* ==========================================================================
   HERO TEXT — the first screen's lines under the h1 (copy: workflow
   wf_3de95b2b-0e3, converge:hero). The hero is the mirrored section, not a
   .wb block: it keeps its own faces (Hanken Grotesk, Newsreader) and colour.
   One button only, to the same reservation target as blocks 4 and 10.
   The recorded sentence and its stamp stay visible slots until the
   recording confirms them; the video background is kept (founder).
   ========================================================================== */

@media (min-width: 1024px) and (max-height: 599px) { .wh-eyebrow { display: none; } }
/* Phones key the short-screen hero on the window height at load (content.js sets data-vh0 to
   "short" or "tall", per width), so an Android in-app keyboard shrinking the window does not
   reflow the hero and move every form below it. Before the script runs, the media query decides. */
@media (max-width: 1023.98px) and (max-height: 599px) { html:not([data-vh0="tall"]) .wh-eyebrow { display: none; } }
@media (max-width: 1023.98px) { html[data-vh0="short"] .wh-eyebrow { display: none; } }
.wh-label, .wh-phrase, .wh-price, .wh-terms, .wh-under { -webkit-hyphens: manual; hyphens: manual; }

.wh-label { margin-top: 16px; font-family: var(--font-sans); font-size: 14px; line-height: 19px; color: #4a4741; }
.wh-phrase {
  margin-top: 4px;
  font-family: var(--font-serif);
  font-weight: 200;
  font-style: italic;
  font-size: 34px;
  line-height: 37px;
  letter-spacing: -0.32px;
  color: #1b1d1a;
  text-wrap: balance;
}
.wh-offer { margin-top: 16px; display: flex; flex-direction: column; align-items: flex-start; }
.wh-price { font-family: var(--font-sans); font-size: 17px; line-height: 23px; color: #1b1d1a; }
.wh-terms { margin-top: 4px; max-width: 342px; font-family: var(--font-sans); font-size: 14px; line-height: 20px; color: #4a4741; }
.wh-cta {
  margin-top: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 56px;
  padding: 0 28px;
  border-radius: 28px;
  background: #1b1d1a;
  color: #f3efe9;
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 16px;
  line-height: 20px;
  text-decoration: none;
}
.wh-cta:hover { background: #4a4741; color: #f3efe9; }
.wh-cta:focus-visible { outline: 2px solid #1b1d1a; outline-offset: 3px; }
.wh-under { margin-top: 10px; max-width: 342px; font-family: var(--font-sans); font-size: 13px; line-height: 18px; color: #4a4741; }

@media (min-width: 1024px) {
  .wh-label { margin-top: 24px; font-size: 15px; line-height: 20px; }
  .wh-phrase { margin-top: 6px; font-size: 44px; line-height: 50px; letter-spacing: -0.48px; }
  .wh-offer { margin-top: 24px; }
  .wh-price { font-size: 19px; line-height: 26px; }
  .wh-terms { margin-top: 6px; max-width: 480px; font-size: 15px; line-height: 22px; }
  .wh-cta { margin-top: 24px; height: 60px; padding: 0 32px; border-radius: 30px; }
  .wh-under { margin-top: 12px; max-width: 480px; font-size: 14px; line-height: 20px; }
}

/* The headline in Newsreader: 0.4 of tracking-tighter; on desktop a wider column and 56px glyphs, so it stays
   on two lines. The size undoes Newsreader's 95% size-adjust, with the line box (61.6px) and tracking (-1.12px)
   the approved renders had. It applies only to windows taller than 760px; shorter ones keep the F2 rules below. */
[data-cy="landing-page-compound-hero"] h1 { letter-spacing: -0.02em; }
@media (min-width: 1024px) {
  [data-cy="landing-page-compound-hero"] .max-w-xl { max-width: 42rem; }
  [data-cy="landing-page-compound-hero"] h1 { text-wrap: balance; }
}
@media (min-width: 1024px) and (min-height: 761px) {
  [data-cy="landing-page-compound-hero"] h1 { font-size: calc(3.5rem / 0.95); line-height: 3.85rem; letter-spacing: -0.019em; }
}

/* F2 — the hero box is exactly one screen tall and clips what overflows it, so on short screens the lines tighten
   until the one button and the line under it fit. */
@media (max-width: 1023px) { html[data-vh0="short"] [data-cy="landing-page-compound-hero"] h1 { font-size: 30px; line-height: 33px; } }
@media (max-width: 1023px) and (max-height: 600px) {
  html:not([data-vh0="tall"]) [data-cy="landing-page-compound-hero"] h1 { font-size: 30px; line-height: 33px; }
  .wh-label { margin-top: 8px; }
  .wh-phrase { font-size: 28px; line-height: 31px; }
  .wh-offer { margin-top: 12px; }
  .wh-terms { margin-top: 2px; }
  .wh-cta { margin-top: 12px; height: 48px; }
  .wh-under { margin-top: 8px; }
}
@media (min-width: 1024px) and (max-height: 760px) {
  [data-cy="landing-page-compound-hero"] h1 { font-size: 46px; line-height: 50px; }
  .wh-label { margin-top: 14px; }
  .wh-phrase { font-size: 34px; line-height: 38px; }
  .wh-offer { margin-top: 16px; }
  .wh-cta { margin-top: 16px; height: 52px; }
  .wh-under { margin-top: 8px; }
}

@media (min-width: 1024px) and (max-height: 640px) {
  [data-cy="landing-page-compound-hero"] h1 { font-size: 40px; line-height: 44px; }
  .wh-phrase { font-size: 30px; line-height: 34px; }
  .wh-cta { height: 48px; }
}


/* --------------------------------------------------------------------------
   6. MEMBERSHIP SECTION (heading + card slider): copied verbatim from clone3
   shared/welv-blocks.css lines 1087-1089. This is what 127.0.0.1:8128 serves:
   clip instead of the original overflow-hidden, so the section is not a scroll
   container.
   -------------------------------------------------------------------------- */

/* the mirrored wrapper clips with overflow:hidden, which turns it into a scroll container and stops the sticky
   card below from pinning to the viewport; clip clips the same without that side effect */
section[data-cy="home-membership"] { overflow: clip; }


/* --------------------------------------------------------------------------
   7. PHOTO PLACEHOLDER: stands in for a photo until the real one exists.
   It takes the place of the <img>: the block's photos are absolutely positioned
   inside a positioned frame, and the placeholder fills that frame the same
   way, under the frame's own rounding and clipping.
     <div class="welv-ph" role="img" aria-label="What the photo will show">Photo coming soon</div>
   The label is the element's own text; the builder chooses the words.

   The default is light, in the ground's palette. Where light text sits on
   top of the photo (the slider cards' titles, the menu cards' captions), use
   welv-ph--dark, so that text stays readable as it is on the real photos.
   -------------------------------------------------------------------------- */

.welv-ph {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 16px;
  overflow: hidden;
  border: 1px solid rgb(74 71 65 / 0.14);           /* hairline, inside the frame */
  background-color: #efe6db;                        /* one step under the page ground, so the frame reads as a frame */
  background-image:
    radial-gradient(60% 50% at 50% 46%, rgb(254 250 239 / 0.95) 0%, rgb(254 250 239 / 0.55) 50%, rgb(254 250 239 / 0) 100%),
    radial-gradient(75% 60% at 0% 100%, rgb(182 207 221 / 0.55) 0%, rgb(182 207 221 / 0.2) 50%, rgb(182 207 221 / 0) 100%),
    radial-gradient(80% 65% at 100% 100%, rgb(213 195 171 / 0.55) 0%, rgb(213 195 171 / 0.2) 50%, rgb(213 195 171 / 0) 100%),
    radial-gradient(55% 45% at 100% 0%, rgb(255 182 72 / 0.16) 0%, rgb(255 182 72 / 0) 100%);
  color: #6e6b65;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 12px;
  line-height: 16px;
  letter-spacing: 0.02em;
  text-align: center;
  text-wrap: balance;
  -webkit-user-select: none;
  user-select: none;
}

.welv-ph--dark {
  border-color: rgb(247 241 232 / 0.12);
  background-color: #3a3835;
  background-image:
    radial-gradient(60% 50% at 50% 46%, rgb(74 71 65 / 0.9) 0%, rgb(74 71 65 / 0.4) 50%, rgb(74 71 65 / 0) 100%),
    radial-gradient(75% 60% at 0% 100%, rgb(182 207 221 / 0.16) 0%, rgb(182 207 221 / 0) 100%),
    radial-gradient(80% 65% at 100% 100%, rgb(255 182 72 / 0.1) 0%, rgb(255 182 72 / 0) 100%),
    radial-gradient(55% 45% at 100% 0%, rgb(213 195 171 / 0.14) 0%, rgb(213 195 171 / 0) 100%);
  color: rgb(247 241 232 / 0.72);
}

@media (min-width: 1024px) {
  .welv-ph { font-size: 13px; line-height: 18px; }
}

/* Until the photos ship (founder's call, B9) no page shows the placeholder's label: visible
   placeholder text reads as a draft. Its role=img and aria-label stay. */
.welv-ph, .welv-ph--dark { color: transparent; }


/* --------------------------------------------------------------------------
   8. TOUCH AREA of the phone menu button. The protected header draws it at
   40 px (size-10, md:size-12); a finger needs 44. An invisible ring 4 px
   wide round it takes the taps, so the drawn button is unchanged.
   -------------------------------------------------------------------------- */

@media (max-width: 767.98px) {
  [data-cy="nav-menu-button"]::after {
    content: "";
    position: absolute;
    inset: -4px;
    border-radius: 9999px;
  }
}

/* The open phone menu keeps its scrolling to itself (no scroll chaining into the page behind it)
   and is exactly as tall as the visible screen, toolbars included. */
[data-cy="header"] .overflow-y-auto { overscroll-behavior: contain; }
@media (max-width: 1023.98px) { [data-cy="header"] .h-\[100svh\] { height: 100dvh; } }
