/* Utilities: single-purpose classes the markup composes, after Fizzy's.
   They sit above the components in the cascade, so a utility on an
   element is the last word on that one property — no weight needed and
   none given: each selector here is one class. Measures come from the
   rhythm in _global.css (--block-space, --inline-space, --text-*), the
   colours from the palette. Components keep their own names and
   measures; reach for these where a one-off rule would otherwise be
   born. */
@layer utilities {

/* Text */
.txt-x-small { font-size: var(--text-x-small); }
.txt-small { font-size: var(--text-small); }
.txt-normal { font-size: var(--text-normal); }
.txt-medium { font-size: var(--text-medium); }
.txt-large { font-size: var(--text-large); }
.txt-x-large { font-size: var(--text-x-large); }

.txt-align-center { text-align: center; }
.txt-align-start { text-align: start; }
.txt-align-end { text-align: end; }

.txt-current { color: currentColor; }
.txt-ink { color: var(--ink); }
.txt-subtle { color: var(--ink-dim); }
.txt-gold { color: var(--gold); }
.txt-alert { color: var(--alert); }
.txt-reversed { color: var(--paper); }
.txt-fire { color: var(--fire); }
.txt-earth { color: var(--earth); }
.txt-air { color: var(--air); }
.txt-water { color: var(--water); }

.txt-undecorated { text-decoration: none; }
.txt-underline { text-decoration: underline; }
.txt-italic { font-style: italic; }
.txt-tight-lines { line-height: 1.2; }
.txt-nowrap { white-space: nowrap; }
.txt-balance { text-wrap: balance; }
.txt-break { word-break: break-word; }
.txt-uppercase { text-transform: uppercase; }
.txt-capitalize { text-transform: capitalize; }
.txt-tabular { font-variant-numeric: tabular-nums; }

.font-display { font-family: var(--font-display); }
.font-body { font-family: var(--font-body); }
.font-ui { font-family: var(--font-ui); }

.font-weight-normal { font-weight: 400; }
.font-weight-medium { font-weight: 500; }
.font-weight-semibold { font-weight: 600; }
.font-weight-bold { font-weight: 700; }

/* Flexbox and grid */
.justify-start { justify-content: start; }
.justify-end { justify-content: end; }
.justify-center { justify-content: center; }
.justify-space-between { justify-content: space-between; }

.align-start { align-items: start; }
.align-center { align-items: center; }
.align-end { align-items: end; }
.align-baseline { align-items: baseline; }

.align-self-start { align-self: start; }
.align-self-center { align-self: center; }
.align-self-end { align-self: end; }

.v-align-middle { vertical-align: middle; }

.display-inline { display: inline; }
.display-block { display: block; }

.flex { display: flex; }
.flex-inline { display: inline-flex; }
.flex-column { flex-direction: column; }
.flex-wrap { flex-wrap: wrap; }
.grid { display: grid; }

.flex-1 { flex: 1; }
.flex-item-grow { flex-grow: 1; }
.flex-item-shrink { flex-shrink: 1; }
.flex-item-no-shrink { flex-shrink: 0; }
.flex-item-justify-start { margin-inline-end: auto; }
.flex-item-justify-end { margin-inline-start: auto; }

.gap {
  column-gap: var(--column-gap, var(--inline-space));
  row-gap: var(--row-gap, var(--block-space));
}
.gap-half {
  column-gap: var(--column-gap, var(--inline-space-half));
  row-gap: var(--row-gap, var(--block-space-half));
}
.gap-double {
  column-gap: var(--column-gap, var(--inline-space-double));
  row-gap: var(--row-gap, var(--block-space-double));
}
.gap-none {
  --column-gap: 0;
  --row-gap: 0;
  gap: 0;
}

/* Sizing */
.full-width { inline-size: 100%; }
.half-width { inline-size: 50%; }
.max-width { max-inline-size: 100%; }
.min-width { min-inline-size: 0; }
.min-content { inline-size: min-content; }
.fit-content { inline-size: fit-content; }

/* Overflow */
.overflow-x { overflow-x: auto; scroll-snap-type: x mandatory; scroll-behavior: smooth; }
.overflow-y { overflow-y: auto; scroll-snap-type: y mandatory; scroll-behavior: smooth; }
.overflow-clip { text-overflow: clip; white-space: nowrap; overflow: hidden; }
.overflow-ellipsis { text-overflow: ellipsis; white-space: nowrap; overflow: hidden; }
.overflow-line-clamp {
  -webkit-line-clamp: var(--lines, 2);
  -webkit-box-orient: vertical;
  display: -webkit-box;
  overflow: hidden;
  text-overflow: clip;
  white-space: normal;
}

/* The pointer */
.non-clickable { cursor: default; pointer-events: none; }
.cursor-pointer { cursor: pointer; }

/* Padding */
.pad { padding: var(--block-space) var(--inline-space); }
.pad-double { padding: var(--block-space-double) var(--inline-space-double); }

.pad-block { padding-block: var(--block-space); }
.pad-block-start { padding-block-start: var(--block-space); }
.pad-block-end { padding-block-end: var(--block-space); }
.pad-block-half { padding-block: var(--block-space-half); }
.pad-block-start-half { padding-block-start: var(--block-space-half); }

.pad-inline { padding-inline: var(--inline-space); }
.pad-inline-start { padding-inline-start: var(--inline-space); }
.pad-inline-end { padding-inline-end: var(--inline-space); }
.pad-inline-half { padding-inline: var(--inline-space-half); }
.pad-inline-double { padding-inline: var(--inline-space-double); }

.unpad { padding: 0; }
.unpad-block-end { padding-block-end: 0; }
.unpad-inline { padding-inline: 0; }

/* Margins */
.margin { margin: var(--block-space) var(--inline-space); }
.margin-block { margin-block: var(--block-space); }
.margin-block-half { margin-block: var(--block-space-half); }
.margin-block-double { margin-block: var(--block-space-double); }
.margin-block-start { margin-block-start: var(--block-space); }
.margin-block-start-half { margin-block-start: var(--block-space-half); }
.margin-block-start-double { margin-block-start: var(--block-space-double); }
.margin-block-start-auto { margin-block-start: auto; }
.margin-block-end { margin-block-end: var(--block-space); }
.margin-block-end-half { margin-block-end: var(--block-space-half); }
.margin-block-end-double { margin-block-end: var(--block-space-double); }

.margin-inline { margin-inline: var(--inline-space); }
.margin-inline-half { margin-inline: var(--inline-space-half); }
.margin-inline-double { margin-inline: var(--inline-space-double); }
.margin-inline-start { margin-inline-start: var(--inline-space); }
.margin-inline-start-half { margin-inline-start: var(--inline-space-half); }
.margin-inline-end { margin-inline-end: var(--inline-space); }
.margin-inline-end-half { margin-inline-end: var(--inline-space-half); }

.margin-none { margin: 0; }
.margin-none-block { margin-block: 0; }
.margin-none-block-start { margin-block-start: 0; }
.margin-none-block-end { margin-block-end: 0; }
.margin-none-inline { margin-inline: 0; }
.margin-none-inline-start { margin-inline-start: 0; }
.margin-none-inline-end { margin-inline-end: 0; }

.center { margin-inline: auto; }
.center-block { margin-block: auto; }

/* Position */
.position-relative { position: relative; }
.position-sticky { position: sticky; inset: var(--inset, 0 auto auto auto); z-index: var(--z, 1); }

/* Fills, from the palette */
.fill { background-color: var(--paper); }
.fill-high { background-color: var(--paper-high); }
.fill-wash { background-color: var(--wash); }
.fill-dawn { background-color: var(--dawn); }
.fill-ink { background-color: var(--ink); }
.fill-transparent { background-color: transparent; }

.translucent { opacity: var(--opacity, 0.66); }

/* Borders */
.border { border: var(--border-size, 1px) var(--border-style, solid) var(--border-color, var(--line)); }
.border-block { border-block: var(--border-size, 1px) var(--border-style, solid) var(--border-color, var(--line)); }
.border-top { border-block-start: var(--border-size, 1px) var(--border-style, solid) var(--border-color, var(--line)); }
.border-bottom { border-block-end: var(--border-size, 1px) var(--border-style, solid) var(--border-color, var(--line)); }
.borderless { border: 0; }
.border-radius { border-radius: var(--border-radius, 12px); }

.shadow { box-shadow: var(--shadow); }

/* Lists */
:where(.list-style-none) { list-style: none; margin: 0 auto; padding: 0; }
:where(.list-unindented) { padding-inline-start: 1.25em; }

/* Accessibility: the house's name for it, and Fizzy's. */
.sr-only,
.for-screen-reader {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Visibility. The hidden attribute means it, whatever display a
   component gave the element; show-on-native's twin, hide-on-native, is
   native.css's. */
[hidden] { display: none !important; }

/* A wrapper that isn't there: pagination lists use it so stacked page
   frames sit as siblings of what they paginate. */
.display-contents { display: contents; }

body:not(.hotwire-native) .show-on-native { display: none; }

@media (any-hover: none) {
  .hide-on-touch { display: none; }
}
.show-on-touch { display: none; }
@media (any-hover: none) {
  .show-on-touch { display: unset; }
}

.hide-scrollbar {
  scrollbar-width: none;
  &::-webkit-scrollbar { display: none; }
}

@media (prefers-color-scheme: dark) {
  .hide-on-dark { display: none; }
}
@media (prefers-color-scheme: light) {
  .hide-on-light { display: none; }
}

}
