/* SOLLOS SMS signup — brand palette supplied by the client.
   Roc Grotesk / Riviera Nights are licensed, so this uses the nearest good
   free pairing: Archivo (geometric grotesque, close to Roc) for display,
   Inter for body copy. */

:root {
  --cream:  #FDF6E7;
  --ink:    #002A53;
  --orange: #FF6B00;
  --sun:    #FFC72C;

  --ink-70: rgba(0, 42, 83, 0.70);
  --ink-55: rgba(0, 42, 83, 0.55);
  --line:   rgba(0, 42, 83, 0.20);
  --line-strong: rgba(0, 42, 83, 0.42);

  --radius: 10px;
  --tap: 52px;
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--cream);
  color: var(--ink);
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 16px;
  line-height: 1.55;
}

/* Everything lives in one column. Without this the masthead and photo ran the
   full width of the display while the form sat in a 460px well in the middle,
   which is what made wide screens fall apart. */
.page {
  width: 100%;
  max-width: 800px;
  min-height: 100dvh;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
}

/* --- masthead ----------------------------------------------------------- */
/* The supplied artwork is a wide email header with generous whitespace. At
   phone widths that shrinks the wordmark to nothing, so it is scaled up and
   clipped rather than letterboxed. */
.masthead {
  overflow: hidden;
  line-height: 0;
}
.masthead img {
  display: block;
  width: 145%;
  margin-left: -22.5%;
  height: auto;
}
@media (min-width: 640px) {
  .masthead img { width: 100%; margin-left: 0; max-width: 1600px; margin-inline: auto; }
}

/* --- layout ------------------------------------------------------------- */
.wrap {
  position: relative;   /* lifts the copy above the hero it now overlaps */
  z-index: 1;
  width: 100%;
  max-width: 460px;
  margin: 0 auto;
  padding: 34px 22px 40px;
  flex: 1 0 auto;
}
@media (min-width: 640px) {
  .wrap { padding-top: 52px; }
}

.state { animation: rise .28s ease both; }
@keyframes rise {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .state { animation: none; }
}

/* --- type --------------------------------------------------------------- */
h1 {
  font-family: Archivo, Inter, sans-serif;
  font-weight: 800;
  font-size: clamp(21px, 7.4vw, 34px);   /* pre-script fallback; fitHeadline() sets the real size */
  line-height: 1.1;
  letter-spacing: 0.005em;
  text-transform: uppercase;
  margin: 0 0 14px;
}

/* The headline is written as two deliberate lines. Each is its own block and
   never wraps, so a third line is structurally impossible; fitHeadline() in
   app.js then shrinks the type until both lines fit the column. Guessing a
   font-size from character counts was not reliable across devices — the widths
   depend on Archivo's real metrics and on whether the webfont has loaded yet,
   so it is measured instead. */
h1 span {
  display: block;
  white-space: nowrap;
}
h1.wrapped span { white-space: normal; }   /* last-resort escape, see app.js */

.eyebrow {
  font-family: Archivo, sans-serif;
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--orange);
  margin: 0 0 10px;
}

.lede   { font-size: 16.5px; color: var(--ink-70); margin: 0 0 26px; }
.muted  { font-size: 14px; color: var(--ink-55); }
.centered { text-align: center; }

/* Everything above the form is centred; the form itself is not. */
.eyebrow, h1, .lede, .state > .muted { text-align: center; }
.badge { margin-left: auto; margin-right: auto; }
.callout { text-align: left; }

/* --- fields ------------------------------------------------------------- */
.field { margin-bottom: 18px; }

label {
  display: block;
  font-family: Archivo, sans-serif;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin-bottom: 6px;
}

input[type="text"], input[type="email"], input[type="tel"], select {
  width: 100%;
  height: var(--tap);
  padding: 0 14px;
  font: inherit;
  font-size: 16px; /* below 16px iOS zooms the whole page on focus */
  color: var(--ink);
  background: #fff;
  border: 1.5px solid var(--line);
  border-radius: var(--radius);
  transition: border-color .15s ease, box-shadow .15s ease;
  appearance: none;
}

input:focus-visible, select:focus-visible, .btn:focus-visible, .linkish:focus-visible {
  outline: none;
  border-color: var(--orange);
  box-shadow: 0 0 0 3px rgba(255, 107, 0, 0.22);
}

input[readonly] {
  background: rgba(0, 42, 83, 0.05);
  color: var(--ink-70);
  cursor: not-allowed;
}

