/* ============================================================================
   Contact Us — ported from skiv-web/assets/css/contact.css, 2026-08-28.
   Founder: "Le contact us, je le veux comme sur Skiv."

   Ported declaration for declaration. What changed, and only this:
     - the palette values (ink #0E0E0D, card #F5F5F3, rgba literals 14,14,13)
     - the shell and the headline moved OUT, into main.css `.pshell` / `.pmast`,
       where every route now inherits them instead of copying them. Skiv keeps
       four copies of those six declarations, one per route stylesheet, and its
       own comment says what that costs: "if any of those six change on /blog/,
       they change here in the same pass, or the coherence this page was
       rebuilt for is gone."
     - the copy is Kalv's.

   THE LAYOUT is the founder's own call, made on skiv.app and kept: two
   columns, the things you fill in on the left, a small picture on the right.

   THE PICTURE IS SMALL AND TOP-ANCHORED. `max-height: 56%` is deliberate: run
   it to the full column height and the picture becomes the subject of the page,
   which is the form. The three facts sit under it rather than in a column of
   their own — they are read once each and do not deserve a third of the width.

   FIELDS ARE UNDERLINES, NEVER BOXES. A filled input box is a card by another
   name. They get their own line token, a notch darker than `--line`, so a
   control reads as a control and not as a divider.

   Chrome untouched: no background override, no topbar override, no radius of
   its own on `.hero`. main.css owns the ground, the grey card and the bar; a
   route owns its layout, not its skin.
   ========================================================================== */

/* ---- two columns: what you fill in | the picture -------------------------- */

.cbody {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, clamp(300px, 27vw, 430px));
  gap: clamp(28px, 4vw, 72px);
  flex: 1 1 auto;
  padding: clamp(22px, 2.6vw, 40px) 0 clamp(20px, 2.2vw, 34px);
}

.ccol {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}

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

/* The message row takes the slack. Everything above it is fixed height, the
   textarea absorbs whatever the window has left, and the send row sits on the
   floor — so no run of empty stage opens under the button. "Gros espaces vides"
   is a named red flag. */
.cform {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto auto minmax(0, 1fr) auto;
  gap: clamp(20px, 2.3vw, 34px) clamp(24px, 3vw, 52px);
  flex: 1 1 auto;
  min-height: 0;
}

.cfield { display: flex; flex-direction: column; min-width: 0; }
.cfield--wide { grid-column: 1 / -1; min-height: 0; }

.cfield > label {
  margin-bottom: 9px;
  color: var(--ink-2);
  font-size: 0.82rem;
  font-weight: 520;
  letter-spacing: -0.012em;
}

.cfield > label i { font-style: normal; color: var(--ink-3); }

.cfield > input,
.cfield > select,
.cfield > textarea {
  appearance: none;
  width: 100%;
  padding: 0 0 10px;
  border: 0;
  border-bottom: 1px solid var(--field-line);
  border-radius: 0;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 0.95rem;
  letter-spacing: -0.014em;
  transition: border-color 180ms var(--ease-ui);
}

.cfield > textarea {
  height: 100%;
  min-height: 72px;
  resize: none;
  line-height: 1.5;
}

.cfield > input::placeholder,
.cfield > textarea::placeholder { color: var(--ink-3); }

.cfield > input:hover,
.cfield > select:hover,
.cfield > textarea:hover { border-bottom-color: rgba(14, 14, 13, 0.34); }

.cfield > input:focus,
.cfield > select:focus,
.cfield > textarea:focus {
  outline: 0;
  border-bottom-color: var(--ink);
}

/* Native select arrows differ per platform and none of them match a hairline
   field; `appearance: none` plus a drawn chevron is the only way to keep the
   four controls reading as one set. */
.cfield--select { position: relative; }

.cfield--select::after {
  content: "";
  position: absolute;
  right: 2px;
  bottom: 16px;
  width: 7px;
  height: 7px;
  border-right: 1.5px solid var(--ink-2);
  border-bottom: 1.5px solid var(--ink-2);
  transform: rotate(45deg);
  pointer-events: none;
}

.cformfoot {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: clamp(16px, 2vw, 30px);
  flex-wrap: wrap;
}

.csend {
  display: inline-flex;
  align-items: center;
  min-height: 52px;
  padding: 0 26px;
  border: 0;
  border-radius: 999px;
  background: var(--cta-apple-bg);
  color: var(--cta-apple-fg);
  font: inherit;
  font-size: 0.9rem;
  font-weight: 640;
  letter-spacing: -0.016em;
  cursor: pointer;
  transition: background 200ms var(--ease-ui), transform 200ms var(--ease-ui);
}

.csend:hover { background: var(--cta-apple-bg-hover); transform: translateY(-1px); }
.csend:active { transform: translateY(0); }
.csend:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.csend[disabled] { opacity: 0.55; cursor: default; transform: none; }

.cnote {
  margin: 0;
  max-width: 46ch;
  color: var(--ink-3);
  font-size: 0.8rem;
  letter-spacing: -0.01em;
  line-height: 1.45;
}

