/* Page actions end-align and wrap, and long labels wrap inside their buttons at enlarged text sizes. */
.action-toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; max-width: 100%; }
.action-toolbar > a { max-width: 100%; height: auto; min-height: 48px; padding-block: 0.5rem; white-space: normal; }
.action-toolbar > a > span:last-child { min-width: 0; overflow-wrap: anywhere; }
.skip-link { position: fixed; top: 0.5rem; inset-inline-start: 0.5rem; z-index: 1000; transform: translateY(-200%); }
.skip-link:focus { transform: none; }
/* Material's extra-small corner (4dp) for every text field; the framework default is 1rem. */
.field { --md-comp-filled-text-field-container-shape: 0.25rem; }
/* A native select in a field keeps its label above the control, including at enlarged text sizes. */
.field.native-select { display: flex; flex-direction: column; gap: 8px; }
.field.native-select > label { position: static; order: -1; transform: none; color: var(--md-sys-color-on-surface-variant); }
/* The outlined field's floated label paints the page background to cut its edge; above the control it would show as a
   strip on a card. */
.field.outlined.native-select > label { background: none; }
/* In a record form the label floats on the select's outline instead, as a text field's does, so a select paired with
   a text field starts on the same line. dashboard.css places a select's floated label. Record form labels keep to one
   line. Its value keeps the framework select's body-large type, which the inherited font below would replace. */
.record-form .field.native-select { display: block; }
.record-form .field.native-select > label { position: absolute; }
.record-form .field.outlined.native-select > label { background-color: var(--md-sys-color-background); }
.field.native-select > select { width: 100%; min-height: max(56px, calc(1.5em + 24px)); height: auto; padding-block: 12px; text-overflow: ellipsis; }
.field.native-select:not(.record-form *) > select { font: inherit; }
.field.native-select > select, .field.native-select > select::picker(select) { appearance: auto; }
/* In a record form a native select's height grows with the text size, as a text field's 3.5rem does, leaving room under
   the floated label. ExpressiveCSS has no field height token: 3.5rem is the framework select's 56px, and 24px is its
   block padding twice. */
.record-form .field.native-select > select { min-height: max(3.5rem, calc(1.5em + 24px)); }
/* The rules below are defaults wrapped in :where(), so a page's own rule for the same control wins. */
/* Contact details, such as the receipt's business address, read as plain text; browsers italicize an address. */
:where(address) { font-style: normal; }
/* The framework marks checkbox focus with a faint tint only, so keyboard focus gets the same ring as buttons.
   A checkbox followed by a span is hidden and drawn on the span, so the ring would land on nothing. A radio in a form's
   label draws no focus at all, so it takes the ring too. */
:where(:is(label:has(> [type="checkbox"]):not(.switch), .checkbox) > [type="checkbox"]:not(:has(+ span)):focus-visible) { outline: 3px solid var(--md-sys-color-secondary); outline-offset: 2px; }
:where(:is(.record-form, .profile-form, .check-action-action) label > [type="radio"]:focus-visible) { outline: 3px solid var(--md-sys-color-secondary); outline-offset: 2px; }
@media (forced-colors: active) {
  /* Forced colors removes the background that draws a filled, tonal, or elevated button, so give it an edge.
     Menus, app bars, the rail, and toolbars restyle plain buttons without a container, so those stay unboxed. */
  :where(:is(button:not(.datepicker-day-button, .date-picker-day-button, .month-prev, .month-next, .chip, .icon-button), a.button, label.button, .toolbar > a.filled):not(.text, .outlined, menu *, .bar *, .navigation-rail *, .toolbar > :not(.filled))) { border: 1px solid ButtonText; }
  :where(button:disabled) { border-color: GrayText; }
  /* The framework paints the checkbox and its tick with background colors, which forced colors also removes. */
  :where(:is(label:has(> [type="checkbox"]):not(.switch), .checkbox) > [type="checkbox"]) { appearance: auto; }
  :where(:is(label:has(> [type="checkbox"]):not(.switch), .checkbox))::before { display: none; }
}
/* The request indicator sits on the window's top edge. It appears only after 400ms, so quick swaps and polling
   don't flash it, and it leaves the accessibility tree while no request is running. */
