/* request.thedetectivedave.com: one form on the main site's central axis.
   Same room, same type, same keys as thedetectivedave.com (site.css);
   tokens.css is a copy of the main site's generated tokens. */

@import url('tokens.css');

@font-face {
  font-family: 'Akira Expanded';
  src: url('/fonts/akira-expanded.woff2') format('woff2');
  font-weight: 800;
  font-style: normal;
  font-display: swap;
}

/* ------------------------------------------------------------------ base */

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

:root {
  color-scheme: dark;
  /* page top: the top bar's offset + height, then the gap to the heading */
  --page-top: var(--dd-space-16);
  /* errors only: 6.4:1 on navy */
  --dd-error: #ff5a5f;
  --dd-error-a14: rgba(255, 90, 95, 0.14);
  --dd-error-a45: rgba(255, 90, 95, 0.45);
  --above: calc(var(--dd-space-3) + var(--dd-nav-h) + var(--page-top));
  /* the form column */
  --col: 35rem;
  /* field height = key height, the spec's 56px */
  --field-h: var(--dd-key-h);
}

html {
  font-size: 100%;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  background: var(--dd-navy);
  overflow-x: clip;
}

/* above 1920 CSS px the root grows and the page scales as one */
@media (min-width: 1921px) {
  html {
    font-size: min(calc(100vw / 120), 2rem);
  }
}

