/* SUPASMART estate controls — the served component sheet.
 *
 * Founder, 2026-08-20, ruling 4, verbatim:
 *
 *   "While you're at it, try to make the spacing and the layouts consistent
 *   and reusable, and also improve everything using front-end design skills
 *   or other good trending skills for front-end."
 *
 *   "Select what looks best and try to replicate it and improve it across."
 *
 * tokens.css serves the VALUES. layout.css serves the SHAPES those values are
 * spent on. This sheet serves the CONTROLS — the third thing four apps were
 * each writing out by hand, byte-similar and drifting. A recount of
 * `apps/{supasales,supacrm,social,recruiter}/ui/app.css` found the button pair
 * agreeing on every dimension that matters (44px floor, 11px/24px padding,
 * 999px pill, 14px/500) and disagreeing only on which of two equivalent ways to
 * hide the primary's border. That is not four designs; that is one design typed
 * four times, and the fourth copy is where a value goes wrong quietly.
 *
 * It is OPT-IN and CLASS-ONLY, exactly as layout.css is. There is no element
 * selector, no `:root`, no `*` reset and no `!important` here, so the sheet
 * styles NOTHING until a page writes one of these class names — adding the link
 * moves no pixel on any surface. Consume it AFTER tokens.css and BEFORE the
 * app's own styles, so the app still wins every collision:
 *
 *   <link rel="stylesheet" href="/shell/tokens.css?v=20260820-rhythm">
 *   <link rel="stylesheet" href="/shell/layout.css?v=20260820-rhythm">
 *   <link rel="stylesheet" href="/shell/controls.css?v=20260821-chips">
 *
 * Every colour is a var() and the file declares zero hexes, so gate.sh's
 * check_palette_law holds here as everywhere else. It reads tokens.css's
 * CANONICAL names, never the aliases that sheet publishes for apps.
 *
 * VOCABULARY OF RECORD: `.primary-button` / `.secondary-button`, the
 * three-app majority (supasales, supacrm, social). Recruiter's
 * `.btn` / `.btn.is-primary` call sites migrate onto these names; the
 * website's `.v2-*` dialect is §9-licensed and out of scope.
 *
 * The sheet serves TWO things a person meets: the controls they PRESS, and —
 * since 2026-08-21 — the `.chip` READINGS they only look at. Founder, on the
 * two items pass 548 left open, verbatim: "fix this too".
 *
 * WHAT THIS SHEET DELIBERATELY DOES NOT SHIP:
 *   · `.card`, and any hover on it. layout.css OWNS `.card` and has already
 *     ruled on it — "a card is not a control", no rest shadow, no hover — and
 *     its suite pins that refusal. A lift declared here would be a second owner
 *     for one class name, which is the exact duplication this train exists to
 *     end. An interactive card (SupaCRM's `a.card`) keeps its lift app-side.
 *   · Dialogs and sheets. Train 3C.
 *   · Any element reset. All four apps carry `* { box-sizing: border-box }` and
 *     `button, input { font: inherit }` of their own; this sheet re-declares
 *     both on its own classes instead, so it is correct on a page that has
 *     neither and loses to neither on a page that has both.
 */

/* ── the button pair ────────────────────────────────────────────────────────
   The floor, the padding, the pill, the type — unanimous across all four apps,
   re-read off the shipped CSS rather than trusted. Two literals survive on
   purpose: 44px is the touch-target floor, not a spacing step, and 11px is the
   measured block padding the estate ships — tokens.css's scale deliberately
   drops 11px, and rounding it to 10 or 12 would move every button in the estate
   by 2px to make a comment tidier.

   The base carries the hairline border and each variant recolours it, rather
   than the primary setting `border: 0`. Both render identically under the
   border-box the base declares, and only this form keeps the two buttons the
   same height on a page that has no box-sizing reset of its own. */
.primary-button,
.secondary-button {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s3);
  min-height: 44px;
  padding: 11px var(--s10);
  border: 1px solid var(--hairline);
  border-radius: var(--pill);
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0;
  /* Several of these are `<a>`, and a pill with an underline through it reads
     as a link wearing a button rather than as a press. */
  text-decoration: none;
  cursor: pointer;
  transition: background var(--swift), color var(--swift), border-color var(--swift);
}

/* Tomato is the ONE accent: it belongs to the press. */
.primary-button {
  border-color: var(--tomato);
  background: var(--tomato);
  color: var(--paper);
}
.primary-button:hover:not(:disabled),
.primary-button:active:not(:disabled) {
  border-color: var(--tomato-dark);
  background: var(--tomato-dark);
}
/* Shut is a grey pill, not a faded red one: 40% of an accent still shouts.
   `opacity: 1` is load-bearing — it defeats the UA's own fade, which is what
   would otherwise turn the grey back into washed-out tomato. */
.primary-button:disabled {
  border-color: var(--calm);
  background: var(--calm);
  color: var(--faint);
  opacity: 1;
  cursor: not-allowed;
}

.secondary-button:hover:not(:disabled) { background: var(--wash); }
.secondary-button:disabled {
  color: var(--faint);
  opacity: 1;
  cursor: not-allowed;
}

