/*
 * The public marketing page.
 *
 * Same palette and display face as the two apps (ios-client Theme/Theme.swift), the salon
 * portal and the admin console, so somebody who arrives here and then signs in does not feel
 * handed between two products. Light only, like both apps, which pin .preferredColorScheme
 * (.light) -- no prefers-color-scheme block, because a half-finished dark variant looks worse
 * than none.
 *
 * The noir treatment is carried by the header, the hero and the sign-up band rather than by a
 * photograph. The app's welcome screen uses InstantCover.jpg and BrandLogo.png; neither is
 * reused here. BrandLogo is a photograph of an identifiable model, which is a licensing
 * question for a public site rather than a design one, and InstantCover has "B VOGUE" baked
 * into it -- a salon's branding, not the product's.
 */

:root {
  --noir900: #0A0A0A;
  --noir600: #2A2A28;
  --noir500: #3D3D3A;
  --noir400: #6B6B66;
  --noir200: #D4D4D0;
  --noir100: #EDEDEB;
  --noir50:  #F7F7F5;
  --gold600: #A8841F;
  --gold500: #C9A227;
  --gold400: #D9B64A;
  --gold100: #F5EDD6;
  --cream:   #F8F5ED;
  --ivory:   #FFFEF9;
  --danger:  #9F1239;
  --display: Georgia, "Times New Roman", serif;
  --text: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }

/* The hidden attribute is a UA-stylesheet rule and loses to any class that sets
   display -- which is how a "hidden" video button rendered anyway, greyed and
   dead, next to the one that works. Everything here that toggles does it with
   [hidden], so this has to win. */
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--ivory);
  color: var(--noir600);
  font: 17px/1.6 var(--text);
}

.wrap { max-width: 1060px; margin: 0 auto; padding: 0 20px; }

.skip {
  position: absolute; left: -9999px;
  background: var(--noir900); color: var(--ivory);
  padding: 10px 16px; border-radius: 0 0 8px 0; z-index: 20;
}
.skip:focus { left: 0; top: 0; }
#main:focus { outline: none; }

/* ---- bar ---------------------------------------------------------------- */

.bar { background: var(--noir900); color: var(--ivory); position: sticky; top: 0; z-index: 10; }
.bar-in {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; min-height: 62px; flex-wrap: wrap;
}
.mark {
  display: inline-flex; align-items: center;
  font-family: var(--display); font-size: 19px; letter-spacing: 0.01em;
  color: var(--ivory); text-decoration: none;
}
.bar nav { display: flex; align-items: center; gap: 18px; }
.quiet { color: var(--noir200); text-decoration: none; font-size: 15px; }
.quiet:hover, .quiet:focus { color: var(--gold400); text-decoration: underline; }

/* ---- buttons ------------------------------------------------------------ */

.btn {
  display: inline-block;
  background: var(--gold500); color: var(--noir900);
  font: 600 16px/1.2 var(--text);
  text-decoration: none; text-align: center;
  padding: 14px 26px; border-radius: 999px;
  border: 1px solid var(--gold600); cursor: pointer;
}
.btn:hover, .btn:focus { background: var(--gold600); color: var(--ivory); }
.btn[disabled] { opacity: 0.5; cursor: default; }
.btn[disabled]:hover { background: var(--gold500); color: var(--noir900); }
.btn.small { padding: 9px 17px; font-size: 15px; }
.btn.wide { width: 100%; padding: 15px 26px; font-size: 17px; }
.btn.ghost { background: transparent; color: var(--noir600); border: 1px solid var(--noir200); }
.btn.ghost:hover, .btn.ghost:focus { background: var(--noir50); color: var(--noir900); border-color: var(--noir400); }

a:focus-visible, .btn:focus-visible, input:focus-visible { outline: 2px solid var(--gold600); outline-offset: 2px; }

/* ---- hero --------------------------------------------------------------- */

