/* ══════════════════════════════════════════════════════════════════════════
   CAPITAL CULTURES · FORMS
   Every control on the site: the field, the consent box, the error, the
   status line. Split out of components.css on 28 August 2026 so the intake
   markup (lib/forms.mjs), the endpoints (api/) and these styles are owned by
   one hand.

   The rules underneath every one of them:
     · a control is a rule and a line of type. No box, no radius, no shadow
     · the label is mono and it is always there — a placeholder is not a label
     · the focus ring is the band's own type colour, offset outside the control
     · a spice never carries small type; consent boxes read on both grounds

   Owner: W5. Loaded by components.css (@import, first rule) until the head is
   extracted and can link it beside the others.
   ══════════════════════════════════════════════════════════════════════════ */

/* ══ 1. THE FIELD ════════════════════════════════════════════════════════ */
.form{margin-top:clamp(22px,2.8vw,40px);max-width:760px}
.form-grid{display:grid;gap:clamp(18px,2.2vw,28px);grid-template-columns:repeat(2,1fr)}
.f{display:flex;flex-direction:column;gap:7px;grid-column:span 2;min-width:0}
@media(min-width:700px){.f--half{grid-column:span 1}}
.f > label,.f > .f-legend{font-family:var(--face-mono);font-size:var(--fs-mono);
  font-weight:600;letter-spacing:var(--ls-mono);text-transform:uppercase;color:var(--type-2)}
.f .req{color:var(--type-2)}
.f input,.f textarea,.f select{
  font:inherit;font-size:18px;color:inherit;background:transparent;
  border:0;border-bottom:var(--rule-thick) solid currentColor;
  padding:12px 2px;outline:none;border-radius:0;width:100%;min-width:0;
  transition:background var(--t-micro)}
.f select{appearance:none;padding-right:26px;
  background-image:linear-gradient(45deg,transparent 50%,currentColor 50%),
                   linear-gradient(135deg,currentColor 50%,transparent 50%);
  background-position:calc(100% - 12px) 22px,calc(100% - 6px) 22px;
  background-size:6px 6px,6px 6px;background-repeat:no-repeat}
.f select option{background:var(--ink);color:var(--paper)}
.band--turmeric .f select option,.band--matcha .f select option,
.band--saffron .f select option,.band--paper .f select option{background:var(--paper);color:var(--ink)}
.f textarea{min-height:130px;resize:vertical;line-height:1.5}
/* a placeholder is text. At .55 alpha it measured 2.9:1 on sumac. */
.f input::placeholder,.f textarea::placeholder{color:var(--type-2);opacity:1}
.f input:focus-visible,.f textarea:focus-visible,.f select:focus-visible{
  outline:var(--rule-thick) solid var(--type);outline-offset:3px}
.f .help{font-size:13px;color:var(--type-2);max-width:56ch}
.f[data-invalid="true"] input:not([type=checkbox]):not([type=radio]),
.f[data-invalid="true"] textarea,.f[data-invalid="true"] select{
  background:color-mix(in srgb,var(--type) 14%,transparent)}
.f .err{font-size:13px;font-weight:700}
.f .err:empty{display:none}

/* ══ 2. CHECKBOX / RADIO GROUPS — CASL consent lives here ════════════════ */
.f-group{display:grid;gap:11px;border:0;padding:0;margin:0;grid-column:span 2}
.f-group legend{padding:0;margin-bottom:11px;font-family:var(--face-mono);
  font-size:var(--fs-mono);font-weight:600;letter-spacing:var(--ls-mono);text-transform:uppercase}
.check{display:grid;grid-template-columns:22px 1fr;gap:12px;align-items:start;
  font-size:15px;line-height:1.45;cursor:pointer}
.check input{appearance:none;width:22px;height:22px;margin:0;
  border:var(--rule-thick) solid currentColor;background:transparent;cursor:pointer;
  display:grid;place-content:center;flex:0 0 auto}
.check input[type=radio]{border-radius:0}
.check input::before{content:"";width:10px;height:10px;background:currentColor;
  transform:scale(0);transition:transform var(--t-micro) var(--snap)}
.check input:checked::before{transform:scale(1)}
.check input:focus-visible{outline:var(--rule-thick) solid var(--type);outline-offset:3px}

/* ══ 3. THE FOOT — the button and the status line ════════════════════════ */
.form-foot{display:flex;flex-wrap:wrap;gap:16px;align-items:center;
  margin-top:clamp(22px,2.6vw,34px)}
.form .msg{min-height:1.4em;font-weight:600;flex:1 1 220px}
.form .msg:empty{min-height:0}
.form .note{margin-top:14px;color:var(--type-2);max-width:60ch}

/* ══ 4. SMALL SCREENS ═════════════════════════════════════════════════════ */
@media(max-width:760px){
  .form-grid{grid-template-columns:1fr}
  .f,.f-group{grid-column:span 1}
  .form-foot{flex-direction:column;align-items:stretch}
  .form-foot .btn{justify-content:center}
  /* in a column flex the 220px basis becomes a 220px dead height under the
     button; the status line only ever needs its own line of text */
  .form-foot .msg{flex:0 1 auto}
}

