/* =========================================================================
   ListingLoom — base/reset + typography + layout primitives.
   Consumes tokens.css exclusively (var(--...)). Mobile-first: unprefixed
   rules are the mobile layout; min-width queries build upward (design.md
   Breakpoints). CSS logical properties are used throughout (hygiene per
   design.md RTL rules note, even though v1 ships English-only LTR).
   ========================================================================= */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--text-body-size);
  line-height: var(--text-body-line);
  font-weight: var(--text-body-weight);
  -webkit-font-smoothing: antialiased;
}

img,
svg {
  max-width: 100%;
  display: block;
}

a {
  color: inherit;
}

button {
  font-family: inherit;
}

/* Visible focus ring on every interactive element (design.md §3.4 a11y). Never
   remove outline without this replacement. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
[tabindex]:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
/* The focus ring follows each element's own border-radius automatically, so we
   must NOT force a radius here — a global radius (0,1,1) outranks .btn / .tag /
   .input class radii (0,1,0) and snapped pill buttons and rounded inputs to 6px
   corners the instant they were focused. Bare unstyled links have no radius of
   their own, so give the ring a small radius only for them. */
a:not([class]):focus-visible,
[tabindex]:not([class]):focus-visible {
  border-radius: var(--radius-xs);
}

/* Skip link for keyboard users */
.skip-link {
  position: absolute;
  inset-inline-start: var(--space-4);
  top: -100px;
  background: var(--color-surface);
  color: var(--color-text);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);
  z-index: 100;
  transition: top var(--duration-base) var(--easing-standard);
}
.skip-link:focus {
  top: var(--space-4);
}

/* Screen-reader-only utility (used for aria-live status text visible only to AT
   when no visible copy is specced, and for supplementary labels). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

h1,
h2,
h3,
h4 {
  margin: 0;
  font-family: var(--font-head);
  font-weight: var(--weight-semibold);
}

p {
  margin: 0;
}

.text-display {
  font-family: var(--font-head);
  font-size: var(--text-display-size);
  line-height: var(--text-display-line);
  font-weight: var(--text-display-weight);
  letter-spacing: -0.02em;
}
.text-h1 {
  font-family: var(--font-head);
  font-size: var(--text-h1-size);
  line-height: var(--text-h1-line);
  font-weight: var(--text-h1-weight);
  letter-spacing: -0.02em;
}
.text-h2 {
  font-family: var(--font-head);
  font-size: var(--text-h2-size);
  line-height: var(--text-h2-line);
  font-weight: var(--text-h2-weight);
  letter-spacing: -0.015em;
}
.text-h3 {
  font-family: var(--font-head);
  font-size: var(--text-h3-size);
  line-height: var(--text-h3-line);
  font-weight: var(--text-h3-weight);
  letter-spacing: -0.01em;
}
.text-lg {
  font-size: var(--text-lg-size);
  line-height: var(--text-lg-line);
  font-weight: var(--text-lg-weight);
}
/* .text-body is explicit rather than relying on the body{} default matching
   by coincidence — templates apply the class directly (e.g. "text-body
   text-muted") and a future change to the body{} base rule (dir/locale
   variants, etc.) must not silently change this role's rendered size/weight
   (F1 cycle-2 review minor). Values match design.md's text-body role exactly
   (16px/1.6/400), same as the body{} rule below in this file. */
.text-body {
  font-size: var(--text-body-size);
  line-height: var(--text-body-line);
  font-weight: var(--text-body-weight);
}
.text-body-strong {
  font-size: var(--text-body-strong-size);
  line-height: var(--text-body-strong-line);
  font-weight: var(--text-body-strong-weight);
}
.text-sm {
  font-size: var(--text-sm-size);
  line-height: var(--text-sm-line);
}
.text-sm-med {
  font-size: var(--text-sm-med-size);
  line-height: var(--text-sm-med-line);
  font-weight: var(--text-sm-med-weight);
}
.text-xs {
  font-size: var(--text-xs-size);
  line-height: var(--text-xs-line);
  font-weight: var(--text-xs-weight);
}
.text-mono-sm {
  font-family: var(--font-mono);
  font-size: var(--text-mono-sm-size);
  line-height: var(--text-mono-sm-line);
  font-weight: var(--text-mono-sm-weight);
}
.text-muted {
  color: var(--color-text-muted);
}
.text-strong {
  color: var(--color-text-strong);
}

/* ---- Layout primitives ---- */
.container {
  width: 100%;
  max-width: var(--content-max);
  margin-inline: auto;
  padding-inline: var(--space-4);
}
.container-narrow {
  width: 100%;
  max-width: var(--content-max-narrow);
  margin-inline: auto;
  padding-inline: var(--space-4);
}

.stack > * + * {
  margin-block-start: var(--space-4);
}
.stack-lg > * + * {
  margin-block-start: var(--space-8);
}

.visually-hide-below-md {
  display: none;
}
@media (min-width: 768px) {
  .visually-hide-below-md {
    display: initial;
  }
  .hide-above-md {
    display: none;
  }
}

/* ---- Section rhythm ---- */
.section {
  padding-block: var(--space-16);
}
@media (max-width: 767px) {
  .section {
    padding-block: var(--space-12);
  }
}

/* ---- Utility classes ----
   Replace one-off `style="..."` attributes so CSP's style-src can stay
   'self' (+ the Google Fonts stylesheet host) with no 'unsafe-inline' —
   every spacing/layout value below is a token already defined in tokens.css,
   not a new invented value. */
.u-mt-2 {
  margin-block-start: var(--space-2);
}
.u-mt-3 {
  margin-block-start: var(--space-3);
}
.u-mt-4 {
  margin-block-start: var(--space-4);
}
.u-mt-5 {
  margin-block-start: var(--space-5);
}
.u-mt-6 {
  margin-block-start: var(--space-6);
}
.u-mt-8 {
  margin-block-start: var(--space-8);
}
.u-pt-0 {
  padding-block-start: 0;
}
.u-pt-8 {
  padding-block-start: var(--space-8);
}
.u-pb-24 {
  padding-block-end: var(--space-24);
}
.u-text-center {
  text-align: center;
}
.u-hidden {
  /* !important: later same-specificity display rules (.banner { display: flex })
     must not re-show elements shipped hidden; JS toggles this class, never style.display */
  display: none !important;
}
.u-reading-measure {
  max-width: 70ch;
}
.u-fieldset-reset {
  border: none;
  padding: 0;
}
.u-actions-row {
  display: flex;
  gap: var(--space-3);
  justify-content: center;
  flex-wrap: wrap;
}
.u-actions-row--start {
  justify-content: flex-start;
}
.u-space-between {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
}
.u-list-indent {
  padding-inline-start: var(--space-5);
}
.u-mx-auto {
  margin-inline: auto;
}
.u-price-lg {
  font-size: var(--text-h1-size);
}
.u-width-0 {
  width: 0%;
}
.u-pre-wrap {
  white-space: pre-wrap;
}
.u-block {
  display: block;
}
