/* Buttons, fields and forms: the controls both shells draw.

   They started in product.css, back when every page that took input lived in
   the product shell. The community page moved into the archive shell — which
   had never held a form — and its admin panel came out as raw browser widgets:
   system-font buttons, white input boxes, checkboxes with no rhythm, all of it
   under a heading in the site's own type. Copying the rules into the second
   stylesheet would leave two definitions of one button free to drift apart, so
   they live here and each shell loads them after the tokens and before its own
   sheet, which stays free to override. */

/* One measure for every form on the site: wide enough for two fields side by
   side, short enough that a label still belongs to the box under it. Whatever a
   form stands next to — an invite list, a hint — lines up with it. */
:root {
  --form-measure: 760px;
}

/* A control does not inherit the page's font on its own, and the archive shell
   never had to say so. */
button,
input,
select,
textarea {
  font: inherit;
}

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 2.75rem;
  padding: var(--space-4) var(--space-7);
  border: var(--border-width) solid var(--line);
  border-radius: var(--radius-control);
  background: var(--surface);
  color: var(--text);
  font: var(--text-item);
  text-decoration: none;
  cursor: pointer;
}

.button:hover {
  background: var(--raised);
}

/* Google's sign-in button is Google's, not ours: its branding guidelines fix
   the mark, the wording, the 40px height, the 4px corner and the dark theme's
   colours — kept as --google-* in tokens.css — and they ask for Roboto Medium,
   named here without loading it, the way Google's own snippet does, so the page keeps its
   fallback rather than a font request. The hover is their state layer: white at
   8%, over the fill instead of replacing it. The geometry stays in literals for
   the same reason the colours have their own tokens: our control scale is free
   to move, this button is not. */
.google-button {
  display: inline-flex;
  position: relative;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  height: 40px;
  max-width: 400px;
  padding: 0 12px;
  border: 1px solid var(--google-line);
  border-radius: 4px;
  background-color: var(--google-surface);
  color: var(--google-ink);
  font: 500 14px/1 "Roboto", arial, sans-serif;
  letter-spacing: 0.25px;
  text-decoration: none;
  cursor: pointer;
}

.google-button::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background-color: var(--google-state);
  opacity: 0;
}

.google-button:hover::before { opacity: 0.08; }
.google-button:focus-visible::before,
.google-button:active::before { opacity: 0.12; }

.google-button-mark { flex: none; width: 20px; height: 20px; margin-right: 12px; }
/* The state layer sits over the fill, so the contents ride above it. */
.google-button-label { position: relative; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.button-danger {
  color: var(--danger);
  border-color: var(--danger);
  background: transparent;
}

.button-danger:hover {
  background: color-mix(in srgb, var(--danger) 10%, transparent);
}

.button-primary {
  background: var(--brand);
  border-color: var(--brand);
  color: var(--background);
}

/* The filled button states its own hover background: .button:hover outranks
   .button-primary, so leaving it to a filter dropped the fill back to the
   surface colour and left dark text on a dark button. */
.button-primary:hover {
  background: color-mix(in srgb, var(--white) 12%, var(--brand));
  border-color: color-mix(in srgb, var(--white) 12%, var(--brand));
  color: var(--background);
}

/* A row's own action sits inside dense content, so it drops the 44px comfort
   height the page-level buttons keep; the phone step below restores it. */
.button-compact {
  min-height: 2.15rem;
  padding: var(--space-3) var(--space-5);
  font: var(--text-meta);
}

.button[disabled] {
  opacity: var(--opacity-disabled);
  cursor: not-allowed;
}

.button-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
}

.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-5);
  max-width: var(--form-measure);
}

.field {
  display: grid;
  gap: var(--space-3);
}

.field-full {
  grid-column: 1 / -1;
}

/* Both field shapes state a display of their own, which outranks the UA's
   [hidden] rule: a field a form turns off — the identifier Steam and the
   consoles never ask for, Nintendo's disclosure everywhere else — stayed on
   screen and asked for something the platform does not use. */
.field[hidden],
.field-check[hidden] {
  display: none;
}

.field label {
  color: var(--muted);
  font: var(--text-meta);
}

.field input,
.field select,
.field textarea {
  font: var(--text-input);
  width: 100%;
  min-height: 2.7rem;
  color: var(--text);
  background: var(--background);
  border: var(--border-width) solid var(--line);
  border-radius: var(--radius-control);
  padding: var(--space-4) var(--space-5);
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  border-color: var(--text);
}

.field textarea {
  min-height: 7rem;
  resize: vertical;
}

.field-hint {
  color: var(--muted);
  font: var(--text-micro);
}

/* A value the person cannot change stands in the same row as the inputs but
   never poses as one: no control border, no editable ground. */
.field-static {
  margin: 0;
  display: flex;
  align-items: center;
  min-height: 2.7rem;
  padding: var(--space-4) 0;
  color: var(--muted);
  overflow-wrap: anywhere;
}

.field-check {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  color: var(--muted);
  font: var(--text-body);
}

.field-check input {
  margin-top: var(--space-2);
  accent-color: var(--brand);
}

/* A grade and the rarity it stands for read as one label: the rule sits under
   the word it explains rather than beside it. */
.field-check small {
  display: block;
  font: var(--text-micro);
  opacity: 0.75;
}

/* The product shell states one focus ring for the whole document; the archive
   shell gives each of its controls one. These are the archive's first inputs,
   so they carry their own — the same ring either way. */
.button:focus-visible,
.field :is(input, select, textarea):focus-visible,
.field-check input:focus-visible {
  outline: var(--border-width-strong) solid var(--brand);
  outline-offset: 3px;
}

/* A secret shown once. The warning frame is the whole point: it says the value
   is not coming back, so it is read before the page moves on. */
.secret-output {
  margin-top: var(--space-6);
  padding: var(--space-6);
  background: var(--background);
  border: var(--border-width) solid var(--warning);
  border-radius: var(--radius-surface);
  word-break: break-all;
}

.secret-output code {
  color: var(--warning);
  user-select: all;
}

/* The Stable Scale Rule's phone step: dense row controls take the 44px target
   back once the layout is one column. */
@media (max-width: 720px) {
  .button-compact {
    min-height: 2.75rem;
    padding: var(--space-4) var(--space-5);
  }
}

/* One column, and a field that spanned two spans nothing. */
@media (max-width: 560px) {
  .form-grid {
    grid-template-columns: 1fr;
  }

  .field-full {
    grid-column: auto;
  }
}
