/* ===== Fields =====
 *
 * Every dropdown, text box and text area in the app, drawn once.
 *
 * There were nine looks and two holes. The session picker on the timeline; the
 * outcome and rest pickers in its amend form; the alias picker under the dice;
 * the voice pickers in the stage's drawer; the doorway pages' own rule for
 * inputs; the campaign and character fields; the admin boxes; the search page's
 * one big box -- five stylesheets, four background colours, five paddings,
 * three font sizes. And then two controls that matched no selector at all and
 * so were drawn by the operating system: the three dropdowns on the familiar
 * panel, and the member-name boxes under "Running the table".
 *
 * Its own sheet, loaded by every page, for the reason nav.css, theme.css and
 * button.css have theirs. A control whose styling is scattered across the
 * sheets of the pages that happen to use it is a control that gets missed on
 * the next page somebody writes -- which is exactly what happened, twice.
 *
 * What is deliberately NOT here: how big a given box is and where it sits.
 * A search box wants to be large and a rest picker wants to be small; the
 * doorway forms stack full-width and the amend rows sit side by side. Those
 * stay with the page that has the opinion. This file owns the *look*.
 *
 * Palette from tokens.css; nothing here defines its own colours.
 */

select,
textarea,
input[type="text"],
input[type="email"],
input[type="password"],
input[type="search"] {
  background-color: var(--field);
  color: var(--text);

  /* --edge, not --line. This is the boundary of something you operate, and
     --line is a rule between things: it manages 1.3:1 against the paler
     surfaces here, well under the 3:1 WCAG asks of a control's edge. See the
     note in tokens.css. */
  border: 1px solid var(--edge);
  border-radius: 8px;

  /* 1rem is not a preference, it is the iOS rule: Mobile Safari zooms the
     whole viewport when you focus a field whose text is under 16px, and then
     leaves you there. This app is meant to be used on a tablet propped at the
     end of a table and on the phone in your pocket, so every one of these had
     to clear 16px.

     That put fields a size above the buttons, which are 0.9rem and have no
     such problem -- so the padding is what closes the gap instead: 0.44rem
     against the button's 0.5rem puts both boxes at the same height, to within
     a hundredth of a rem. A dropdown standing in a row beside Bind and Dismiss
     has to line up with them. */
  font-family: inherit;
  font-size: 1rem;
  line-height: 1.3;
  padding: 0.44rem 0.7rem;
}

textarea { resize: vertical; }

/* ---------- writing, as opposed to filling in ----------
 *
 * A campaign note and a familiar's persona are documents. They were being
 * written through a slot: the persona box inherited .amend-form's 3.2rem
 * min-height -- two lines -- for a page of prose, so editing one meant
 * scrolling a small window up and down a long text you could never see the
 * shape of.
 *
 * Three things fix that, and the third is the one that matters. It opens at a
 * useful size. It is set like something meant to be read back: more air inside
 * the box, a looser line, and a measure that stops at --prose rather than
 * running the width of a laptop. And it grows as you type (autoGrowTextarea in
 * hub.js), so the box is always exactly as tall as what is in it and the page
 * scrolls instead of the field.
 *
 * `resize: none` follows from that rather than taking something away: a box
 * that sizes itself has nothing left for a drag handle to do, and the handle
 * would only be overruled by the next keystroke. */
textarea.prose {
  min-height: 11rem;
  max-width: var(--prose);
  padding: 0.8rem 0.95rem;
  line-height: 1.65;
  resize: none;
  /* The grown height is set inline; without this the growth is a jump. */
  transition: height 0.08s ease-out;
}

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

select {
  /* The native widget goes, arrow and all, so the whole control can follow the
     palette. What replaces the arrow is drawn below, out of the same tokens --
     an SVG would have had to bake its colour into a data URI, and a colour
     baked into a URI is a colour that cannot follow the theme. */
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  padding-right: 1.7rem;

  /* The arrow: two right-triangles from two gradients, meeting to make one
     solid caret pointing down. Five pixels each, laid end to end -- 12px to
     7px from the right edge -- so they share an edge rather than leaving a
     hairline of background between them. */
  background-image:
    linear-gradient(45deg, transparent 50%, var(--text-dim) 50%),
    linear-gradient(135deg, var(--text-dim) 50%, transparent 50%);
  background-size: 5px 5px, 5px 5px;
  background-position: right 12px center, right 7px center;
  background-repeat: no-repeat;
}

/* --accent, not --control-hover. Reaching for the "hover" token was the
   obvious move and it was the wrong one: --control-hover is a *fill*, and
   using it as an edge dropped the border to 1.26:1 in daylight -- so putting
   the pointer on a dropdown made its outline fade out, which is precisely
   backwards. Hover and focus share a colour; the focus ring is what tells
   them apart. */
select:hover { border-color: var(--accent); }

/* Matched to the buttons: the border takes the accent, and a keyboard arrival
   gets a ring it cannot miss. */
select:focus,
textarea:focus,
input[type="text"]:focus,
input[type="email"]:focus,
input[type="password"]:focus,
input[type="search"]:focus { outline: none; border-color: var(--accent); }

select:focus-visible,
textarea:focus-visible,
input[type="text"]:focus-visible,
input[type="email"]:focus-visible,
input[type="password"]:focus-visible,
input[type="search"]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

select:disabled,
textarea:disabled,
input:disabled { opacity: 0.6; cursor: default; }
select:disabled:hover { border-color: var(--edge); }

::placeholder { color: var(--text-dim); }

/* ---------- small print ----------
 *
 * The line under a label that says what the box is for, and the sibling class
 * the rest of the app spells `.note` -- an empty state, a caveat, the sentence
 * explaining what a control will do. They are one typographic object and are
 * declared once here.
 *
 * Here specifically because this file is loaded by every page and the ones
 * that own text are not. `.note` lived in page.css, which the doorway pages
 * load and the table's own pages do not -- so all twenty-six of them on the
 * hub, the campaign panel's own "the familiar reads these before every answer"
 * included, were rendering as full-size body text. It was small print that was
 * not small anywhere it mattered.
 *
 * landing.css keeps its own italic variant on purpose; that page sets its
 * captions differently and says so. */
.note,
.field-hint {
  color: var(--text-dim);
  font-size: 0.88rem;
  line-height: 1.5;
}

/* Inside a field it is guidance, and it belongs to the label above it rather
   than floating loose between two controls. */
.field-hint { display: block; max-width: var(--prose); }

/* The open list is drawn by the operating system and is mostly not ours to
   paint. It is not left to chance, though: tokens.css sets `color-scheme` per
   theme, so the platform draws its own menu the right way round -- dark on the
   dark table, light in daylight. */
