/* Buttons whose long labels wrap at enlarged text: the framework's fixed height becomes a minimum, which each page's own
   rule sets for its button size. :where() keeps this from outranking those rules. */
:where(.action-toolbar > a, .stats dd > .button.text, .csv-import a[download], .csv-export .page-header button,
       .file-field > label.button, .form-actions > :is(button, .button), .detail :is(.button, button):not(.icon-button, .circle, .chip)) {
  max-width: 100%; height: auto; white-space: normal;
}
/* Page actions end-align and wrap, and long labels wrap inside their buttons at enlarged text sizes. */
.action-toolbar { gap: 8px; }
.action-toolbar > a { min-height: 48px; padding-block: 0.5rem; }
.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; }
/* 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 surface role 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-surface); }
.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; }
/* App rings augment the framework's normal state layers on direct checkboxes and form radios. A checkbox followed
   by a span draws on that span instead of its hidden input. Keep the existing ring overrides in both schemes. */
: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, .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; }
  /* Retain the checkbox appearance override; 0.16.0 supports forced colors, but safe removal needs rendered checks. */
  :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 var(--md-sys-motion-duration-short4) ease-in 400ms; }
/* Stat tiles default to the lowest container; detail layouts override their own surface role. */
.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 { min-height: 48px; margin-inline-start: -16px; justify-content: flex-start; 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 { 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: relative; z-index: 2; padding: 12px 16px; container-type: scroll-state; }
/* It sticks only in a window at least 40em tall. Media query ems follow the browser's text size, so on a phone with
   enlarged text the bar stays at the form's end instead of covering a third of the screen. */
@media (height >= 40em) {
  .record-form > .form-actions { position: sticky; bottom: 0; }
}
/* 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. It takes the large corner of the framework's menus and
   selects. In dark the cards under it are surface-container-high, so the bar takes the next step up there. */
.record-form > .form-actions::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  border-radius: var(--md-sys-shape-corner-large) var(--md-sys-shape-corner-large) 0 0;
  background: light-dark(var(--md-sys-color-surface-container-high), var(--md-sys-color-surface-container-highest));
}
@container not scroll-state(stuck: bottom) {
  .record-form > .form-actions::before { border-radius: var(--md-sys-shape-corner-large); }
}
/* 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 (width < 600px) {
  .record-form > .form-actions { padding-inline: 12px; }
  .record-form > .form-actions > .button.text { padding-inline: 12px; }
  /* Wrapped upload actions can cover the focused file control; keep them in the document on Compact windows. */
  .record-form:has(.file-field-native-fallback) > .form-actions { position: relative; }
}
/* 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; }
/* Alerts take the cards' 24px side padding, and 16px below Medium as the cards do, so their icons line up with the
   cards' text. */
.settings-form .alert { --md-comp-alert-padding: 16px 24px; }
@media (width < 600px) {
  .settings-form .record-form-layout > section { padding: 16px; }
  .settings-form .alert { --md-comp-alert-padding: 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(--md-comp-filled-text-field-caret-color); }
.record-form .field.outlined.native-select:has(> select:disabled) > label { color: color-mix(in oklab, var(--md-sys-color-on-surface) 38%, transparent); }
/* In-page messages use the framework's alert: secondary by default and .critical for errors. Warnings take the tertiary
   tone and standing notes a neutral surface, through the alert's own tokens. Shared by the workspace and the public
   pickup and kiosk pages. */
.alert.tertiary { --md-comp-alert-container-color: var(--md-sys-color-tertiary-container); --md-comp-alert-color: var(--md-sys-color-on-tertiary-container); }
.alert.neutral { --md-comp-alert-container-color: var(--md-sys-color-surface-container-highest); --md-comp-alert-color: var(--md-sys-color-on-surface); }
/* The shared form layout's error summary (shared/form.html). Its 1rem corner matches the alert's large corner at the
   default text size, 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; }
}
/* Record/profile forms and check actions retain these system-control overrides. ExpressiveCSS 0.16.0 has explicit
   forced-colors rules for radios and both checkbox renderings; that source support alone does not verify removal. */
@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; }
  /* Retain the app's 3px Highlight ring at a 2px offset alongside the framework's forced-colors focus support. */
  :is(.record-form, .profile-form, .check-action-action) label > :is([type=radio], [type=checkbox]):focus-visible { outline: 3px solid Highlight; outline-offset: 2px; }
}