.hero {
  background: var(--noir900);
  color: var(--noir200);
  padding: 76px 0 70px;
  border-bottom: 1px solid #000;
}
.hero-in { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.75fr); gap: 48px; align-items: center; }
/* The brand photograph, dissolved into the noir behind it rather than sitting on
   it as a square. Same treatment as the apps' welcome screen, which calls
   .fadeEdgesIntoBackground() on this exact image -- done here with a mask so the
   edge is soft at any size and needs no alpha channel in the file. */
.hero-art { display: flex; justify-content: center; }
.hero-art img {
  width: min(420px, 86vw);
  height: auto;
  -webkit-mask-image: radial-gradient(closest-side, #000 52%, rgba(0,0,0,0.75) 72%, transparent 97%);
          mask-image: radial-gradient(closest-side, #000 52%, rgba(0,0,0,0.75) 72%, transparent 97%);
}

.eyebrow {
  margin: 0 0 16px; text-transform: uppercase;
  letter-spacing: 0.16em; font-size: 12px; font-weight: 600;
  color: var(--gold400);
}
h1 {
  font-family: var(--display); font-weight: 400;
  font-size: clamp(34px, 5.4vw, 54px); line-height: 1.08;
  margin: 0 0 22px; color: var(--ivory); max-width: 24ch;
}
/* Each sentence gets its own line where there is room for one, so the break
   falls at the full stop rather than wherever the measure happens to run out.
   Below the breakpoint they run together and wrap normally -- two short lines
   are better than four very short ones on a phone. */
h1 span { display: block; }
@media (max-width: 520px) { h1 span { display: inline; } }
.hero .lede { color: var(--noir200); }
.lede { font-size: 19px; max-width: 56ch; color: var(--noir500); margin: 0 0 28px; }
.lede.narrow { margin-bottom: 34px; }
.cta-row { display: flex; flex-wrap: wrap; gap: 12px; margin: 0 0 20px; }
.fine { font-size: 14px; color: var(--noir400); margin: 0; max-width: 62ch; }
.hero .fine { color: var(--gold400); font-weight: 500; }

/* ---- video -------------------------------------------------------------- */

.video { padding: 56px 0; background: var(--noir900); }
.video h2 { color: var(--ivory); }
.frame { position: relative; padding-top: 56.25%; border-radius: 14px; overflow: hidden; background: #000; }
.frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* ---- sections ----------------------------------------------------------- */

.band { background: var(--noir50); border-bottom: 1px solid var(--noir100); padding: 66px 0; }
.split { padding: 66px 0; border-bottom: 1px solid var(--noir100); }
.band, .split, .join, .video { scroll-margin-top: 92px; }

h2 {
  font-family: var(--display); font-weight: 400;
  font-size: clamp(27px, 3.5vw, 35px);
  color: var(--noir900); margin: 0 0 24px;
}

.cards { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(252px, 1fr)); }
.card { background: var(--ivory); border: 1px solid var(--noir100); border-radius: 14px; padding: 25px; }
.band .card { background: var(--ivory); }
.card h3 { font-family: var(--display); font-weight: 400; font-size: 20px; margin: 0 0 10px; color: var(--noir900); }
.card p { margin: 0; color: var(--noir500); font-size: 16px; }
.split > .wrap > .cta-row, .band > .wrap > .cta-row { margin-top: 32px; }

/* ---- sign-up ------------------------------------------------------------ */

.join { padding: 72px 0 80px; background: linear-gradient(180deg, var(--cream), var(--ivory)); }

/* /join is its own page, so its heading is an h1 on a light background -- not the hero's
   h1, which is ivory on noir and would be invisible here. */
.join-page { padding-top: 56px; }
.join-title {
  color: var(--noir900);
  font-size: clamp(32px, 5vw, 46px);
  max-width: none;
  margin-bottom: 18px;
}
.join-page .fine { margin-bottom: 26px; color: var(--gold600); font-weight: 500; }
.join-page .eyebrow { color: var(--gold600); }
.closer { text-align: left; }
.form, .done { max-width: 560px; margin-top: 8px; }
.field { margin: 0 0 20px; border: 0; padding: 0; }
/* Direct children only. The radio pills inside .choices are labels too, and an
   unscoped `.field label` beat `.choice` on specificity -- block, bold, margin --
   so every pill rendered as a field heading with a radio stuck to it. */
.field > label, .field > legend { display: block; font-weight: 600; font-size: 15px; color: var(--noir600); margin: 0 0 7px; padding: 0; }
.req { color: var(--gold600); font-weight: 500; font-size: 13px; }
.opt { color: var(--noir400); font-weight: 400; font-size: 13px; }
.field input[type="text"], .field input[type="email"], .field input[type="tel"] {
  width: 100%; padding: 12px 14px; font: 16px/1.4 var(--text);
  color: var(--noir900); background: var(--ivory);
  border: 1px solid var(--noir200); border-radius: 10px;
}
.field input::placeholder { color: var(--noir400); }
.hint { font-size: 13px; color: var(--noir400); margin: 7px 0 0; }

.choices { display: flex; flex-wrap: wrap; gap: 9px; }
.choice {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 15px; border: 1px solid var(--noir200); border-radius: 999px;
  font-weight: 400; font-size: 15px; cursor: pointer; margin: 0;
  background: var(--ivory);
}
.choice span { font-weight: 400; }
.choice:has(input:checked) { border-color: var(--gold600); background: var(--gold100); }
.choice input { accent-color: var(--gold600); margin: 0; }

.agree { display: flex; gap: 11px; align-items: flex-start; font-size: 15px; color: var(--noir500); margin: 0 0 20px; }
.agree input { margin-top: 3px; accent-color: var(--gold600); flex: none; }
.agree a { color: var(--gold600); }

.formerr {
  background: #FFF1F2; border: 1px solid #FECDD3; color: var(--danger);
  border-radius: 10px; padding: 11px 14px; font-size: 15px; margin: 0 0 16px;
}

.done h3 { font-family: var(--display); font-weight: 400; font-size: 24px; margin: 0 0 10px; color: var(--noir900); }
.done p { color: var(--noir500); margin: 0 0 16px; }
.done .cta-row { margin: 0; }
.done .cta-row:empty { display: none; }

/* ---- footer ------------------------------------------------------------- */

.foot { background: var(--noir900); color: var(--noir200); padding: 34px 0; }
.foot-in { display: flex; flex-wrap: wrap; gap: 8px 28px; justify-content: space-between; font-size: 14px; }
.foot .fine { color: var(--noir400); }
.foot a { color: var(--noir200); }

@media (max-width: 820px) {
  .hero-in { grid-template-columns: 1fr; gap: 32px; }
  .hero-art { order: -1; }
  .hero-art img { width: min(300px, 72vw); }
  h1 { max-width: none; }
}
@media (max-width: 640px) {
  .hero { padding: 48px 0 52px; }
  .band, .split { padding: 50px 0; }
  .join { padding: 54px 0 62px; }
}

/* ---- the three doors ----------------------------------------------------- */

.pick { padding: 66px 0 72px; background: var(--noir50); border-bottom: 1px solid var(--noir100); }
.picks { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); margin-top: 30px; }

.pickbtn {
  display: block; width: 100%; text-align: left; cursor: pointer;
  background: var(--ivory); border: 1px solid var(--noir200); border-radius: 18px;
  padding: 24px 22px; font: inherit; color: inherit;
  transition: border-color 0.15s, transform 0.15s;
}
.pickbtn:hover, .pickbtn:focus-visible { border-color: var(--gold500); transform: translateY(-2px); }
.pickbtn b { display: block; font-family: var(--display); font-weight: 400; font-size: 26px; color: var(--noir900); }
.pickbtn span { display: block; margin-top: 4px; font-size: 15px; color: var(--noir500); }
@media (prefers-reduced-motion: reduce) { .pickbtn { transition: none; } .pickbtn:hover { transform: none; } }

/* ---- a step -------------------------------------------------------------- */

/* With JavaScript off these stack and the page reads as three plain sections.
   With it on, one shows at a time and the nav below is fixed to the screen. */
.flow { padding: 0; }
.step {
  max-width: 760px; margin: 0 auto; padding: 56px 20px 40px;
  display: flex; flex-direction: column; align-items: flex-start; gap: 18px;
}
.step h2 {
  font-family: var(--display); font-weight: 400;
  font-size: clamp(28px, 5.2vw, 42px); line-height: 1.14;
  color: var(--noir900); margin: 0; max-width: 20ch;
}
.step p { margin: 0; font-size: 19px; line-height: 1.55; color: var(--noir500); max-width: 52ch; }
.step .fine { font-size: 14px; }
.step-cta { display: flex; flex-wrap: wrap; gap: 12px; }

/* A phone screenshot and a piece of brand art want different treatment: one is a
   device and keeps its proportions, the other is a square plate. */
.step img {
  display: block; width: 100%; height: auto; margin-top: 4px;
  max-width: 260px; border-radius: 22px; border: 1px solid var(--noir200);
}
.step img.art { max-width: 300px; border-radius: 20px; border-color: var(--noir100); }

/* With a flow open, one step has to FIT the screen -- picture included. Stacked, the
   headline alone pushed the picture below the fold, where a presenter never scrolls to
   it and (while these were lazy) the browser never even fetched it. So above 820px the
   step is two columns, words beside picture, and the picture is capped to the height
   actually available between the header and the nav. */
.in-flow .step {
  min-height: calc(100vh - 200px);
  justify-content: center;
  padding-top: 24px;
}
.in-flow .bar { position: static; }

@media (min-width: 820px) {
  /* Words keep their natural flex stacking; the picture is lifted out of flow and
     centred in a reserved gutter on the right. A grid cell spanning every row was the
     first attempt, and the spanning picture forced the text rows apart -- the headline
     and the line under it ended up at opposite ends of the column. */
  .in-flow .step {
    position: relative;
    max-width: 1000px;
    padding-right: 400px;
  }
  .in-flow .step > img {
    position: absolute;
    right: 20px;
    top: 50%;
    transform: translateY(-50%);
    margin-top: 0;
    max-height: calc(100vh - 260px);
    width: auto;
  }
  .in-flow .step > img:not(.art) { max-width: 300px; }
  .in-flow .step > img.art { max-width: 340px; }
}}