#request-progress { position: fixed; inset: 0 0 auto; z-index: 1000; width: 100%; margin: 0; }
#request-progress:not(.htmx-request) { visibility: hidden; }
#request-progress.htmx-request { transition: opacity 200ms ease-in 400ms; }
/* Key figures sit on the lowest container, like the other content regions on the surface-container window. */
.stats { --md-comp-stat-container-color: var(--md-sys-color-surface-container-lowest); }
.stats dt > .material-symbols { margin-inline-end: 8px; font-size: 1.25rem; vertical-align: -0.25rem; }
/* A stat tile's link lines up with the figure above it, past the text button's 16px leading padding, and wraps at
   enlarged text inside its 48px target with the arrow after the label. */
.stats dd > .button.text { height: auto; min-height: 48px; margin-inline-start: -16px; justify-content: flex-start; white-space: normal; text-align: start; }
/* Directory tables sit flat on their card: no outline or corner, the card's surface, and Material's row dividers.
   Cells keep vertical padding because rows hold several lines. */
.table-scroll.data-table { --md-comp-data-table-container-color: transparent; --md-comp-data-table-shape: 0; margin-block: 0; border: 0; }
.table-scroll.data-table :is(th, td) { padding-block: 12px; }
/* A row menu's trigger sits at the end of its cell, after the identity text. */
.row-menu-trigger { flex-shrink: 0; margin-inline-start: auto; }
/* Long record forms keep Save in reach: the action row sticks to the window's bottom edge on a raised tone, and the
   scroll padding keeps a focused field from landing behind it. */
.record-form > .form-actions { position: sticky; bottom: 0; z-index: 2; padding: 12px 16px; container-type: scroll-state; }
/* The bar's fill is drawn on ::before, because a scroll-state query can style the container's pseudo-elements but not
   the container. Its bottom corners are square while it sticks to the window's edge and round once the form ends.
   A browser without scroll-state queries keeps them square. ExpressiveCSS has no shape token for the bar, so it takes the
   16px corner of the framework's menus and selects. */
.record-form > .form-actions::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  border-radius: 16px 16px 0 0; background: var(--md-sys-color-surface-container-high);
}
@container not scroll-state(stuck: bottom) {
  .record-form > .form-actions::before { border-radius: 16px; }
}
/* Forced colors paints the bar's fill as the page's Canvas, so an edge shows where fields scroll under it. */
@media (forced-colors: active) {
  .record-form > .form-actions::before { border: 1px solid CanvasText; }
}
html:has(.record-form > .form-actions) { scroll-padding-block-end: 6rem; }
/* Discard and Save share one row down to 360px: buttons in a group sit 8px apart, and on Compact windows the row and
   its text button use M3's 12px padding. */
.record-form > .form-actions { gap: 8px; }
@media (max-width: 599px) {
  .record-form > .form-actions { padding-inline: 12px; }
  .record-form > .form-actions > .button.text { padding-inline: 12px; }
}
/* A form of a few fields keeps a readable line length on wide windows instead of stretching its pairs across the pane.
   ExpressiveCSS has no measure token, so it takes the 42rem of the .account-form panels some of these pages stack
   below it. */
.record-form-short { max-width: 42rem; }
/* The settings layout (shared/settings.html): settings stack in one readable column; fields pair up whenever two fit, at any window size or text size. */
.settings-form { max-width: 56rem; }
.settings-form .record-form-fields { grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr)); }
.settings-form .record-form-layout { grid-template-columns: minmax(0, 1fr); }
.settings-form fieldset { margin: 0; }
/* A choice group paired with a field starts level with it, without a nested group's top margin (dashboard.css). */
.settings-form .record-form-fields > fieldset { margin-top: 0; }
/* A reader gets headed sections instead of fieldsets, painted as the editor's cards (dashboard.css), with the legend's
   space under the title. A switch and the field it governs sit closer than unrelated rows. */