body {
  /* flow-root: the top bar's margin stays inside the body's 100svh */
  display: flow-root;
  margin: 0;
  min-height: 100svh;
  background: transparent;
  color: var(--dd-fg);
  font-family: var(--dd-font-sans);
  font-size: var(--dd-size-body);
  font-weight: 400;
  line-height: 1.6;
  letter-spacing: var(--dd-track-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: clip;
}

svg {
  display: block;
}

p,
h1 {
  margin: 0;
}

a {
  color: inherit;
}

::selection {
  background: var(--dd-select-bg);
  color: var(--dd-select-fg);
}

:focus-visible {
  outline: 0.1875rem solid var(--dd-focus);
  outline-offset: 0.1875rem;
  border-radius: var(--dd-radius-sm);
}

[hidden] {
  display: none !important;
}

[data-theme='navy'] {
  color: var(--dd-fg);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ----------------------------------------------------------------- world */

/* the courtroom, held still and dimmed for reading */
.world {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  background: var(--dd-navy);
  pointer-events: none;
}

.world__plate {
  position: absolute;
  inset: -4%;
  background:
    image-set(url('/assets/world/court.avif') type('image/avif'), url('/assets/world/court.webp') type('image/webp'), url('/assets/world/court.jpg') type('image/jpeg'))
    center 38% / cover no-repeat,
    var(--dd-navy);
}

.world__light {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(60% 45% at 50% 44%, var(--dd-white-a08), transparent 70%),
    linear-gradient(to bottom, var(--dd-navy-a60) 0, transparent 24%, transparent 60%, var(--dd-navy-a86) 100%),
    radial-gradient(120% 90% at 50% 45%, transparent 55%, var(--dd-navy-a60) 100%);
}

.world__dim {
  position: absolute;
  inset: 0;
  background: var(--dd-navy);
  opacity: 0.6;
}

/* -------------------------------------------------------------- the link */

.text-link {
  display: inline-flex;
  align-items: center;
  gap: var(--dd-space-2);
  border-radius: var(--dd-radius-sm);
  font-weight: 600;
  text-decoration: none;
}

/* only the words are underlined, not the arrow */
.text-link__words {
  text-decoration: underline;
  text-decoration-thickness: var(--dd-stroke-ink);
  text-underline-offset: 0.3125rem;
}

/* ------------------------------------------------------------------ keys */

/* the main site's key: 2px rim, the hard lip under it, sinks when pressed */
.key {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--dd-space-3);
  min-height: var(--dd-key-h);
  padding: var(--dd-space-2) var(--dd-space-6);
  border: var(--dd-stroke-ink) solid var(--dd-white);
  border-radius: var(--dd-radius-md);
  font: inherit;
  font-size: var(--dd-size-body);
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  box-shadow: var(--dd-shadow-lip);
  transition:
    translate var(--dd-dur-press) var(--dd-ease-out),
    box-shadow var(--dd-dur-press) var(--dd-ease-out),
    opacity var(--dd-dur-fast) var(--dd-ease-out);
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  user-select: none;
}

.key--light {
  background: var(--dd-white);
  color: var(--dd-navy);
}

.key--wide {
  width: 100%;
}

@media (hover: hover) and (pointer: fine) {
  .key:hover {
    translate: 0 var(--dd-lift);
    box-shadow: var(--dd-shadow-lip-hover);
  }
}

.key:active {
  translate: 0 0.25rem;
  box-shadow: var(--dd-shadow-lip-down);
}

.key:focus-visible {
  outline-offset: var(--dd-space-1);
  border-radius: var(--dd-radius-md);
}

/* sending: held down in its lip, not clickable twice */
.key[aria-disabled='true'],
.key[aria-disabled='true']:hover {
  translate: 0 0.25rem;
  box-shadow: var(--dd-shadow-lip-down);
  cursor: progress;
}

/* ------------------------------------------------------------------- top */

/* The main site's nav box, minus the bar: same container (--dd-max), same
   top offset and height, the fedora on the exact spot the nav's fedora
   sits. Fedora and the way back are one link, so there is one action. */
.top {
  --pad: var(--dd-space-2);
  display: flex;
  align-items: center;
  width: min(var(--dd-max), calc(100% - var(--dd-gutter) * 2));
  min-height: var(--dd-nav-h);
  margin: calc(var(--dd-space-3) + env(safe-area-inset-top)) auto 0;
  /* the nav's 1px hairline + its inner padding */
  padding-left: calc(1px + var(--pad) + var(--dd-space-3));
}

.top__back {
  gap: var(--dd-space-4);
  min-height: 2.75rem;
  font-size: var(--dd-size-small);
  color: var(--dd-white-a86);
  transition: color var(--dd-dur-fast) var(--dd-ease-hover);
}

.top__words {
  display: inline-flex;
  align-items: center;
  gap: var(--dd-space-2);
}

.top__mark {
  flex: none;
  width: auto;
  height: var(--dd-nav-mark);
  aspect-ratio: 247 / 143;
  color: var(--dd-white);
}

@media (hover: hover) and (pointer: fine) {
  .top__back:hover {
    color: var(--dd-white);
  }
}

/* ------------------------------------------------------------------ page */

.page {
  width: 100%;
  max-width: calc(var(--col) + var(--dd-gutter) * 2);
  margin-inline: auto;
  padding: var(--page-top) max(var(--dd-gutter), env(safe-area-inset-right)) calc(var(--dd-space-24) + env(safe-area-inset-bottom)) max(var(--dd-gutter), env(safe-area-inset-left));
}

.view {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

/* A small version of the main hero's signature: Dave, chest up, standing
   on the white bar with its lip. The crop is cut to the body's own width
   at its bottom edge, so the bar spans the jacket exactly, 4px past it on
   both sides, and hides the image's bottom 5px. He rises out from behind
   the bar, never below it. */
.dave {
  --dave-h: 12.5rem;
  --bar-h: 0.5625rem;
  position: relative;
  height: var(--dave-h);
  aspect-ratio: 701 / 600;
  /* 24px from the bar's bottom edge to the heading */
  margin-bottom: calc(var(--dd-space-6) + var(--bar-h) - 0.3125rem);
}

.dave picture {
  display: block;
  height: 100%;
  clip-path: inset(-50% -50% 0.3125rem -50%);
}

.dave img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: 50% 100%;
}

.dave__bar {
  position: absolute;
  left: -0.25rem;
  right: -0.25rem;
  bottom: calc(var(--bar-h) * -1 + 0.3125rem);
  height: var(--bar-h);
  border-radius: calc(var(--bar-h) * 0.3);
  background: var(--dd-white);
  box-shadow: var(--dd-shadow-lip);
}

.head-title {
  max-width: 22em;
  margin-bottom: var(--dd-space-5);
  font-family: var(--dd-font-display);
  font-size: var(--dd-size-display);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: 0;
  word-spacing: -0.15em;
  text-wrap: balance;
}

.head-title:focus {
  outline: none;
}

.lede {
  max-width: 100%;
  font-size: var(--dd-size-large);
  line-height: 1.45;
  color: var(--dd-fg-2);
  text-wrap: balance;
}

/* The thank-you sits on the viewport's centre: it gets the whole screen
   below the top bar, with the same space held below it as above it. */
.view--sent {
  justify-content: center;
  min-height: calc(100svh - var(--above) * 2);
}

.page:has(.view--sent:not([hidden])) {
  padding-bottom: var(--above);
}

.view--sent .key {
  margin-top: var(--dd-head-gap);
}

/* ------------------------------------------------------------------ form */

.form {
  display: grid;
  gap: var(--dd-space-8);
  width: 100%;
  margin-top: var(--dd-head-gap);
  text-align: left;
}

.field {
  display: grid;
}

.field__label {
  font-weight: 600;
  line-height: 1.35;
  color: var(--dd-white);
}

.field__hint {
  margin-top: var(--dd-space-1);
  font-size: var(--dd-size-small);
  line-height: 1.45;
  color: var(--dd-fg-3);
}

/* Solid white fields, navy ink: the one thing on the page you type into.
   Flat, no stroke, the key's radius. */
.field__input {
  width: 100%;
  min-height: var(--field-h);
  margin-top: var(--dd-space-3);
  padding: 0 var(--dd-space-4);
  border: 0;
  border-radius: var(--dd-radius-md);
  background: var(--dd-white);
  color: var(--dd-navy);
  font: inherit;
  font-size: var(--dd-size-body);
  line-height: 1.4;
  caret-color: var(--dd-navy);
  outline: 0.1875rem solid transparent;
  outline-offset: 0.125rem;
  transition: outline-color var(--dd-dur-fast) var(--dd-ease-out);
  -webkit-appearance: none;
  appearance: none;
}

.field__input--area {
  min-height: 9rem;
  padding-block: 0.875rem;
  resize: vertical;
}

.field__input:focus,
.field__input:focus-visible {
  outline-color: var(--dd-doodle);
}

/* error: a red ring outside the field, kept while it has focus */
.field__input[aria-invalid='true'],
.field__input[aria-invalid='true']:focus {
  outline-color: var(--dd-error);
}

/* keep autofill white: no yellow or blue fill from the browser */
.field__input:-webkit-autofill,
.field__input:-webkit-autofill:hover,
.field__input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--dd-navy);
  box-shadow: inset 0 0 0 100vmax var(--dd-white);
  caret-color: var(--dd-navy);
}

