/* onboarding/public/styles.css
   Hydrophone, phone-first. Tokens are lifted verbatim from templates/hydrophone/dashboard-shell.html
   so the form and the dashboards stay one visual system.

   Two deliberate departures from the dashboard treatment, both because this is a fifteen-minute
   thinking session rather than a document to admire:
     - No WebGL hero and no scroll reveals. The depth gradient is static CSS. Nothing moves while
       the client is trying to remember something.
     - The only animation on the page is the recording waveform, which is not decoration: it is
       the one thing that answers "is this working". */
:root {
  --abyss:#061419; --depth1:#0A2833; --depth2:#0E2D38; --anchor:#0F4D5C;
  --glow:#45C2D8; --glow-bright:#8CE0F0; --ember:#E9A960; --ember-hot:#FF9068;
  --ink:#EAF5F7; --ink2:#A8C4CC; --ink3:#6F909A;
  --line:#1C4552; --glass:rgba(14,45,56,.55); --glass-line:rgba(69,194,216,.22);
  --sans:system-ui,-apple-system,'Segoe UI',sans-serif;
  --mono:ui-monospace,'Cascadia Mono',Consolas,monospace;
  --max:34rem;
  /* The built-in CSS easings are too weak to read as intentional. */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
}
/* A phone measure stretched onto a monitor reads as a phone page on a monitor. 47rem
   is about a quarter wider, and closer to the weight the client dashboards carry on the
   same screen. It runs a little past the measure a typographer would pick for body text,
   and that is the trade: this is a form someone works through, not an essay they settle
   into, and the cramped column read as unfinished. */
@media (min-width: 48rem) { :root { --max: 47rem; } }
/* Dark is the default, per the hydrophone spec. Light is honoured for anyone who has set it,
   using the shell's own light pairs so the hue stays true. There is no toggle on this page. */
@media (prefers-color-scheme: light) {
  :root {
    --abyss:#F2F7F8; --depth1:#FFFFFF; --depth2:#E6EFF1; --anchor:#0F4D5C;
    --glow:#0E6478; --glow-bright:#0A4B5A; --ember:#B87333; --ember-hot:#C24E1F;
    --ink:#122B33; --ink2:#3F5C66; --ink3:#67828C;
    --line:#D3E2E6; --glass:rgba(255,255,255,.72); --glass-line:rgba(15,77,92,.18);
  }
}