input[aria-invalid="true"] { border-color: #C0392B; }

.hint { font-size: 13px; color: var(--ink-55); margin: 6px 0 0; }

.phone-row { display: flex; gap: 8px; }
.phone-row select {
  flex: 0 0 108px;
  padding-right: 26px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' stroke='%23002A53' stroke-width='1.8' fill='none' stroke-linecap='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 10px center;
}
.phone-row input { flex: 1 1 auto; min-width: 0; }

/* Off-screen rather than hidden — some bots skip display:none inputs. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* --- consent ------------------------------------------------------------ */
.consent {
  display: flex;
  gap: 11px;
  align-items: flex-start;
  margin: 22px 0 18px;
  font-family: Inter, sans-serif;
  font-weight: 400;
  font-size: 12.5px;
  line-height: 1.5;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-70);
  cursor: pointer;
}
.consent input {
  flex: 0 0 auto;
  width: 21px;
  height: 21px;
  margin: 1px 0 0;
  accent-color: var(--orange);
  cursor: pointer;
}

/* --- buttons ------------------------------------------------------------ */
.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 54px;
  padding: 0 20px;
  font-family: Archivo, sans-serif;
  font-weight: 800;
  font-size: 15px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  color: #fff;
  background: var(--orange);
  border: 0;
  border-radius: var(--radius);
  cursor: pointer;
  transition: transform .12s ease, filter .12s ease;
}
.btn:hover:not(:disabled) { filter: brightness(1.07); }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled { opacity: .4; cursor: not-allowed; }

.btn-ghost {
  margin-top: 24px;
  color: var(--ink);
  background: transparent;
  border: 1.5px solid var(--line-strong);
}
.btn-ghost:hover { filter: none; background: rgba(0, 42, 83, 0.05); }

.linkish {
  margin-top: 7px;
  padding: 0;
  font: inherit;
  font-size: 13px;
  color: var(--orange);
  background: none;
  border: 0;
  border-radius: 4px;
  text-decoration: underline;
  cursor: pointer;
}

.fineprint {
  margin: 16px 0 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--ink-55);
  text-align: center;
}
.fineprint a, .lede a { color: inherit; }

.error {
  margin: 0 0 14px;
  padding: 11px 13px;
  font-size: 14px;
  color: #8C2A1E;
  background: rgba(192, 57, 43, 0.09);
  border-radius: 8px;
}

/* --- result states ------------------------------------------------------ */
.badge {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 62px;
  height: 62px;
  margin-bottom: 20px;
  font-size: 27px;
  color: #fff;
  background: var(--orange);
  border-radius: 50%;
}

/* --- hero --------------------------------------------------------------- */
/* No crop and no CSS fade: the photograph opens on a gradient that already
   matches the page background, so it dissolves on its own. A negative margin
   pulls it up under the copy, and .wrap is raised above it so the fine print
   stays readable over the pale top of the image. */
.hero {
  position: relative;
  /* Establishes a stacking context, which keeps the fade below sitting inside
     the hero instead of competing with .wrap (z-index 1) in the root context.
     Without this the fade wins on document order and paints over the fine
     print the hero is tucked beneath. */
  z-index: 0;
  flex: 0 0 auto;
  width: 100%;
  margin-top: -80px;
  line-height: 0;
}

/* The photo's own gradient runs cream -> cool grey over its top ~15%. Rendered
   at desktop size that is ~240px and reads as a smooth blend; rendered at phone
   width the whole image is half as tall, so the same gradient is compressed
   into half the distance and shows as a seam. This fade is measured in percent,
   so it scales with the image and lengthens the transition proportionally at
   every width. It has run to transparent well before the desktop crop line, so
   desktop is unaffected. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    to bottom,
    var(--cream) 0%,
    rgba(253, 246, 231, 0.92) 5%,
    rgba(253, 246, 231, 0.55) 12%,
    rgba(253, 246, 231, 0) 22%
  );
}
.hero img {
  display: block;
  width: 100%;
  height: auto;
}
@media (min-width: 640px) {
  /* Pulled well up so the photo fills the space the column leaves on tall
     desktop viewports rather than sitting below a long run of empty cream. */
  .hero { margin-top: -450px; }
}

/* The one thing on the success screen that must not be skimmed past: without a
   Y reply nothing happens, and the visitor has no other cue that they are not
   yet subscribed. */
.callout {
  margin: 0 0 22px;
  padding: 14px 16px;
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink);
  background: rgba(255, 199, 44, 0.30);
  border-left: 4px solid var(--orange);
  border-radius: 0 8px 8px 0;
}