/* ── the chip grammar ───────────────────────────────────────────────────────
   Founder, 2026-08-21, on the two items pass 548 left open, verbatim:

     "fix this too"

   RULING BY DEFAULT, recorded for the founder to reverse. A chip is one of two
   things, and the drift across the estate's local chip blocks came from the two
   being typed as one:

     A PRESS   — an interactive filter or choice. Hairline border on paper;
                 CHOSEN fills INK, per the 2026-08-20 ink ruling. Already served
                 and adopted; this section declares nothing about it.
     A READING — a status about a thing or a person: keen, paused, live, hot,
                 won, added, soon. Not pressable, and it must not dress like
                 something that is. SupaCRM's sentence becomes the estate's:
                 "keen is a READING of a person, not a thing to press."

   READINGS ARE CALM BY DEFAULT: `--calm` ground, `--muted` text, no border, the
   999px pill, and the estate kicker's own type (BRAND §3 — 13px / 500 / muted /
   letter-spacing 0), because a status line and a status chip are one voice. The
   geometry is the middle of what the local blocks shipped: 4px/10px, on the
   scale rather than the 3px and 5px two of them invented.

   ONE ACCENT WASH, `.chip--live`: soft tomato marks the thing that is HAPPENING
   or just happened — live, now, hot, won — and nothing else. Its text is the
   DARKENED red, not the flat hue, which BRAND §2's legibility rule already
   spells out (`--red-dark` on `--soft-red`) and which is measured, not taste:
   flat `--tomato` on `--tomato-wash` is 3.8:1 at 13px and fails AA; the
   darkened form is 5.2:1 and passes.

   SOLID-TOMATO CHIPS RETIRE. A solid red chip reads as a button or an alarm; a
   solid fill belongs to the chosen state (ink) and the primary press (tomato),
   and a reading is neither. Nothing here fills `--tomato`. */
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  padding: var(--s1) var(--s4);
  border: 0; /* the law, and a `.chip` on a <button> must not wear the UA's */
  border-radius: var(--pill);
  background: var(--calm);
  color: var(--muted);
  font-family: var(--font);
  font-size: 13px;
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: 0;
  white-space: nowrap; /* a pill that wraps mid-status stops being a pill */
}
/* A weightier reading darkens its TEXT only: the calm ground is what says
   "reading", so carrying weight must not change it. */
.chip--ink { color: var(--ink); }
/* The one accent wash. Never `background: var(--tomato)` — see above. */
.chip--live {
  background: var(--tomato-wash);
  color: var(--tomato-dark);
}

/* ── the field ──────────────────────────────────────────────────────────────
   A CLASS, never the bare `input` element: a sheet that styled `input` would
   repaint every checkbox, radio and file picker on any page that merely LINKED
   it, which is the opposite of opt-in. Apply it to an input, a textarea or a
   select alike.

   48px is the majority height (social and recruiter; supasales runs 52px
   because its composer field carries a send button inside the shell). `--box`
   is the rest border — one step darker than the hairline, so a field reads as a
   field — and all three styling apps already agree on it, social by way of the
   `--line-strong` alias. 16px is not body copy: below 16px iOS Safari zooms the
   whole page on focus, so a field is the one place the 14px app canon yields. */
.field-input {
  box-sizing: border-box;
  width: 100%;
  min-width: 0;
  min-height: 48px;
  padding: var(--s5) var(--s6);
  border: 1px solid var(--box);
  border-radius: var(--r-sm);
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font);
  font-size: 16px;
  font-weight: 400;
  -webkit-appearance: none;
  appearance: none;
  transition: border-color var(--swift), box-shadow var(--swift);
}
.field-input::placeholder { color: var(--faint); }
.field-input:focus {
  outline: none;
  border-color: var(--ink);
  box-shadow: var(--ring);
}
/* The other half of "tomato is the accent AND the invalid marker". Pair it with
   a spoken reason (§8: never a silent fail, never colour alone). */
.field-input.is-invalid { border-color: var(--tomato); }

/* ── the one ring, ink ───────────────────────────────────────────────────────
   Founder, 2026-08-20, ruling 2 — "Ink everywhere": the keyboard focus ring is
   INK. A red ring on a control that is merely focused said "something is wrong"
   on every tab press. `--focus` is served; the 2px offset is the pairing that
   token's own comment names. It follows `.field-input:focus` because the two
   are equal specificity and the field clears its outline — source order is the
   whole reason the ring survives on a focused field. */
.primary-button:focus-visible,
.secondary-button:focus-visible,
.field-input:focus-visible {
  outline: var(--focus);
  outline-offset: 2px;
}

/* ── motion, clamped ────────────────────────────────────────────────────────
   Scoped to this sheet's OWN transitions. The estate carries five copy-pasted
   `*, *::before, *::after` clamps; a served sheet must not ship a sixth,
   because a `*` rule here would reach every element on every adopting page and
   the opt-in promise above would be a lie. */
@media (prefers-reduced-motion: reduce) {
  .primary-button,
  .secondary-button,
  .field-input { transition: none; }
}
