:root {
  /*
      One blue family, anchored on the logo's hue (H 206). Before this the
      wordmark sat at 206, the toggle at 209 and the waveform at 211-213 —
      close enough to look like a mistake rather than a choice.
  */
  --blue-deep: #004a82;
  --blue-dark: #1e75b8;
  --blue: #2785ce;
  --blue-soft: #6cabda;
  --blue-light: #79acd5;
  --blue-muted: #8ea3b4;

  /*
      Everything below has a dark value in talk-theme.css, which only the
      talk pages load, so the prototypes that share this file stay light.
      The names match front.css and the legal pages where the job is the
      same. Add a token here and it must get a dark value there too;
      test/pages.test.js fails if it doesn't.
  */
  --page-1: #ffffff;
  --page-2: #eef3f9;
  --page-3: #dbe4ef;
  --page-4: #c6d2e1;

  --ground: #f4f7fb;
  --surface: #ffffff;
  --card: rgba(255, 255, 255, 0.8);
  --card-line: rgba(255, 255, 255, 0.95);
  --raised: rgba(255, 255, 255, 0.9);
  --raised-hover: #ffffff;
  --field: rgba(255, 255, 255, 0.9);
  --tint: #f2f7fc;
  --icon-ground: #e3eef9;
  --ring-ground: #f7fbff;

  --line: #e1e7ef;
  --hairline: rgba(90, 125, 175, 0.3);
  --control-line: #71889e;
  --button-line: rgba(39, 133, 206, 0.45);

  --ink: #1b2a3d;
  --heading: #0f2340;
  --ink-2: #41586d;
  --placeholder: #757575;
  --link: #004a82;
  --accent: #1e75b8;
  --focus: #004a82;
  --error: #a2382f;

  --good-ink: #1c6b3a;
  --good-ground: #e6f4ea;
  --good-line: #a9d3b6;

  --logo-1: var(--blue-deep);
  --logo-2: var(--blue-light);
  --logo-gap: #ffffff;

  --card-shadow: 0 18px 40px rgba(64, 87, 120, 0.18);
  --step-shadow: 0 10px 30px rgba(43, 74, 112, 0.12);
  --hint-shadow: 0 8px 22px rgba(15, 35, 64, 0.25);
  --wave-shadow: 0 1px 3px rgba(48, 78, 120, 0.35);

  /* The talk button: a metal rim, a dome, a lit ring and the microphone. */
  --talk-rim: linear-gradient(
    145deg,
    #ffffff 0%,
    #e6edf5 12%,
    #bcc9d8 28%,
    #93a4b8 65%,
    #d3dde9 88%,
    #ffffff 100%
  );
  --talk-shadow:
    0 25px 45px rgba(64, 87, 120, 0.35),
    inset 0 2px 3px rgba(255, 255, 255, 0.95),
    inset 0 -5px 8px rgba(83, 105, 137, 0.45);
  --talk-shadow-pressed:
    0 10px 20px rgba(64, 87, 120, 0.4),
    inset 0 5px 10px rgba(83, 105, 137, 0.5);
  --talk-dome:
    radial-gradient(circle, rgba(40, 70, 110, 0.1) 0.7px, transparent 1.5px) 0 0 /
      7px 7px,
    radial-gradient(circle, rgba(40, 70, 110, 0.06) 0.4px, transparent 1.1px)
      3.5px 3.5px / 7px 7px,
    radial-gradient(circle, #ffffff 0%, #eaf1f9 65%, #d2dded 100%);
  --talk-dome-glow:
    0 0 12px rgba(0, 122, 224, 0.3),
    0 0 25px rgba(0, 122, 224, 0.18),
    inset 0 2px 10px rgba(83, 105, 137, 0.3);
  --talk-ring: #2d9bff;
  --talk-ring-glow:
    0 0 6px rgba(45, 155, 255, 0.55),
    0 0 15px rgba(45, 155, 255, 0.35),
    0 0 30px rgba(0, 140, 255, 0.2);
  --talk-ring-on: #0b6fd8;
  --talk-ring-on-glow:
    0 0 10px rgba(45, 155, 255, 0.8),
    0 0 25px rgba(0, 140, 255, 0.55),
    0 0 50px rgba(0, 140, 255, 0.35),
    0 0 90px rgba(0, 140, 255, 0.2);
  --mic-edge: #1f6fc4;
  --mic-core: #3f9be8;
  --mic-frame: var(--blue);
  --mic-shadow: drop-shadow(0 2px 3px rgba(40, 70, 110, 0.35));

  /* The clinic page's on/off switch. */
  --switch-body: linear-gradient(180deg, #888, #fff);
}

* {
  box-sizing: border-box;
}

html {
  height: 100%;
}

body {
  margin: 0;

  /*
      An app shell, not a document. The page itself never scrolls, so the
      phone has nothing to rubber-band against. Anything that outgrows the
      viewport scrolls inside .app instead.

      `dvh` tracks the visible area as mobile browser chrome slides away.
      `vh` does not — it counts the area behind the chrome too, which is
      exactly what let the page drift up and down on load.
  */
  height: 100vh;
  height: 100dvh;

  display: flex;

  background: radial-gradient(
    circle at center,
    var(--page-1) 0%,
    var(--page-2) 35%,
    var(--page-3) 75%,
    var(--page-4) 100%
  );
  background-attachment: fixed;

  color: var(--ink);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  overflow: hidden;
  overscroll-behavior: none;
}

.app {
  /*
      Full width, so its scroll bar sits at the window's right edge rather
      than beside a centred 500px column. The side padding keeps the
      content to that same 460px column (500px less 20px each side).
  */
  width: 100%;
  max-height: 100%;

  /* Auto margins centre it while short, without clipping once it is tall. */
  margin: auto;

  padding: 40px max(20px, calc((100% - 460px) / 2));
  padding-top: max(40px, env(safe-area-inset-top));
  padding-bottom: max(40px, env(safe-area-inset-bottom));

  display: flex;
  flex-direction: column;
  align-items: center;

  /* The one scroll container, so the letter stays reachable. */
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;

  text-align: center;
}

/* --------------------------------
   TEXT
-------------------------------- */

.wordmark {
  width: 100%;
  max-width: 420px;

  margin: 0 0 10px;
}

.wordmark-lockup {
  display: block;
  width: 100%;
  height: auto;
}

.wordmark-cross {
  fill: var(--logo-1);
}

/* The gap between cross and check — it has to match the page behind it. */
.wordmark-sep {
  fill: var(--logo-gap);
}

.wordmark-check {
  fill: var(--logo-2);
}

.wordmark-appeal {
  fill: var(--logo-1);
}

.wordmark-buddy {
  fill: var(--logo-2);
}

.subtitle {
  font-size: clamp(18px, 4vw, 28px);
  color: var(--ink-2);

  margin-bottom: clamp(26px, 7vh, 55px);
}

/* --------------------------------
   BUTTON
-------------------------------- */

.talk-button {
  position: relative;

  width: min(70vw, 330px);
  aspect-ratio: 1;

  border: none;
  border-radius: 50%;

  cursor: pointer;

  padding: 0;

  touch-action: none;
  -webkit-tap-highlight-color: transparent;

  /* Outer brushed-silver body */
  background: var(--talk-rim);

  box-shadow: var(--talk-shadow);

  transition:
    transform 0.12s ease,
    box-shadow 0.12s ease;
}

/* Recessed inner face */
.talk-button::before {
  content: "";

  position: absolute;

  inset: 9%;

  border-radius: 50%;

  /* Alternating dot lattice, faint, over the dome */
  background: var(--talk-dome);

  box-shadow: var(--talk-dome-glow);

  z-index: 1;
}

/* Blue ring */
.talk-button::after {
  content: "";

  position: absolute;

  inset: 11%;

  border-radius: 50%;

  border: 5px solid var(--talk-ring);

  box-shadow: var(--talk-ring-glow);

  z-index: 2;

  transition:
    box-shadow 0.15s ease,
    border-color 0.15s ease;
}

/* --------------------------------
   MICROPHONE
-------------------------------- */

.microphone {
  position: absolute;

  z-index: 5;

  left: 50%;
  top: 50%;

  transform: translate(-50%, -50%);

  width: 32%;
  height: auto;

  pointer-events: none;

  filter: var(--mic-shadow);
}

.microphone .shine-edge {
  stop-color: var(--mic-edge);
}

.microphone .shine-core {
  stop-color: var(--mic-core);
}

.microphone .capsule {
  fill: url(#micShine);
}

.microphone .frame {
  fill: none;

  stroke: var(--mic-frame);
  stroke-width: 6;
  stroke-linecap: round;
}

/* --------------------------------
   PRESSED STATE
-------------------------------- */

.talk-button:active,
.talk-button.is-recording {
  transform: translateY(7px) scale(0.97);

  box-shadow: var(--talk-shadow-pressed);
}

.talk-button.is-recording::after {
  border-color: var(--talk-ring-on);

  box-shadow: var(--talk-ring-on-glow);
}

/* --------------------------------
   WAVEFORM
-------------------------------- */

.waveform {
  display: flex;

  align-items: center;
  justify-content: center;

  gap: 7px;

  height: 70px;

  margin-top: 55px;
}

.waveform span {
  width: 5px;

  height: 18px;

  border-radius: 10px;

  background: linear-gradient(to bottom, var(--blue-soft), var(--blue-dark));

  box-shadow: var(--wave-shadow);

  transition: height 0.15s ease;
}

.waveform span:nth-child(1),
.waveform span:nth-child(9) {
  height: 15px;
}

.waveform span:nth-child(2),
.waveform span:nth-child(8) {
  height: 25px;
}

.waveform span:nth-child(3),
.waveform span:nth-child(7) {
  height: 38px;
}

.waveform span:nth-child(4),
.waveform span:nth-child(6) {
  height: 50px;
}

.waveform span:nth-child(5) {
  height: 65px;
}

/* Animate waveform while recording */

.is-recording + .waveform span {
  animation: waveform 0.45s ease-in-out infinite alternate;
}

.is-recording + .waveform span:nth-child(2),
.is-recording + .waveform span:nth-child(8) {
  animation-delay: 0.1s;
}

.is-recording + .waveform span:nth-child(3),
.is-recording + .waveform span:nth-child(7) {
  animation-delay: 0.2s;
}

.is-recording + .waveform span:nth-child(4),
.is-recording + .waveform span:nth-child(6) {
  animation-delay: 0.3s;
}

@keyframes waveform {
  from {
    transform: scaleY(0.4);
  }

  to {
    transform: scaleY(1.25);
  }
}

/* --------------------------------
   MOBILE
-------------------------------- */

@media (max-width: 600px) {
  .subtitle {
    margin-bottom: 40px;
  }

  .waveform {
    margin-top: 40px;
  }

  /*
      Phone controls go in the lower half. The switch is much shorter
      than the old hold button, so on its own it floats into the top
      half. The line above it takes the room instead, with its words at
      the bottom so they sit right over the switch: the switch's top then
      lands just under the middle of the screen. 140px is the space above
      this line (padding, wordmark and gaps). Only where the switch sits
      straight in the page column (talk.html, not the clinic page).
  */
  .app > .subtitle:has(+ .toggle) {
    min-height: calc(50dvh - 140px);

    display: flex;
    flex-direction: column;
    justify-content: flex-end;
  }
}

/* --------------------------------
   APPEAL
-------------------------------- */

.appeal {
  width: 100%;

  margin-top: 45px;
  padding: 24px;

  border: 1px solid var(--hairline);
  border-radius: 16px;

  background: var(--card);

  box-shadow: var(--card-shadow);

  text-align: left;
}

.appeal-heading {
  margin: 0 0 18px;

  font-size: 15px;
  font-weight: 600;
  letter-spacing: 1.5px;
  text-transform: uppercase;

  color: var(--link);
}

.appeal-fields {
  margin: 0;

  display: grid;
  grid-template-columns: auto 1fr;
  gap: 8px 16px;
}

.appeal-fields dt {
  font-size: 13px;
  color: var(--ink-2);

  white-space: nowrap;
}

.appeal-fields dd {
  margin: 0;

  font-size: 15px;
  color: var(--ink);
}

.appeal-letter {
  margin-top: 22px;
  padding-top: 22px;

  border-top: 1px solid var(--hairline);
}

.appeal-letter-bar {
  margin-bottom: 12px;

  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.appeal-letter-heading {
  margin: 0;

  font-size: 13px;
  font-weight: 600;
  letter-spacing: 1.2px;
  text-transform: uppercase;

  color: var(--link);
}

.appeal-toggle {
  padding: 4px 8px;

  border: 0;
  border-radius: 6px;

  background: none;

  color: var(--ink-2);
  font-family: inherit;
  font-size: 13px;

  cursor: pointer;

  transition: color 0.15s ease;
}

.appeal-toggle:hover {
  color: var(--ink);
}

/* A textarea, so the letter can be selected and copied without the button. */
.appeal-argument {
  display: block;
  width: 100%;
  min-height: 140px;

  box-sizing: border-box;
  padding: 14px 16px;

  border: 1px solid var(--hairline);
  border-radius: 10px;

  background: var(--field);

  color: var(--ink);
  font-family: inherit;
  font-size: 15px;
  line-height: 1.65;

  resize: vertical;
}

.appeal-letter .appeal-action {
  width: 100%;
  margin-top: 12px;
}

.appeal-actions {
  margin-top: 24px;

  display: flex;
  gap: 10px;
}

.appeal-action {
  flex: 1;

  padding: 11px 14px;

  border: 1px solid var(--hairline);
  border-radius: 9px;

  background: var(--raised);

  color: var(--ink);
  font-family: inherit;
  font-size: 14px;

  cursor: pointer;

  transition:
    background 0.15s ease,
    border-color 0.15s ease;
}

.appeal-action:hover {
  border-color: rgba(45, 155, 255, 0.6);

  background: var(--raised-hover);
}