.field__error {
  display: flex;
  align-items: flex-start;
  gap: 0.625rem;
  margin-top: var(--dd-space-2);
  padding: 0.625rem 0.875rem;
  border: 1px solid var(--dd-error-a45);
  /* concentric with the field: its radius minus 4px */
  border-radius: calc(var(--dd-radius-md) - 0.25rem);
  background: var(--dd-error-a14);
  font-size: var(--dd-size-small);
  font-weight: 600;
  line-height: 1.4;
  color: var(--dd-white);
}

.field__error svg {
  width: 1.25rem;
  height: 1.25rem;
  flex: none;
  /* centred on the first line: (17 x 1.4 - 20) / 2 */
  margin-top: 0.12rem;
}

.form__end {
  display: grid;
  gap: var(--dd-space-4);
  margin-top: var(--dd-space-2);
  /* room for the key's lip */
  padding-bottom: 0.3125rem;
}

.form__error {
  margin-top: 0;
}

/* the honeypot: off screen, out of the tab order, out of the a11y tree */
.trap {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ---------------------------------------------------------------- motion */

@media (prefers-reduced-motion: no-preference) {
  /* entrance: fade up out of a light blur, one after another */
  .js [data-enter] {
    animation: enter var(--dd-dur-enter) cubic-bezier(0.23, 1, 0.32, 1) both;
    animation-delay: calc(var(--i, 0) * var(--dd-stagger-enter));
  }

  /* Dave comes up first, then the heading's stagger */
  .js .dave img {
    animation: dave-in var(--dd-dur-enter) cubic-bezier(0.23, 1, 0.32, 1) both;
  }

  .js .dave__bar {
    animation: fade var(--dd-dur-enter) cubic-bezier(0.23, 1, 0.32, 1) both;
  }

  .top {
    animation: fade var(--dd-dur-enter) cubic-bezier(0.23, 1, 0.32, 1) both;
  }

  /* an error arrives with a small rise */
  .field__error:not([hidden]) {
    animation: rise 180ms cubic-bezier(0.23, 1, 0.32, 1) both;
  }

  /* on submit only: the field shakes its head, once */
  .field__input.is-shaking {
    animation: shake 300ms cubic-bezier(0.23, 1, 0.32, 1);
  }

  /* the thank-you comes in the same way the page did */
  .view.is-entering > * {
    animation: enter var(--dd-dur-reveal) cubic-bezier(0.23, 1, 0.32, 1) both;
  }

  .view.is-entering > :nth-child(2) {
    animation-delay: 60ms;
  }

  .view.is-entering > :nth-child(3) {
    animation-delay: 120ms;
  }

  /* leaving is quicker than arriving */
  .view.is-leaving {
    animation: leave var(--dd-dur-exit) cubic-bezier(0.23, 1, 0.32, 1) both;
  }
}

@keyframes enter {
  from {
    opacity: 0;
    translate: 0 14px;
    filter: blur(6px);
  }
}

@keyframes dave-in {
  from {
    opacity: 0;
    translate: 0 12px;
  }
}

@keyframes fade {
  from {
    opacity: 0;
  }
}

@keyframes rise {
  from {
    opacity: 0;
    translate: 0 4px;
  }
}

@keyframes shake {
  16%,
  50%,
  83% {
    translate: -4px 0;
  }
  33%,
  66% {
    translate: 4px 0;
  }
}

@keyframes leave {
  to {
    opacity: 0;
    translate: 0 -8px;
  }
}

/* ------------------------------------------------------------ preferences */

@media (prefers-reduced-motion: reduce) {
  .key {
    transition: none;
  }
}

@media (prefers-contrast: more) {
  [data-theme='navy'] {
    --dd-fg-2: var(--dd-white);
    --dd-fg-3: var(--dd-white);
  }
  .world__plate {
    opacity: 0.4;
  }
}

@media (forced-colors: active) {
  .key,
  .field__input {
    border: var(--dd-stroke-ink) solid CanvasText;
  }
  .world {
    display: none;
  }
}

/* ------------------------------------------------------------ responsive */

@media (max-width: 640px) {
  :root {
    --page-top: var(--dd-space-10);
  }
  .dave {
    --dave-h: 9.375rem;
  }
  .form {
    gap: var(--dd-space-6);
  }
}
