.ua-layout-section {
  position: relative;
  display: grid;
  gap: clamp(1rem, 3vw, 2rem);
  min-width: 0;
}

.ua-layout-container {
  width: min(100%, 72rem);
  margin-inline: auto;
  min-width: 0;
}

.ua-layout-container-narrow {
  width: min(100%, 48rem);
}

.ua-layout-container-full {
  width: 100%;
}

.ua-layout-columns {
  display: grid;
  grid-template-columns: repeat(var(--ua-columns, 2), minmax(0, 1fr));
  gap: clamp(0.75rem, 2vw, 1.25rem);
  min-width: 0;
}

.ua-layout-columns[data-column-count="1"] { --ua-columns: 1; }
.ua-layout-columns[data-column-count="2"] { --ua-columns: 2; }
.ua-layout-columns[data-column-count="3"] { --ua-columns: 3; }
.ua-layout-columns[data-column-count="4"] { --ua-columns: 4; }
.ua-layout-columns[data-column-count="5"] { --ua-columns: 5; }
.ua-layout-columns[data-column-count="6"] { --ua-columns: 6; }

.ua-layout-divider {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-width: 0;
  border: 0;
  color: var(--universe-color-muted);
}

.ua-layout-divider::before,
.ua-layout-divider::after {
  content: "";
  flex: 1 1 auto;
  border-top: 1px solid var(--universe-line);
}

hr.ua-layout-divider {
  display: block;
  border-top: 1px solid var(--universe-line);
}

hr.ua-layout-divider::before,
hr.ua-layout-divider::after {
  content: none;
}

.ua-layout-spacer {
  block-size: clamp(1rem, 4vw, 3rem);
}

.ua-layout-spacer-sm { block-size: clamp(0.5rem, 2vw, 1rem); }
.ua-layout-spacer-lg { block-size: clamp(2rem, 7vw, 5rem); }

.ua-anchor {
  scroll-margin-block-start: 6rem;
}

/* The shared navigable-card capability (see navigableShell). Any card/tile whose whole region is a
   real <a href> carries .ua-navigable: it strips the default anchor chrome so the card keeps its own
   look, while preserving a visible keyboard focus ring for accessibility. Layout (grid/flex, padding)
   stays owned by the card's own class — this only neutralizes link styling and adds the focus state. */
.ua-navigable {
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  /* Touch: navigate on tap with no 300ms delay, and never let the browser swallow the tap as a gesture
     or text-selection (the whole-card anchor must fire reliably on mobile). */
  touch-action: manipulation;
  -webkit-tap-highlight-color: color-mix(in srgb, var(--universe-color-primary) 22%, transparent);
}
/* The card's own descriptive children are inert to pointer input so a tap anywhere on the card region
   resolves to the anchor itself (no inner span/heading/badge stealing the tap on touch). Real interactive
   descendants (links/buttons/inputs) re-enable themselves below. */
.ua-navigable > * { pointer-events: none; }
.ua-navigable a, .ua-navigable button, .ua-navigable input,
.ua-navigable select, .ua-navigable textarea, .ua-navigable [tabindex] { pointer-events: auto; }

.ua-navigable:focus-visible {
  outline: 0.15rem solid var(--universe-color-focus);
  outline-offset: 0.2rem;
}

.ua-background {
  position: relative;
  display: grid;
  min-width: 0;
}

.ua-icon {
  display: inline-grid;
  place-items: center;
  inline-size: 1.15em;
  block-size: 1.15em;
  line-height: 1;
}

.ua-icon svg {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  overflow: visible;
}

.ua-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-block-size: 2.5rem;
  border: 1px solid var(--universe-line);
  border-radius: var(--universe-radius-control, 0.35rem);
  padding: 0.65rem 0.9rem;
  text-decoration: none;
  color: var(--universe-color-text);
  background: color-mix(in srgb, var(--universe-color-surface) 82%, transparent);
  box-shadow: 0 0.65rem 1.8rem color-mix(in srgb, var(--universe-color-background) 22%, transparent);
  font-weight: 800;
  line-height: 1.05;
  transition: border-color 140ms ease, background-color 140ms ease, color 140ms ease, box-shadow 140ms ease, transform 140ms ease;
}

.ua-button.ua-fill,
.ua-button-fill,
.ua-action-fill {
  width: 100%;
  inline-size: 100%;
}

.ua-button-primary {
  color: var(--universe-color-background);
  background: var(--universe-color-primary);
  border-color: var(--universe-color-primary);
  box-shadow: 0 0.75rem 2rem color-mix(in srgb, var(--universe-color-primary) 28%, transparent);
}