* { box-sizing: border-box; }
body {
  margin: 0; color: var(--ink); font-family: var(--sans);
  font-size: 1.0625rem; line-height: 1.6;
  background: linear-gradient(180deg,#0d3945 0%,#0a2833 45%,#061419 100%) fixed;
  -webkit-text-size-adjust: 100%;
  /* Clearance for the fixed control bar, plus the iPhone home indicator. */
  padding-bottom: calc(6rem + env(safe-area-inset-bottom));
}
@media (prefers-color-scheme: light) {
  body { background: linear-gradient(180deg,#DCEEF2 0%,#EAF4F6 55%,#F2F7F8 100%) fixed; }
}
.pad { max-width: var(--max); margin: 0 auto; padding: 2rem 1.25rem; }
/* On a desktop window a short question sits in the top eighth of the screen with a wall of
   empty gradient under it. Padding rather than vertical centring on purpose: centring cuts off
   the top of any screen taller than the viewport, and the assets and intro screens both get
   there. */
@media (min-width: 48rem) { .pad { padding-top: clamp(2rem, 9vh, 6rem); } }

h1, h2 { margin: 0 0 1rem; text-wrap: balance; }
/* One face on the whole form. Fraunces was kept here after the questions moved to the sans,
   on the reasoning that the intro greeting and the payoff are display work; on the device that
   left a serif headline sitting above a sans page and reading as a different document. The
   hydrophone serif still belongs on the dashboards, which ARE documents. This is a form. */
h1 {
  font-family: var(--sans); font-weight: 650;
  font-size: clamp(1.75rem, 7vw, 2.5rem); letter-spacing: -0.025em; line-height: 1.15;
}
/* The question is not display work. It is text somebody has to read on a phone, hold in their
   head, and answer out loud, and Fraunces lost that job on the device: tuning the size and
   tracking helped and still left it effortful. The system sans is SF on iOS and Segoe on
   Windows -- faces drawn for exactly this, hinted for these sizes, and already resident. A
   heavier weight and slightly tight tracking keep it reading as a headline rather than body. */
h2 {
  font-family: var(--sans); font-weight: 650;
  font-size: clamp(1.6rem, 6.5vw, 2.1rem);
  letter-spacing: -0.02em; line-height: 1.25;
}
p { margin: 0 0 1rem; }
.muted { color: var(--ink2); }
.small { font-size: 0.875rem; }
ul { padding-left: 1.2rem; }
li { margin-bottom: 0.4rem; }
strong { font-weight: 600; }
a { color: var(--glow); text-decoration: underline; text-underline-offset: 0.15em; }
a:hover { color: var(--glow-bright); }
:focus-visible { outline: 2px solid var(--glow); outline-offset: 2px; border-radius: 4px; }

/* ---------- progress ---------- */
/* Eight segments rather than the words "question 3 of 8": it shows position and remaining
   distance in less vertical space than the line of text it replaces. */
#steps {
  position: sticky; top: 0; z-index: 10;
  background: color-mix(in srgb, var(--abyss) 82%, transparent);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}
.steps-inner {
  max-width: var(--max); margin: 0 auto; padding: 0.75rem 1.25rem;
  display: flex; align-items: center; gap: 0.75rem;
}
.track { flex: 1; display: flex; gap: 0.25rem; }
.seg {
  flex: 1; height: 3px; border-radius: 2px; background: var(--line);
  /* Colour, not width. A width or transform animation on eight segments runs layout or
     compositing work on every step for a state the fill colour already carries. Colour change
     also survives prefers-reduced-motion, because it aids comprehension without moving
     anything. */
  transition: background-color 260ms var(--ease-out);
}
.seg.done { background: var(--glow); }
.count {
  font-family: var(--mono); font-size: 0.75rem; font-variant-numeric: tabular-nums;
  color: var(--ink3); flex: none;
}
.warn { background: var(--depth2); border-bottom: 1px solid var(--line); padding: 1rem 1.25rem; }

textarea, input[type="text"] {
  width: 100%; padding: 0.75rem; font: inherit; color: var(--ink);
  background: var(--depth1); border: 1px solid var(--line); border-radius: 0.5rem;
}
textarea { min-height: 9rem; resize: vertical; }
input[type="text"] { margin-bottom: 1rem; }
textarea::placeholder { color: var(--ink3); }
input[type="file"] { color: var(--ink2); font-size: 0.9rem; max-width: 100%; }

button {
  font: inherit; padding: 0.7rem 1.1rem; border-radius: 0.5rem;
  border: 1px solid var(--line); background: var(--depth1); color: var(--ink);
  cursor: pointer; min-height: 2.75rem;
}
button:hover { border-color: var(--glow); }
/* Instant acknowledgement of a tap. Without it nothing on this page responds until the network
   does, which on a phone is long enough to invite a second press. */
button { transition: transform 160ms var(--ease-out), background-color 160ms ease, border-color 160ms ease; }
button:active { transform: scale(0.97); }
@media (prefers-reduced-motion: reduce) { button { transition: none; } button:active { transform: none; } }
button.primary { background: var(--glow); color: var(--abyss); border-color: var(--glow); font-weight: 600; }
button.primary:hover { background: var(--glow-bright); border-color: var(--glow-bright); }
button:disabled { opacity: 0.45; cursor: default; }
button:disabled:hover { border-color: var(--line); }

/* ---------- the control bar ---------- */
/* Fixed, not in the flow. A long question with a hint, a recorder and a confirmation card was
   pushing Next below the fold, which hides the only way forward at the moment someone has just
   finished answering. */
#bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
  background: color-mix(in srgb, var(--abyss) 88%, transparent);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border-top: 1px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom);
}
.bar-msg {
  max-width: var(--max); margin: 0 auto; padding: 0.6rem 1.25rem 0;
  font-size: 0.875rem; color: var(--ember);
}
.bar-msg[hidden] { display: none; }
/* Dimmed, not disabled: the button still has to be able to fire the click that explains why
   it is dimmed. */
.primary.is-blocked { opacity: 0.45; }
.nav {
  max-width: var(--max); margin: 0 auto; padding: 0.75rem 1.25rem;
  display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
}
/* Both the skip and the type-instead control are deliberately quiet. They have to be findable
   without competing with the thing we actually want the client to do. Block, not the browser
   default inline-block: two of these sit on one screen and side by side they ran together into
   a single underlined smear that read as one nonsense sentence. */
.quiet {
  display: block; width: fit-content;
  background: none; border: none; color: var(--ink2); text-decoration: underline;
  text-underline-offset: 0.15em; padding: 0.5rem 0; min-height: 2.75rem; font-size: 0.9375rem;
}
.quiet:hover { color: var(--glow); border-color: transparent; }
/* The escape hatch belongs with the control it escapes from. */
.mode-link { margin-top: 0.25rem; }

/* The microphone picker. Only ever rendered when the browser names more than one input, which
   means desktop in practice -- iOS reports a single device and routes in the system. */
.mic-row { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.75rem; }
.mic-row[hidden] { display: none; }
.mic-label {
  font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ink3); flex: none;
}
.mic-select {
  flex: 1; min-width: 0; font: inherit; font-size: 0.875rem; color: var(--ink);
  background: var(--depth1); border: 1px solid var(--line); border-radius: 0.4rem;
  padding: 0.4rem 0.5rem;
}
.mic-select:hover { border-color: var(--glow); }

