/* Primitives applied as a class to a native element. They cannot live in a
   component's scoped stylesheet because the element is written by the page —
   an <input> rendered by InputText, a <button> in a form. Anything with markup
   of its own is a component and is styled next to that markup instead. */

/* Read by assistive technology, not drawn: a heading the bar above already
   shows, a label its field's placeholder makes obvious. The scripted form is
   hidden only once theme.js marks the document as scripted: a control script
   stands in for, shown without script. */
.visually-hidden,
html.js .visually-hidden-scripted {
  border: 0;
  clip-path: inset(50%);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

/* The other half: a control only script can drive, such as a field that
   narrows a list as it is typed in, is not drawn until theme.js marks the
   document as scripted. What it would drive works without it. */
html:not(.js) .scripted-only {
  display: none;
}

/* The mark on a disclosure's summary: a triangle made of borders, the solid side
   being the one it points away from. It is a primitive rather than a component's
   own rule because more than one component draws a details element — Fold, and
   the report queue's rows, whose summary is a grid and so cannot be Fold — and a
   scoped stylesheet cannot be shared. Logical properties only: it mirrors under
   dir="rtl" without a rule of its own, and the open state is read off the element
   the browser already marks rather than off each component's class. */
.disclosure-caret {
  block-size: 0;
  border-block: .3rem solid transparent;
  border-inline-start: .4rem solid var(--text-subtle);
  flex: none;
  inline-size: 0;
}

details[open] > summary .disclosure-caret {
  border-block-end: 0;
  border-block-start: .4rem solid var(--text-subtle);
  border-inline: .3rem solid transparent;
}

/* The label above a field. FormField writes it for an input, and a page
   writes it for a control that is not one — a picker, a group — so the two
   read alike. The uppercase treatment is shared by every form in the product. */
.field-label {
  color: var(--text-subtle);
  display: block;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: calc(.08em * var(--label-tracking));
  margin-bottom: .35rem;
  text-transform: uppercase;
}

/* The name of one part of a public page, set small above it rather than at a
   heading's size, whatever element carries it: a section's heading, a group's,
   a term in a list of facts. */
.section-label {
  color: var(--text-muted);
  font-size: .75rem;
  font-weight: 800;
  letter-spacing: calc(.08em * var(--label-tracking));
  line-height: 1.3;
  margin: 0;
  text-transform: uppercase;
}

/* What narrows a label down, such as the language a localized field holds.
   Every localized field says it, so switching language visibly rewrites all
   of them at once. */
.label-detail {
  color: var(--accent-text);
}

.field {
  background: var(--field-bg);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  color: var(--text);
  font: inherit;
  font-size: .95rem;
  padding: .55rem .7rem;
  width: 100%;
}

.field::placeholder {
  color: var(--text-subtle);
}

.field:focus {
  border-color: var(--accent);
  outline: 2px solid var(--accent);
  outline-offset: -1px;
}

/* A one-time code is read digit by digit off another device. Monospace with
   wide tracking is what makes a typo visible before the form is submitted. */
.field-code {
  font-family: var(--font-mono);
  font-size: 1.15rem;
  letter-spacing: .35em;
  text-align: center;
}

.btn {
  background: var(--surface-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  color: var(--text);
  cursor: pointer;
  display: inline-block;
  font: inherit;
  font-size: .92rem;
  font-weight: 600;
  padding: .55rem 1rem;
  text-align: center;
  text-decoration: none;
}

.btn:hover {
  background: var(--surface-high);
  text-decoration: none;
}

.btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-contrast);
}

.btn-primary:hover {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
}

/* A command that cannot be undone, such as deleting a record permanently.
   Outlined rather than filled, so it never outweighs the command beside it
   that keeps things as they are. */
.btn-danger {
  background: transparent;
  border-color: var(--danger);
  color: var(--danger-text);
}

.btn-danger:hover {
  background: var(--danger-soft);
}

.btn-block {
  width: 100%;
}

/* A command that belongs to the frame rather than to the screen, such as
   signing out. */
.btn-ghost {
  background: transparent;
  border-color: var(--border);
  color: var(--text-muted);
}

.btn-ghost:hover {
  background: var(--surface-raised);
  color: var(--text);
}

.btn-sm {
  font-size: .82rem;
  padding: .35rem .7rem;
}

/* A control of the bar that stands on the bar itself, with no frame until the
   pointer is on it: the language switcher's summary and the theme control.
   Its label is a mark, so the name it is missing on screen is carried by a
   visually-hidden span and a title. */
.btn-bare {
  align-items: center;
  background: transparent;
  border-color: transparent;
  border-radius: var(--radius-pill);
  color: var(--text-muted);
  display: inline-flex;
  gap: .3rem;
  justify-content: center;
  min-block-size: 2.1rem;
  min-inline-size: 2.1rem;
  padding: 0 .75rem;
}

.btn-bare:hover {
  background: var(--surface);
  color: var(--text);
}

/* A refused command still has to be read, so it loses its fill and keeps a
   readable label: fading the whole button far enough to look unavailable would
   take the text under the contrast floor. Transparent, so it recedes into
   whichever surface it sits on. After the variants and their hover states,
   which are no more specific, so it wins over them. */
.btn:disabled {
  background: transparent;
  border-color: var(--border);
  color: var(--text-muted);
  cursor: not-allowed;
}

/* EditForm writes this class on a field that failed validation, and renders the
   message through ValidationMessage. */
.field.invalid {
  border-color: var(--danger);
}

.validation-message {
  color: var(--danger-text);
  display: block;
  font-size: .84rem;
  margin-top: .35rem;
}

/* The action that ends a panel, and the message that is read before the form is
   used again — it sits above the fields, never under the button. Both are
   classes on an element the page writes, which is why they are here. */
.submit {
  margin-top: 1.4rem;
}

.alert-slot {
  margin-bottom: 1.2rem;
}

/* The popup of a combobox: the list of options, one option, and the line under
   it that says why there is no list. Here rather than beside a component
   because two of them write it — Components/Admin/Shared/Combobox.razor, whose
   options are in the page, and developer-picker.js, whose options arrive from
   DeveloperChoicesEndpoint and are therefore written by a script, which carries
   no component's scope. One skin, so the two cannot drift apart.

   The list opens under the field and in the flow of the page, pushing what
   follows down rather than covering it, and scrolls after a few rows as the
   other long lists on the screen do. */
.combobox-list {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  list-style: none;
  margin: .4rem 0 0;
  max-height: 15rem;
  overflow-y: auto;
  padding: .3rem;
}

.combobox-list[hidden],
.combobox-option[hidden],
.combobox-empty[hidden] {
  display: none;
}

.combobox-option {
  border-radius: var(--radius-sm);
  color: var(--text);
  cursor: pointer;
  font-size: .88rem;
  padding: .35rem .5rem;
}

.combobox-option:hover {
  background: var(--surface-raised);
}

/* The active option is the one Enter chooses. Focus stays in the field, so the
   list draws the ring the option would have had. */
.combobox-option[aria-selected="true"] {
  background: var(--surface-raised);
  color: var(--accent-text);
  font-weight: 700;
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.combobox-empty {
  color: var(--text-muted);
  font-size: .85rem;
  margin: .4rem 0 0;
}