.ua-button-secondary {
  color: var(--universe-color-text);
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--universe-color-primary) 14%, transparent), transparent),
    color-mix(in srgb, var(--universe-color-surface) 88%, var(--universe-color-text) 4%);
  border-color: color-mix(in srgb, var(--universe-color-primary) 48%, var(--universe-line));
}

.ua-button-ghost {
  color: var(--universe-color-primary-strong, var(--universe-color-primary));
  background: color-mix(in srgb, var(--universe-color-background) 18%, transparent);
  border-color: color-mix(in srgb, var(--universe-color-primary) 34%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--universe-color-primary) 10%, transparent);
}

.ua-button:hover,
.ua-button:focus-visible {
  border-color: var(--universe-color-primary-strong, var(--universe-color-primary));
  box-shadow: 0 0.85rem 2.3rem color-mix(in srgb, var(--universe-color-primary) 24%, transparent);
}

.ua-button:focus-visible {
  outline: 0.15rem solid var(--universe-color-focus);
  outline-offset: 0.15rem;
}

.ua-button:active {
  transform: translateY(0.04rem);
}

/* Glass is the default button material: seamless, cool, modern — the brand
   colour only tints and accents it, never fills it. On dashboards and shared
   surfaces the brand colour resolves to the Universe gold; a tenant's brand
   colour flows in automatically through --universe-color-primary. */
.ua-button-glass {
  color: var(--universe-color-text);
  background: color-mix(in srgb, var(--universe-color-primary) 9%, color-mix(in srgb, var(--universe-color-text) 6%, transparent));
  border-color: color-mix(in srgb, var(--universe-color-primary) 20%, var(--universe-line));
  box-shadow: none;
  backdrop-filter: blur(0.7rem) saturate(1.04);
}

.ua-button-glass:hover,
.ua-button-glass:focus-visible {
  color: var(--universe-color-text);
  background: color-mix(in srgb, var(--universe-color-primary) 18%, color-mix(in srgb, var(--universe-color-text) 9%, transparent));
  border-color: color-mix(in srgb, var(--universe-color-primary) 44%, var(--universe-line));
  box-shadow: 0 0.5rem 1.5rem color-mix(in srgb, var(--universe-color-primary) 16%, transparent);
}

.ua-header-description,
.ua-footer-description,
.ua-waitlist-subtext {
  display: grid;
  gap: 0.45rem;
}

.ua-header-description > *,
.ua-footer-description > *,
.ua-waitlist-subtext > * {
  margin-block: 0;
}

.ua-button-icon {
  display: inline-grid;
  place-items: center;
  flex: 0 0 auto;
  inline-size: 1.15em;
  block-size: 1.15em;
  color: currentColor;
}

.ua-button-icon svg {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  overflow: visible;
}

.ua-button.ua-button-icon {
  inline-size: 2.5rem;
  min-inline-size: 2.5rem;
  block-size: 2.5rem;
  min-block-size: 2.5rem;
  padding-inline: 0;
  border-radius: 999rem;
}

/* Shared "working" state — one platform-wide pending affordance keyed on the semantic aria-busy
   attribute. Any button/[role=button] (and .ua-button) whose aria-busy is set gets a centered spinner,
   its label hidden, pointer events off. Reaches both the shared element and bespoke buttons (e.g. the
   accounts login actions) because this foundation stylesheet is inlined everywhere. rem/em units only. */
@keyframes ua-busy-spin { to { transform: rotate(360deg); } }

button[aria-busy="true"],
[role="button"][aria-busy="true"],
.ua-button[aria-busy="true"] {
  position: relative;
  pointer-events: none;
  cursor: progress;
  color: transparent !important;            /* hides bare-text labels (e.g. accounts "Continue") */
}
button[aria-busy="true"] > *,
[role="button"][aria-busy="true"] > *,
.ua-button[aria-busy="true"] > * { visibility: hidden; }   /* hides wrapped icon+label spans (ua.button) */

button[aria-busy="true"]::after,
[role="button"][aria-busy="true"]::after,
.ua-button[aria-busy="true"]::after {
  content: "";
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  inline-size: 1.15em; block-size: 1.15em;
  margin-block-start: -0.575em; margin-inline-start: -0.575em;
  border-radius: 999rem;
  border: 0.14em solid color-mix(in srgb, var(--ua-busy-ink, var(--universe-color-text)) 26%, transparent);
  border-block-start-color: var(--ua-busy-ink, var(--universe-color-text));
  animation: ua-busy-spin 0.7s linear infinite;
}
.ua-button-primary[aria-busy="true"] { --ua-busy-ink: var(--universe-color-background); }  /* dark spinner on primary */

