/* OSTC form shell (spec 4.5, R13 b "one matrix", R15 for corners and states, R17 for durations). Contract: /shared/README-scripts.md. Paired with /shared/form-shell.js.
   Soft rectangle (R15): the card is 16 px (--radius-panel), every field and the submit 10 px (--radius-control), 48 px tall. The gold and brass top edges follow the curve:
   they are inset shadows on an overlay in the card's own shape, never a border-top or a stripe the curve would cut off.
   Tokens come from tokens.css when present; every one has a fallback hex so this file stands alone.
   No panel is dark. White on every light ground and on terracotta; #FBF7EE only in the walnut footer (.site-footer sets its own surface).
   data-ground says what the ground ROUND the panel is: "light" (cream, limestone, honey, ochre, vellum, sandstone) or "dark" (terracotta, walnut). */

.form-panel {
  --fp-ink: #12233a;        /* navy on white 15.82 */
  --fp-line: #7a6a58;       /* input border 5.21 on white */
  --fp-error: #8e2a1e;      /* 8.40 on white, 7.86 on #FBF7EE */
  --fp-locked: #efe7d8;     /* sending: navy on it 12.88 */
  --fp-surface: #fff;
  --fp-gold: var(--light, #f5c542);
  --fp-core: var(--light-core, #fff3d6);
  --fp-ember: var(--light-ember, #e8a33d);
  --fp-edge: var(--fp-gold);                  /* the 2 px top edge: gold on a dark ground */
  --fp-ledge: var(--brass-deep, #6e4e17);     /* the lit ledge under the field you are in */
  --fp-pad: 24px;
  position: relative;
  isolation: isolate;
  color-scheme: light;
  color: var(--fp-ink);
  font-family: var(--font-body, Lato, "Lato Fallback", system-ui, sans-serif);
  font-size: 17px;
  line-height: 1.5;
  text-align: left;
}
.form-panel[data-ground="light"] { --fp-edge: var(--brass, #8c6420); } /* 5.30 on white */
.site-footer .form-panel { --fp-surface: var(--panel-warm, #fbf7ee); } /* Home's signup on walnut: navy on it 14.80 */
@media (min-width: 900px) {
  .form-panel { --fp-pad: 32px; }
}

/* The cast under the panel's foot on a light ground (R13): a 10 px gradient falling away from the lamp, never a box-shadow. Static.
   Set in by the panel radius and faded at its ends, so it never shows past the 16 px curve (R15 d). */
.form-panel[data-ground="light"]::before {
  content: "";
  position: absolute;
  z-index: -1;
  left: var(--radius-panel, 16px);
  right: var(--radius-panel, 16px);
  top: 100%;
  height: 10px;
  pointer-events: none;
  background: linear-gradient(var(--cast, rgb(42 30 20 / 0.18)), rgb(42 30 20 / 0));
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 24px, #000 calc(100% - 24px), transparent);
  mask-image: linear-gradient(90deg, transparent, #000 24px, #000 calc(100% - 24px), transparent);
}

/* The pool of light on the ground under the panel (dark grounds only: terracotta and walnut). Static. */
.form-panel[data-ground="dark"]::before {
  content: "";
  position: absolute;
  z-index: -1;
  left: max(-6%, -12px); /* the pool runs 6 percent past each side but never past 12 px, which is inside the 16 px phone gutter (it made the page scroll sideways) */
  right: max(-6%, -12px);
  top: 100%;
  aspect-ratio: 1.8 / 1;
  transform: translateY(-50%);
  pointer-events: none;
  background: radial-gradient(closest-side, rgb(245 197 66 / 0.4), rgb(232 163 61 / 0.16) 50%, rgb(232 163 61 / 0) 100%);
}

.fp-card {
  position: relative;
  box-sizing: border-box;
  overflow: hidden;
  padding: var(--fp-pad);
  background: var(--fp-surface);
  border-radius: var(--radius-panel, 16px);
}
.form-panel[data-ground="light"] .fp-card { border: 1px solid rgb(18 35 58 / 0.16); } /* a hairline, decoration */
.form-panel[data-state="success"] .fp-card { display: flex; flex-direction: column; justify-content: center; }

/* The top edge: 2 px, an overlay in the card's own shape (R15 d). ::before is the line, an inset shadow that runs the full width along the straight top
   and thins round each corner to nothing, its opacity carrying the state (240 ms, --t-light); ::after is the travelling bar of light, 2 px tall,
   and the overlay's corners clip it. */
.fp-edge {
  position: absolute;
  z-index: 2;
  inset: 0;
  height: auto;
  border-radius: inherit;
  overflow: hidden;
  container-type: inline-size;
  pointer-events: none;
}
.fp-edge::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: none;
  box-shadow: inset 0 2px 0 var(--fp-edge);
  opacity: 0.8;
  transition: opacity var(--t-light, 240ms) var(--ease, ease);
}
.fp-edge::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 96px;
  height: 2px;
  opacity: 0;
  transform: translateX(-96px);
  /* sending: a 96 px bar of #FFF3D6 to gold to clear, with a 2 px #8C6420 leading edge so the moving light shows on white */
  background: linear-gradient(90deg, rgb(255 243 214 / 0), var(--fp-core) 25%, var(--fp-gold) 70%, rgb(245 197 66 / 0.6) calc(100% - 2px), var(--brass, #8c6420) calc(100% - 2px));
}
.form-panel[data-state="sending"] .fp-edge::before { opacity: 0.5; }
.form-panel[data-state="send-error"] .fp-edge::before { opacity: 0.35; }
.form-panel[data-state="success"] .fp-edge::before { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  html:not(.motion-paused) .form-panel[data-state="sending"] .fp-edge::before { opacity: 0.22; }
  html:not(.motion-paused) .form-panel[data-state="sending"] .fp-edge::after {
    opacity: 1;
    animation: fp-travel var(--t-travel, 900ms) cubic-bezier(0.45, 0, 0.55, 1) infinite;   /* one 900 ms pass, repeated only while sending (R17 b) */
  }
}
@keyframes fp-travel {
  from { transform: translateX(-96px); }
  to { transform: translateX(100cqw); }
}

/* Fields */
.fp-fields { display: grid; gap: 20px; min-width: 0; margin: 0; padding: 0; border: 0; }
.fp-field label { display: block; margin-bottom: 8px; font-weight: 700; font-size: 16px; line-height: 1.3; color: var(--fp-ink); }
.fp-field label .fp-opt { font-weight: 400; }
.fp-control { position: relative; }
.fp-control :is(input, select, textarea) {
  display: block;
  box-sizing: border-box;
  width: 100%;
  min-height: 48px;
  margin: 0;
  padding: 12px 14px;
  font: 400 17px/22px var(--font-body, Lato, "Lato Fallback", system-ui, sans-serif);   /* 22 + 24 + 2 = 48 exactly on one line; 17 px keeps iOS from zooming */
  color: var(--fp-ink);
  background: #fff;
  border: 1px solid var(--fp-line);
  border-radius: var(--radius-control, 10px);
  -webkit-appearance: none;
  appearance: none;
}
.fp-control textarea { min-height: 132px; resize: vertical; }
.fp-control select {
  padding-right: 44px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%2312233A' stroke-width='1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 16px center;
}
/* Focus: the field's own edge becomes a 2 px navy line along the 10 px curve (the 1 px border plus a 1 px inset line of the same ink), which is the accessible signal,
   and the lit ledge fades in (decoration). The transparent outline stays on purpose: forced colours paints it in the system colour. */
.fp-control :is(input, select, textarea):focus {
  outline: 2px solid transparent;
  border-color: var(--fp-ink);
  box-shadow: inset 0 0 0 1px var(--fp-ink);
}
.fp-control::after {
  content: "";
  position: absolute;
  left: 20%;
  right: 20%;
  bottom: -2px;
  height: 2px;
  opacity: 0;
  transition: opacity var(--t-hover, 140ms);
  pointer-events: none;
  background: linear-gradient(90deg, rgb(245 197 66 / 0), var(--fp-ledge) 50%, rgb(245 197 66 / 0));
}
.fp-control:focus-within::after { opacity: 1; }

/* Field error: border, a 2 px error ledge, and a message led by a rule, so colour is never alone. */
.fp-error { display: none; position: relative; margin: 10px 0 0; padding-left: 20px; font-size: 16px; line-height: 1.4; color: var(--fp-error); }
.fp-error::before { content: ""; position: absolute; left: 0; top: 0.7em; width: 12px; height: 2px; background: currentColor; }
.fp-field.is-invalid .fp-error { display: block; }
.fp-field.is-invalid .fp-control :is(input, select, textarea) { border-color: var(--fp-error); }
.fp-field.is-invalid .fp-control :is(input, select, textarea):focus { border-color: var(--fp-ink); }
.fp-field.is-invalid .fp-control::after { left: var(--radius-control, 10px); right: var(--radius-control, 10px); opacity: 1; background: var(--fp-error); } /* starts and ends one radius in, so the bar never stands past the 10 px curve (R15 d) */

/* Sending: fields locked on #EFE7D8 */
.fp-fields:disabled :is(input, select, textarea) {
  background-color: var(--fp-locked);
  color: var(--fp-ink);
  -webkit-text-fill-color: var(--fp-ink);
  opacity: 1;
  cursor: progress;
}
.fp-fields:disabled label { color: var(--fp-ink); }

/* The honeypot: off screen, out of the tab order (tabindex -1), hidden from assistive tech. */
.fp-honey { position: absolute; left: -9999px; top: auto; width: 1px; height: 1px; overflow: hidden; }

/* Submit: the navy door (4.3, R13, R15): navy with a 2 px gold top edge that follows the curve (an inset shadow, no border), on every panel.
   It takes buttons.css's press (scale 0.98, colour in 70 ms, shrink in 120 ms, back in 140 ms) through the same three-property transition list. */
.fp-submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  min-height: 48px;
  margin: 24px 0 0;
  padding: 0 24px;
  font: 700 17px/1.3 var(--font-body, Lato, "Lato Fallback", system-ui, sans-serif);
  letter-spacing: 0.01em;
  color: #fff3d6;           /* the door's label: 14.35 on navy */
  background-color: #12233a;
  border: 0;
  box-shadow: inset 0 2px 0 var(--fp-gold);
  border-radius: var(--radius-control, 10px);
  cursor: pointer;
  transition: background-color var(--t-hover, 140ms) var(--ease, ease), border-color var(--t-hover, 140ms) var(--ease, ease), transform var(--t-hover, 140ms) var(--ease, ease);
}
@media (hover: hover) { .fp-submit:hover { background-color: var(--navy-hover, #1b3150); } }
.fp-submit:active { background-color: var(--navy-press, #0b1626); }
.fp-submit:focus-visible { outline: 2px solid var(--fp-ink); outline-offset: 3px; }   /* its own ink: a white card on any ground */
.fp-submit:disabled { cursor: not-allowed; opacity: 0.55; }
.fp-submit[aria-busy="true"] { cursor: progress; }

/* Send error: the line above the button */
.fp-send-error { display: none; margin: 20px 0 0; }
.form-panel[data-state="send-error"] .fp-send-error { display: block; }
.fp-send-error p { margin: 0; position: relative; padding-left: 20px; font-size: 17px; line-height: 1.45; color: var(--fp-error); }
.fp-send-error p::before { content: ""; position: absolute; left: 0; top: 0.72em; width: 12px; height: 2px; background: currentColor; }
.fp-send-error .fp-or { margin-top: 6px; color: var(--fp-ink); }
.fp-send-error .fp-or::before { display: none; }
.fp-send-error .fp-or[hidden] { display: none; }
.fp-send-error a { color: var(--fp-ink); text-decoration: underline; text-underline-offset: 3px; }
.form-panel[data-state="send-error"] .fp-submit { margin-top: 20px; }

/* Success: the form is replaced in place by the thank-you line; a pool of light rises from the floor. */
.fp-thanks { display: none; position: relative; z-index: 1; }
.form-panel[data-state="success"] .fp-thanks { display: block; padding: 24px 0 40px; }
.form-panel[data-state="success"] .fp-form { display: none; }
.fp-thanks p {
  margin: 0;
  font: 600 26px/1.25 var(--font-display, "Cormorant Garamond", "Cormorant Fallback", Georgia, serif);
  color: var(--fp-ink);
}
.fp-thanks p:focus { outline: none; }
.fp-rise {
  position: absolute;
  z-index: 0;
  left: 0;
  right: 0;
  bottom: 0;
  height: 75%;
  pointer-events: none;
  transform-origin: 50% 100%;
  /* sent: a #FFF1CC pool rises behind the thank-you line (navy on it 14.09) */
  background: radial-gradient(ellipse 75% 100% at 50% 100%, #fff1cc, rgb(255 241 204 / 0.65) 55%, rgb(255 241 204 / 0) 82%);
}
/* The success pool is an entrance (R17 a): the finished pool is the default, so with no motion-ok (reduced motion, Save-Data, a slow connection), under Pause, and
   once this panel's success has played in the session (form-shell.js adds .is-done), the pool simply stands. It rises (scaleY, --t-done) only on a panel's first
   success, under motion-ok and not paused. The card's overflow and corners cut the pool to the curve. */
.fp-rise { transform: scaleY(0); }
.form-panel[data-state="success"] .fp-rise { transform: none; }
@media (prefers-reduced-motion: no-preference) {
  html.motion-ok:not(.motion-paused) .form-panel[data-state="success"]:not(.is-done) .fp-rise { animation: fp-rise var(--t-done, 400ms) var(--ease-out, cubic-bezier(0.2, 0.7, 0.2, 1)) both; }
}
@keyframes fp-rise { from { transform: scaleY(0); } }
@media (prefers-reduced-motion: reduce) {
  .fp-edge::before { transition: none; }
}

/* No script, no backend: the email line on the same panel. */
.fp-noscript { display: none; margin: 0; }
.fp-noscript p { margin: 0; }
.fp-noscript a { color: var(--fp-ink); text-decoration: underline; text-underline-offset: 3px; }
@media (scripting: none) {
  .fp-form { display: none; }
  .fp-noscript { display: block; }
}
.form-panel[data-state="no-script"] .fp-form { display: none; }
.form-panel[data-state="no-script"] .fp-noscript { display: block; }

/* Review switcher (?review=1) */
.fp-review {
  position: fixed;
  z-index: 2147483000;
  left: 16px;
  bottom: 16px;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  box-sizing: border-box;
  max-width: calc(100vw - 32px);
  padding: 4px;
  background: var(--eave, #e9deca);              /* the eave, never a blue patch (R13) */
  border: 1px solid rgb(18 35 58 / 0.24);
  border-radius: var(--radius-control, 10px);
  font-family: var(--font-body, Lato, "Lato Fallback", system-ui, sans-serif);
}
.fp-review button {
  min-width: 44px;
  min-height: 44px;
  padding: 0 12px;
  font: 700 16px/1.3 var(--font-body, Lato, "Lato Fallback", system-ui, sans-serif);
  color: var(--navy, #12233a);
  background: transparent;
  border: 0;
  border-radius: var(--radius-control, 10px);
  cursor: pointer;
}
.fp-review button[aria-pressed="true"] { color: #12233a; background: #f5c542; }
.fp-review button:focus-visible { outline: 2px solid var(--navy, #12233a); outline-offset: -2px; }

@media (forced-colors: active) {
  /* the browser drops every box-shadow here, so the inset edge vanishes, which is right for decoration. The overlay fills the card now, so a Highlight
     background would paint all of it: the edge becomes a 2 px system-coloured line along the top instead (R15 d). And a button with no border has no outline left
     once its fill is forced, so the submit takes a visible border. */
  .fp-edge::before { background: none; border-top: 2px solid Highlight; }
  .fp-error::before, .fp-send-error p::before { background: CanvasText; }
  .fp-control::after { background: Highlight; }
  .fp-submit { border: 1px solid ButtonText; }
}

/* The line under the button (decision D20) */
.fp-next { margin: 12px 0 0; font-size: 16px; line-height: 1.45; color: var(--panel-quiet, #505869); } /* the page's quiet on white, 7.14 to 12.39 */