/* ---------- recording ---------- */
/* The record control is the screen, not one of two equal options: the spec's whole premise is
   that talking produces better answers than typing, and two matched buttons put the habit
   (typing) on level terms with the thing that works. */
.rec-start {
  display: flex; align-items: center; justify-content: center; gap: 0.6rem;
  width: 100%; padding: 1.1rem; font-size: 1.0625rem; font-weight: 600;
  background: var(--glow); color: var(--abyss); border-color: var(--glow);
}
.rec-start:hover { background: var(--glow-bright); border-color: var(--glow-bright); }
.rec-start.is-recording { background: var(--depth1); color: var(--ink); border-color: var(--ember); }
.rec-start.is-recording:hover { background: var(--depth2); border-color: var(--ember-hot); }
/* After a take we actually heard, the client's next move is Next. Leaving this control at full
   primary weight puts two competing bright buttons on the screen and makes re-recording look
   like the expected action. It stays prominent after a silent or failed take, where recording
   again IS the expected action. */
.rec-start.is-done {
  background: var(--depth1); color: var(--ink); border-color: var(--line); font-weight: 400;
}
.rec-start.is-done:hover { background: var(--depth2); border-color: var(--glow); }
.rec-start.is-done .rec-dot { background: var(--ink3); }
.rec-dot { width: 0.7rem; height: 0.7rem; border-radius: 50%; background: var(--abyss); flex: none; }
.rec-start.is-recording .rec-dot { background: var(--ember-hot); }
@media (prefers-reduced-motion: no-preference) {
  .rec-start.is-recording .rec-dot { animation: pulse 1.4s ease-in-out infinite; }
  @keyframes pulse { 50% { opacity: 0.3; } }
}

/* Ember, not teal, and that is the semantic rule rather than a colour preference: the waveform
   IS the human voice, which is the one thing the hydrophone palette reserves warm for. */
.wave-wrap {
  display: none; align-items: center; gap: 0.75rem; margin-top: 1rem;
  padding: 0.75rem; background: var(--depth1); border: 1px solid var(--line); border-radius: 0.5rem;
}
.wave-wrap.on { display: flex; }
#wave { flex: 1; width: 100%; height: 3rem; display: block; }
.timer {
  font-family: var(--mono); font-size: 0.95rem; font-variant-numeric: tabular-nums;
  color: var(--ember); flex: none;
}

/* The confirmation state. It says what was captured and how long it is, because "Saved" alone
   is exactly the kind of claim this project keeps catching out. Re-recording stays one tap
   away: stopping is not a commitment. */
.saved {
  margin-top: 1rem; padding: 0.9rem 1rem;
  background: var(--depth1); border: 1px solid var(--line);
  border-left: 3px solid var(--ember); border-radius: 0.5rem;
}
.saved .headline { font-weight: 600; margin: 0 0 0.3rem; }
.saved .meta {
  font-family: var(--mono); font-size: 0.8rem; letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums; color: var(--ember); margin: 0 0 0.3rem;
}
.saved .note { font-size: 0.9375rem; color: var(--ink2); margin: 0; }
.saved.is-error { border-left-color: var(--ember-hot); }

.status { font-size: 0.875rem; color: var(--ink2); margin: 0.75rem 0 0; min-height: 1.4rem; }
/* The reserved line stops the panel jumping when "Starting." and "Saving." appear. Once a take
   is finished the status is empty and the confirmation card sits below it, so holding the space
   open there just opens a hole between the button and the card. Collapsing it only in the empty
   case introduces no shift, because nothing else is on screen when the status has text. */
.status:empty { min-height: 0; margin: 0; }

/* What a previously-answered question shows when the client navigates back to it. Without this
   the box is simply empty and their work looks lost. */
.prior {
  margin-bottom: 1rem; padding: 0.9rem 1rem;
  background: var(--depth1); border: 1px solid var(--line);
  border-left: 3px solid var(--ember); border-radius: 0.5rem;
}
.prior .label {
  font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--ink3); display: block; margin-bottom: 0.4rem;
}
.prior p { margin: 0; }

label.field { display: block; margin-bottom: 0.35rem; }
video { width: 100%; border-radius: 0.5rem; margin: 1rem 0; }

/* The booking calendar. A third-party widget with its own light theme, so it gets a white
   ground rather than flashing dark then repainting. min-height is what keeps it usable if
   GoHighLevel's resize script never loads. */
.booking {
  width: 100%; min-height: 44rem; border: 1px solid var(--line);
  border-radius: 0.5rem; background: #fff; display: block; margin: 0 0 1rem;
}