@media (prefers-reduced-motion: reduce) {
  button[aria-busy="true"]::after,
  [role="button"][aria-busy="true"]::after,
  .ua-button[aria-busy="true"]::after {
    animation: none;                          /* static ring, still clearly "working" */
    border-color: color-mix(in srgb, var(--ua-busy-ink, var(--universe-color-text)) 45%, transparent);
    border-block-start-color: var(--ua-busy-ink, var(--universe-color-text));
  }
}

/* Quiet route-progress hairline — the "it's working" cue for NAVIGATION (in-app fragment swaps + full
   page navigations). A 2px (0.125rem) brand-toned line pinned to the top edge of the viewport. It is
   the counterpart to the in-control aria-busy spinner: actions get the in-button spinner, navigations
   get this thin top line. It is NOT a scrim — it never covers the page, never dims the art, never
   blocks input (pointer-events:none). The controller (ua.interaction-feedback client) only reveals it
   after a ~120ms threshold, so an instant action never flashes it. rem/em units only. */
.ua-route-progress {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 0.125rem;
  z-index: 2147483645;                        /* above chrome, below a dialog overlay */
  transform: scaleX(0);
  transform-origin: 0 50%;
  opacity: 0;
  pointer-events: none;                        /* never blocks input — it is a cue, not a scrim */
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--universe-color-primary) 35%, transparent),
    var(--universe-color-primary));
  transition: opacity 0.18s ease;
}
.ua-route-progress[data-ua-route-progress="active"] {
  opacity: 1;
  animation: ua-route-progress-indeterminate 1.4s ease-in-out infinite;
}
.ua-route-progress[data-ua-route-progress="done"] {
  opacity: 0;
  transform: scaleX(1);                        /* snap to full, then fade out */
  animation: none;
  transition: opacity 0.34s ease, transform 0.2s ease;
}
@keyframes ua-route-progress-indeterminate {
  0%   { transform: scaleX(0); }
  55%  { transform: scaleX(0.7); }
  100% { transform: scaleX(0.92); }
}
@media (prefers-reduced-motion: reduce) {
  /* No indeterminate slide under reduced motion — a simple, steady state instead (still clearly "working"). */
  .ua-route-progress[data-ua-route-progress="active"] {
    animation: none;
    transform: scaleX(1);
    opacity: 0.85;
  }
  .ua-route-progress[data-ua-route-progress="done"] {
    transition: opacity 0.2s ease;
  }
}

.ua-skip-navigation {
  position: fixed;
  inset-block-start: 0.75rem;
  inset-inline-start: 0.75rem;
  z-index: 9999;
  transform: translateY(-150%);
  transition: transform var(--ua-motion-micro) var(--ua-motion-ease-soft);
}

.ua-skip-navigation:focus {
  transform: translateY(0);
}

.ua-lazy-container {
  content-visibility: auto;
  contain-intrinsic-size: 1px 24rem;
}

.ua-cookie-blocker {
  display: grid;
  gap: 0.75rem;
  border: 1px solid var(--universe-line);
  border-radius: var(--universe-radius-card, 0.5rem);
  padding: 1rem;
  background: color-mix(in srgb, var(--universe-color-surface) 88%, transparent);
}

.ua-shadow-soft { box-shadow: 0 0.45rem 1.2rem color-mix(in srgb, var(--universe-color-background) 18%, transparent); }
.ua-shadow-panel { box-shadow: var(--universe-shadow-panel); }
.ua-shadow-strong { box-shadow: 0 1.5rem 4rem color-mix(in srgb, var(--universe-color-background) 42%, transparent); }
/* ── THE FOUNDATION MOTION CLASSES, ON TOKENS (D035 / MP-086) ────────────────
   These used to spell 140ms / 180ms / 220ms inline and were then switched off
   by a `@media (prefers-reduced-motion: reduce) { animation: none !important }`
   kill list further down this file. That shape is advisory: it protects the
   classes somebody remembered to add to the list, and silently fails for the
   next one. It also had a real bug — the kill list forced `transform: none` on
   `.ua-skip-navigation`, which parks the skip link ON SCREEN for exactly the
   people most likely to be using it.

   Now every time here is var(--ua-motion-*), and those tokens are 0ms under
   prefers-reduced-motion (element-runtime.css). Instant, still functional,
   nothing to remember. The kill list is gone because there is nothing left for
   it to kill. */