.cnote a { color: var(--ink-2); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--line); }
.cnote a:hover { color: var(--ink); text-decoration-color: var(--ink); }

/* ---- the picture --------------------------------------------------------- */

/* A flat neutral field with a hairline, no label and no hatch. Production is
   not a wireframe. Dropping an <img> inside is the whole act of publishing the
   photograph later — no CSS changes, no markup around it. Founder call,
   carried over from skiv.app: "tu laisses les images toujours en vide". */
.cslot {
  position: relative;
  flex: none;
  aspect-ratio: 4 / 5;
  max-height: 56%;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: clamp(14px, 1.2vw, 18px);
  background: var(--paper);
}

.cslot img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* ---- the three facts ----------------------------------------------------- */

.cfacts { margin: clamp(20px, 2.2vw, 30px) 0 0; padding: 0; list-style: none; }

.cfacts li { padding: clamp(10px, 1.1vw, 15px) 0; border-top: 1px solid var(--line); }
.cfacts li:last-child { border-bottom: 1px solid var(--line); }

/* Sentence-case sans at eyebrow weight. The mono UPPERCASE micro-label is
   banned here as it is on every route. */
.cfacts b {
  display: block;
  margin-bottom: 4px;
  color: var(--ink-3);
  font-size: 0.74rem;
  font-weight: 620;
  letter-spacing: -0.005em;
  line-height: 1;
}

.cfacts span {
  color: var(--ink);
  font-size: 0.9rem;
  font-weight: 520;
  letter-spacing: -0.016em;
  line-height: 1.4;
}

.cfacts a { text-decoration: underline; text-underline-offset: 4px; text-decoration-color: var(--line); }
.cfacts a:hover { text-decoration-color: var(--ink); }
.cfacts a:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; border-radius: 3px; }

/* ---- the honeypot -------------------------------------------------------- */

/* Off-screen rather than `display: none`: the cheap bots that skip hidden
   inputs are exactly the ones this catches, so it has to be a real, focusable,
   fillable field that no human ever meets. `aria-hidden` and `tabindex=-1` on
   the markup keep it away from screen readers and the tab order. */
.chp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ---- the two end states -------------------------------------------------- */

/* One line each, in place of the button row. No tick, no green, no "Thanks!" —
   the page said one working day and the confirmation repeats the promise
   instead of celebrating a form submission. */
.csent, .cfail { display: none; }
.cform[data-state="sent"] .cformfoot,
.cform[data-state="failed"] .cformfoot { display: none; }
.cform[data-state="sent"] .csent { display: block; color: var(--ink); }
.cform[data-state="failed"] .cfail { display: block; }

/* --------------------------------------------------- short desktop window -- */

/* `.pshell { padding-top }` used to live here and was moved to main.css on
   2026-08-30. It is the route shell, not this route's body: overriding it here
   put /contact/'s headline at y=109 while every other page kept y=129 on an
   ordinary 1440x800 laptop — a 20px jump between adjacent pages, which is the
   drift § 6.1's corollary forbids. The short-window accommodation still
   happens; it now happens on every route at once. */
@media (min-width: 1025px) and (max-height: 830px) {
  .cform { gap: clamp(15px, 1.7vw, 24px) clamp(24px, 3vw, 52px); }
  .cslot { max-height: 48%; }
}

/* --------------------------------------------------------------- mobile ---- */

@media (max-width: 1024px) {
  .cbody {
    /* No `grid-template-columns` here: this block later switches `.cbody` to
       `display: flex` for the reordering, which makes a track declaration inert
       — and an inert declaration is a rule the next reader will trust. */
    gap: clamp(24px, 6vw, 34px);
    padding: clamp(20px, 5vw, 28px) 0 clamp(28px, 6vw, 38px);
  }

  /* The form stays first: it is what the page is for. The picture and the
     facts follow it, they do not gate it. */
  .cform { grid-template-columns: 1fr; grid-template-rows: none; gap: clamp(18px, 4.5vw, 24px); }
  .cfield > textarea { height: auto; min-height: 128px; }
  /* The single-line fields are hairline-underlined, so their box was the text
     and 10px of padding: 29px of target on a touch screen, against a 52px send
     button two rows below. The hairline does not move — the padding goes above
     the text, where there is already air. */
  .cfield > input, .cfield > select { min-height: 44px; padding-top: 14px; }
  /* The slot stays — it is the photograph's frame, deliberately empty until
     the photography ships (founder: "tu laisses les images toujours en vide").
     But in one column it landed BETWEEN the send button and the three facts,
     so an empty white rectangle cut the page in half right where the reader
     goes from "I sent it" to "or write to this address". It moves to the end
     of the block instead; the day an <img> lands in it, it closes the page. */
  .cbody { display: flex; flex-direction: column; }
  .cform { order: 1; }
  .cfacts { order: 2; }
  .cslot { order: 3; aspect-ratio: 16 / 10; max-height: none; margin-top: clamp(24px, 6vw, 34px); }
}

@media (prefers-reduced-motion: reduce) {
  .cfield > input, .cfield > select, .cfield > textarea, .csend { transition: none; }
  .csend:hover { transform: none; }
}