/* ══ 5. THE ERROR COLOUR ══════════════════════════════════════════════════
   An error was announced in the type colour of the band — that is to say, in
   no colour at all — over a fill measured at 1.47:1 against the ink ground,
   which WCAG 1.4.11 asks to be 3:1 before it counts as a mark at all. The
   error now owns a colour, and the colour changes with the ground it stands
   on: chilli-lit reads 5.22:1 on ink, plain chilli reads on paper. Colour is
   never the only carrier — the field also gets its own sentence, and the
   summary at the top of the form counts them. */
.form{--err:var(--chilli-lit)}
/* Plain chilli reads 4.01:1 on paper — under the 4.5:1 an error sentence has
   to clear at this size. A fifth of ink darkens it to 5.08:1 and keeps it the
   same red; no colour is invented, the two ends of the mix are both tokens. */
.band--paper .form,.band--turmeric .form,.band--matcha .form,.band--saffron .form{
  --err:color-mix(in srgb,var(--chilli) 85%,var(--ink))}
.band--chilli .form,.band--sumac .form,.band--indigo .form{--err:var(--type)}

/* ══ 6. A FIELD THAT LOOKS LIKE A FIELD BEFORE IT IS TOUCHED ═════════════
   The rule under an input was the only thing marking it, and on a phone the
   gap between the label and that hairline read as 55px of nothing. A sixth
   of the type colour is enough to say «type here» and quiet enough to keep
   the page a run of rules rather than a stack of boxes. */
.f input:not([type=checkbox]):not([type=radio]),.f textarea,.f select{
  background:color-mix(in srgb,var(--type) 6%,transparent)}
.f input:not([type=checkbox]):not([type=radio]):hover,.f textarea:hover,.f select:hover{
  background:color-mix(in srgb,var(--type) 10%,transparent)}

.f[data-invalid="true"] input:not([type=checkbox]):not([type=radio]),
.f[data-invalid="true"] textarea,.f[data-invalid="true"] select{
  background:color-mix(in srgb,var(--err) 10%,transparent);
  border-bottom-color:var(--err)}
.f .err,.f-group .err{color:var(--err);font-size:14px;font-weight:700;line-height:1.4}
.f-group[data-invalid="true"] legend{color:var(--err)}
.err:empty{display:none}

/* ══ 7. THE SUMMARY AND THE CONFIRMATION ════════════════════════════════
   One live region per form. Six fields announcing «one required field is
   still empty» at the same moment is six announcements a screen reader
   queues or drops; this is the one that speaks, it says how many and which
   one comes first, and focus lands on it rather than on a field whose own
   message would then be cut off mid-sentence. */
.form-summary{margin:0 0 clamp(18px,2vw,26px);padding:12px 0 12px 16px;
  border-left:var(--rule-thick) solid var(--err);color:var(--err);
  font-weight:700;font-size:var(--fs-body);max-width:60ch}
.form-summary:focus{outline:var(--rule-thick) solid var(--type);outline-offset:6px}

/* A sent form does not empty itself. It stands down and hands over a number. */
.form-done{border-top:var(--rule-thick) solid currentColor;padding-top:clamp(18px,2.2vw,26px);
  margin-top:clamp(18px,2.2vw,26px);max-width:60ch}
.form-done:focus{outline:var(--rule-thick) solid var(--type);outline-offset:6px}
.form-done .t{font-size:var(--fs-lede);font-weight:800;margin:0 0 10px;line-height:1.25}
.form-done .c{font-family:var(--face-mono);font-size:var(--fs-mono-lg);
  letter-spacing:var(--ls-mono);color:var(--type-2);margin:0}
.form-done .c:empty{display:none}

/* The block hides its own parts, and .form-grid is a grid, so the plain
   attribute needs saying twice. Scoped to the form: nothing else on the site
   is touched by it. */
.form [hidden],.form-summary[hidden],.form-done[hidden]{display:none!important}

/* ══ 8. THE CONSENT BOX ═══════════════════════════════════════════════════
   Two defects, one line of markup apart. The box took its border from
   `currentColor` while `color:inherit` was only ever declared for controls
   inside .f — a group box lives in a fieldset, inherited `fieldtext`, and
   drew itself in #000: 1.13:1 on the ink ground, which is to say invisible,
   ticked or not, on 300 of the site's 374 boxes. And the target itself was
   22px against the 24px WCAG 2.2 asks for, on the last control before the
   send button. */
.f input,.f-group input,.check input{color:inherit}
.check{grid-template-columns:24px 1fr;min-height:44px;align-items:center;padding:4px 0}
.check input{width:24px;height:24px}
.check input::before{width:12px;height:12px}
.check:hover input{background:color-mix(in srgb,currentColor 12%,transparent)}