.ua-transition-subtle { transition: transform var(--ua-motion-micro) var(--ua-motion-ease-soft), opacity var(--ua-motion-micro) var(--ua-motion-ease-soft), box-shadow var(--ua-motion-micro) var(--ua-motion-ease-soft); }
.ua-transition-smooth { transition: transform var(--ua-motion-base) var(--ua-motion-ease-soft), opacity var(--ua-motion-base) var(--ua-motion-ease-soft), box-shadow var(--ua-motion-base) var(--ua-motion-ease-soft); }
.ua-enter-fade { animation: ua-enter-fade var(--ua-motion-fast) var(--ua-motion-ease-soft) both; }
.ua-enter-rise { animation: ua-enter-rise var(--ua-motion-fast) var(--ua-motion-ease-soft) both; }
.ua-enter-scale { animation: ua-enter-scale var(--ua-motion-fast) var(--ua-motion-ease-soft) both; }
/* A hover state has no duration of its own to zero, so these two are the one
   case that still needs the query — and they are written the other way round:
   the motion EXISTS only under no-preference rather than being added and then
   revoked. */
@media (prefers-reduced-motion: no-preference) {
  .ua-hover-lift:hover { transform: translateY(-0.08rem); }
  .ua-hover-glow:hover { box-shadow: 0 0 0 0.18rem color-mix(in srgb, var(--universe-color-primary) 26%, transparent); }
}
.ua-fill { width: 100%; inline-size: 100%; }
.ua-align-start { align-self: start; justify-self: start; }
.ua-align-center { align-self: center; justify-self: center; }
.ua-align-end { align-self: end; justify-self: end; }
.ua-align-stretch { align-self: stretch; justify-self: stretch; }
.ua-justify-start { justify-content: flex-start; justify-items: start; }
.ua-justify-center { justify-content: center; justify-items: center; }
.ua-justify-end { justify-content: flex-end; justify-items: end; }
.ua-justify-between { justify-content: space-between; }
.ua-text-left { text-align: left; }
.ua-text-center { text-align: center; }
.ua-text-right { text-align: right; }
.ua-text-balance { text-wrap: balance; }
.ua-grid-row {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(0.75rem, 2vw, 1.25rem);
  align-items: stretch;
  min-width: 0;
}
.ua-grid-row > * { grid-column: 1 / -1; min-width: 0; }
.ua-grid-continue { min-width: 0; }
.ua-col-full { grid-column: 1 / -1; }
.ua-col-1 { grid-column: span 1; }
.ua-col-2 { grid-column: span 2; }
.ua-col-3 { grid-column: span 3; }
.ua-col-4 { grid-column: span 4; }
.ua-col-5 { grid-column: span 5; }
.ua-col-6 { grid-column: span 6; }
.ua-col-7 { grid-column: span 7; }
.ua-col-8 { grid-column: span 8; }
.ua-col-9 { grid-column: span 9; }
.ua-col-10 { grid-column: span 10; }
.ua-col-11 { grid-column: span 11; }
.ua-col-12 { grid-column: 1 / -1; }
.ua-p-0 { padding: 0; }
.ua-p-1 { padding: 0.5rem; }
.ua-p-2 { padding: 0.85rem; }
.ua-p-3 { padding: 1.15rem; }
.ua-p-4 { padding: 1.6rem; }
.ua-px-3 { padding-inline: 1.15rem; }
.ua-py-3 { padding-block: 1.15rem; }
.ua-m-0 { margin: 0; }
.ua-my-2 { margin-block: 0.85rem; }
.ua-mx-auto { margin-inline: auto; }
.ua-text-display { font-size: clamp(2rem, 5vw, 4.5rem); line-height: 0.98; font-weight: 900; }
.ua-text-heading { font-size: clamp(1.35rem, 3vw, 2.25rem); line-height: 1.05; font-weight: 880; }
.ua-text-body { font-size: var(--universe-font-size-base, 1rem); line-height: var(--universe-font-line-height-body, 1.5); }
.ua-text-small { font-size: 0.875rem; line-height: 1.42; }
.ua-text-emphasis { font-weight: 880; color: var(--universe-color-primary-strong); }
.ua-border { border: 1px solid var(--universe-line); }
.ua-border-none { border: 0; }
.ua-border-top { border-block-start: 1px solid var(--universe-line); }
.ua-border-right { border-inline-end: 1px solid var(--universe-line); }
.ua-border-bottom { border-block-end: 1px solid var(--universe-line); }
.ua-border-left { border-inline-start: 1px solid var(--universe-line); }
.ua-border-gradient {
  border: 1px solid transparent;
  background:
    linear-gradient(var(--universe-color-surface), var(--universe-color-surface)) padding-box,
    linear-gradient(135deg, var(--universe-color-primary-strong), color-mix(in srgb, var(--universe-color-primary) 18%, transparent), var(--universe-color-focus)) border-box;
}
.ua-rounded-none { border-radius: 0; }
.ua-rounded { border-radius: var(--universe-radius-card, 0.5rem); }
.ua-rounded-pill { border-radius: 999rem; }
.ua-bg-none { background: transparent; }
.ua-bg-surface { background: var(--universe-color-surface); }
.ua-bg-soft { background: color-mix(in srgb, var(--universe-color-surface) 76%, transparent); }
.ua-bg-primary-soft { background: color-mix(in srgb, var(--universe-color-primary) 18%, transparent); }
.ua-bg-success-soft { background: color-mix(in srgb, var(--universe-color-success) 16%, transparent); }
.ua-bg-danger-soft { background: color-mix(in srgb, var(--universe-color-danger) 16%, transparent); }
.ua-opacity-75 { opacity: 0.75; }
.ua-opacity-50 { opacity: 0.5; }