.stepnav {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  background: var(--noir900); color: var(--noir200);
  padding: 12px 20px calc(12px + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid #000;
}
.stepnav-top { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 10px; }
.stepnav-row { display: flex; gap: 12px; max-width: 760px; margin: 0 auto; }
.stepnav-row .btn { flex: 1; }
.stepnav-row .btn.ghost { color: var(--noir200); border-color: var(--noir500); background: transparent; }
.stepnav-row .btn.ghost:hover, .stepnav-row .btn.ghost:focus { background: var(--noir600); color: var(--ivory); }
.stepdots { display: flex; align-items: center; gap: 7px; margin: 0; max-width: 760px; }
.stepdots .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--noir500); }
.stepdots .dot.on { background: var(--gold500); }
.stepdots .dot-count { margin-left: 8px; font-size: 13px; color: var(--noir400); }
.stepclose { background: none; border: 0; color: var(--noir400); font: 15px/1.2 var(--text); cursor: pointer; padding: 6px 2px; }
.stepclose:hover, .stepclose:focus { color: var(--gold400); }

@media (max-width: 640px) {
  .pick { padding: 48px 0 54px; }
  .step { padding: 36px 20px 30px; gap: 14px; }
  .in-flow .step { min-height: calc(100vh - 190px); }
  .step img { max-width: 210px; }
  .step img.art { max-width: 230px; }
}

/* A film we cannot embed is offered as a link in the same frame. */
.frame.is-link { padding-top: 0; min-height: 160px; display: flex; align-items: center; justify-content: center; }