.settings-form .record-form-layout > section { padding: 24px; border-radius: 24px; background-color: var(--md-sys-color-surface-container-lowest); }
.settings-form section > h2 { margin: 0 0 16px; }
.settings-form fieldset > label:has(> [type="checkbox"]) + .field { margin-top: 0.5rem; }
/* Below Medium the cards' padding drops to 16px, and the notices follow so their icons line up with the cards' text. */
@media (max-width: 599px) {
  .settings-form .record-form-layout > section { padding: 16px; }
  .settings-form .notice { padding-inline: 16px; }
}
/* An outlined native select sits beside outlined text fields, so it takes their clear container and corner through the
   select's tokens, and their error edge and label color, which ExpressiveCSS gives only to inputs. The pickup
   checkout's time select does the same in pickup.css. A record form's select that JavaScript would enhance looks the
   same until it does, or for good without JavaScript; enhancement moves it out of the field. */
:is(.field.outlined.native-select, .record-form .field.outlined) > select {
  --md-comp-filled-select-container-color: transparent;
  --md-comp-filled-select-container-shape: var(--md-comp-filled-text-field-container-shape);
}
/* The enhanced select's trigger takes the field's corner, which the framework sets to 16px on the field itself. Its
   menu keeps the framework's corner. */
.record-form .field:has(> .hide-select) { --md-comp-filled-select-container-shape: var(--md-comp-filled-text-field-container-shape); }
.field.outlined.native-select > select[aria-invalid="true"] { border-color: var(--md-sys-color-error); }
.field.outlined.native-select:has(> select[aria-invalid="true"]) > label { color: var(--md-sys-color-error); }
/* A record form's floated select label follows the text field's states: the framework's focus color, unless the select
   is invalid, and the framework's 38% on-surface when it is disabled. */
.record-form .field.outlined.native-select:has(> select:focus:not([aria-invalid="true"])) > label { color: var(--input-color); }
.record-form .field.outlined.native-select:has(> select:disabled) > label { color: color-mix(in oklab, var(--md-sys-color-on-surface) 38%, transparent); }
/* Inline notices, shared by the workspace and the public pickup and kiosk pages. */
.notice { display: flex; align-items: center; gap: 0.75rem; padding: 1rem 1.5rem; border-radius: 1rem; }
.notice > .material-symbols { flex: none; }
/* The shared form layout's error summary (shared/form.html). ExpressiveCSS has no shape token, so its corner is the
   notice's 1rem, and its padding is the record-form fieldset's 16px, 24px from Medium, so its text lines up with the
   sections below. Each link keeps the container's text color and a 48px target, since the list is how a returned form
   reaches each wrong field. The summary and its links take the app's 3px secondary focus ring. */
.form-errors { padding: 16px; border-radius: 1rem; }
@media (min-width: 600px) {
  .form-errors { padding: 24px; }
}
.form-errors:focus-visible, .form-errors a:focus-visible { outline: 3px solid var(--md-sys-color-secondary); outline-offset: 2px; }
.form-errors a { display: inline-flex; align-items: center; min-height: 48px; color: inherit; text-decoration: underline; overflow-wrap: anywhere; }
/* Forced colors drops the container's fill, so an edge keeps the summary apart from the form below it. */
@media (forced-colors: active) {
  .form-errors { border: 1px solid CanvasText; }
}
/* ExpressiveCSS draws a checked radio's dot as a background image and a checked box as a fill with a masked mark, and
   forced colors drops all three, so checked and unchecked look alike. Record forms fall back to the system controls,
   which forced colors draws. The Personal info card's forms and the check action pages' forms do the same. */
@media (forced-colors: active) {
  :is(.record-form, .profile-form, .check-action-action) label:has(> [type=radio]) > [type=radio],
  :is(.record-form, .profile-form) label:has(> [type=checkbox]):not(.switch) > [type=checkbox] { appearance: auto; }
  :is(.record-form, .profile-form) label:has(> [type=checkbox]):not(.switch)::before { content: none; }
  /* The framework marks focus with a state layer, which forced colors also drops, so focus takes the app's 3px ring at
     a 2px offset, as above; ExpressiveCSS has no focus ring width or offset token. */
  :is(.record-form, .profile-form, .check-action-action) label > :is([type=radio], [type=checkbox]):focus-visible { outline: 3px solid Highlight; outline-offset: 2px; }
}