@keyframes ua-enter-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes ua-enter-rise {
  from { opacity: 0; transform: translateY(0.35rem); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes ua-enter-scale {
  from { opacity: 0; transform: scale(0.985); }
  to { opacity: 1; transform: scale(1); }
}

@media (max-width: 42rem) {
  .ua-layout-columns {
    grid-template-columns: 1fr;
  }
  .ua-col-mobile-1 { grid-column: span 1; }
  .ua-col-mobile-2 { grid-column: span 2; }
  .ua-col-mobile-3 { grid-column: span 3; }
  .ua-col-mobile-4 { grid-column: span 4; }
  .ua-col-mobile-5 { grid-column: span 5; }
  .ua-col-mobile-6 { grid-column: span 6; }
  .ua-col-mobile-7 { grid-column: span 7; }
  .ua-col-mobile-8 { grid-column: span 8; }
  .ua-col-mobile-9 { grid-column: span 9; }
  .ua-col-mobile-10 { grid-column: span 10; }
  .ua-col-mobile-11 { grid-column: span 11; }
  .ua-col-mobile-12 { grid-column: 1 / -1; }
}

@media (min-width: 42.01rem) {
  .ua-col-tablet-1 { grid-column: span 1; }
  .ua-col-tablet-2 { grid-column: span 2; }
  .ua-col-tablet-3 { grid-column: span 3; }
  .ua-col-tablet-4 { grid-column: span 4; }
  .ua-col-tablet-5 { grid-column: span 5; }
  .ua-col-tablet-6 { grid-column: span 6; }
  .ua-col-tablet-7 { grid-column: span 7; }
  .ua-col-tablet-8 { grid-column: span 8; }
  .ua-col-tablet-9 { grid-column: span 9; }
  .ua-col-tablet-10 { grid-column: span 10; }
  .ua-col-tablet-11 { grid-column: span 11; }
  .ua-col-tablet-12 { grid-column: 1 / -1; }
}

@media (min-width: 64rem) {
  .ua-col-desktop-1 { grid-column: span 1; }
  .ua-col-desktop-2 { grid-column: span 2; }
  .ua-col-desktop-3 { grid-column: span 3; }
  .ua-col-desktop-4 { grid-column: span 4; }
  .ua-col-desktop-5 { grid-column: span 5; }
  .ua-col-desktop-6 { grid-column: span 6; }
  .ua-col-desktop-7 { grid-column: span 7; }
  .ua-col-desktop-8 { grid-column: span 8; }
  .ua-col-desktop-9 { grid-column: span 9; }
  .ua-col-desktop-10 { grid-column: span 10; }
  .ua-col-desktop-11 { grid-column: span 11; }
  .ua-col-desktop-12 { grid-column: 1 / -1; }
}

/* The reduced-motion kill list that used to sit here is DELETED, not moved.
   Every class it named now takes its timing from a motion token, and those
   tokens are 0ms under prefers-reduced-motion — so the motion is already gone
   before this block would have run. A kill list is a list somebody has to keep
   up to date; a token that reads zero is not. (It also carried a bug: forcing
   `transform: none` on .ua-skip-navigation parked the skip link on screen for
   the very people most likely to be using it.) */
