/*
 * ux-baseline.css — accessibility and touch-target floor for every page.
 *
 * Added 2026-08-09 after auditing the live UI against WCAG 2.2 AA and standard
 * mobile touch-target guidance. Measured failures this file fixes:
 *
 *   - No visible focus styles at all on /, /client/find.html,
 *     /photographers/login.html and /admin/panel — keyboard and switch users
 *     had no way to see where they were. (WCAG 2.4.7, and 2.4.11 in 2.2)
 *   - prefers-reduced-motion ignored on 6 of 7 pages.
 *   - Interactive controls under the 44x44 minimum on every page audited
 *     (landing 3, find 6, client gallery 7, photographer dashboard 14,
 *     admin 18).
 *   - Body copy below 16px in several places (client gallery had 19 instances
 *     as small as 13px).
 *
 * Load this FIRST, before page stylesheets, so pages can still override it.
 */

/* ---- [hidden] must actually hide ---------------------------------------- */
/*
 * The `hidden` attribute only sets `display:none` at user-agent level, so ANY
 * class that sets display (e.g. .pz-btn { display:inline-flex }) silently wins
 * and the element stays on screen. This bit the landing page: the "Find my
 * photos" confirm button rendered before a selfie had been chosen.
 */
[hidden] {
  display: none !important;
}

/* ---- Focus. Never remove an outline without replacing it. ---------------- */

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 3px solid #2563EB;
  outline-offset: 2px;
  border-radius: 4px;
}

/* Older engines without :focus-visible still get something. */
@supports not selector(:focus-visible) {
  :where(a, button, input, select, textarea, summary, [tabindex]):focus {
    outline: 3px solid #2563EB;
    outline-offset: 2px;
  }
}

/* On dark surfaces a blue ring can disappear; pair it with a light halo.
   `[data-theme="dark"]` is kept for the legacy pages that set it by hand, but
   it never fired on its own — nothing in the product sets that attribute. The
   media query is what actually carries dark now. */
.client-ui :where(a, button, input, select, textarea):focus-visible,
[data-theme="dark"] :where(a, button, input, select, textarea):focus-visible {
  outline-color: #93C5FD;
  box-shadow: 0 0 0 5px rgba(15, 23, 42, 0.45);
}
@media (prefers-color-scheme: dark) {
  :where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
    outline-color: #93C5FD;
    box-shadow: 0 0 0 5px rgba(0, 0, 0, 0.55);
  }
}

/* ---- Touch targets ------------------------------------------------------- */
/*
 * Applied to standalone controls only. Links inside a sentence are deliberately
 * excluded — stretching those to 44px breaks paragraph rhythm, and the
 * guideline targets discrete controls.
 */

button,
.btn,
[role="button"],
input[type="submit"],
input[type="button"],
input[type="reset"],
select,
.seg-btn,
.ph-tab,
.vnav-item {
  min-height: 44px;
  min-width: 44px;
}

/* Text inputs need the same comfortable hit area. */
input[type="text"],
input[type="email"],
input[type="tel"],
input[type="password"],
input[type="number"],
input[type="search"],
input[type="date"],
textarea {
  min-height: 44px;
}

/* File inputs are rendered by the browser and ignore min-height on the element
   itself; give the control room so the button part is reachable. */
input[type="file"] {
  min-height: 44px;
  padding: 10px 0;
}

/*
 * Small controls sitting inside a dense table row (the photographer gallery
 * manager) still need a 44px hit area, but making the button itself 44px would
 * wreck the row. Expand the hit area instead of the box.
 */
.table-action,
td button,
td .btn {
  position: relative;
}
.table-action::after,
td button::after,
td .btn::after {
  content: "";
  position: absolute;
  inset: 50% 0 0 0;
  transform: translateY(-50%);
  height: 44px;
  min-width: 44px;
}

/* ---- Type ---------------------------------------------------------------- */

/*
 * `clamp(16px, 1rem, 18px)` held a 16px floor and also imposed an 18px
 * CEILING — a reader who had set their phone's text size to 200% got 18px.
 * That silently defeated the whole point of a rem type scale. Apple's HIG
 * requires text to enlarge up to 200%; `max()` keeps the floor and removes
 * the ceiling.
 */
body {
  font-size: max(1rem, 16px);
  line-height: 1.5;
}

/* Anything that opts into "small" still stays legible. 12–13px body copy on a
   phone is below the readable floor. */
small,
.small,
.muted,
.hint,
.fine,
.status-message {
  font-size: 0.875rem;   /* 14px at default, and it grows with the reader */
}

/* Comfortable measure. 50–75 characters is the readable range; cap block text
   so wide desktop layouts don't run to 120+ characters per line. */
p,
li {
  max-width: 72ch;
}

/* ---- Motion -------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---- State that isn't carried by colour alone ---------------------------- */
/*
 * A disabled control with no explanation is a dead end — the user cannot tell
 * whether it is broken or whether they have missed a step.
 */
button[disabled],
input[disabled],
.btn[disabled] {
  cursor: not-allowed;
  /* 0.55 pulled a 7.6:1 label down to about 4.2:1, under the 4.5:1 floor the
     HIG sets for text up to 17pt. 0.7 keeps it readable and still reads as
     unavailable — and unavailability is carried by the cursor and the
     explanation too, never by the dimming alone. */
  opacity: 0.7;
}

/* Screen-reader-only helper for labels that must not be visible. */
.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;
}

/* Banner pointing photographers from the legacy dashboard to the new Studio.
   Lives in the baseline stylesheet because every legacy photographer page
   loads it. The old dashboard is not deleted: it is still the only home for
   operator tooling (contacts, provider status, campaign queues, flags). */
.pz-legacy-banner {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--pz-3); flex-wrap: wrap;
  margin: var(--pz-3) auto; max-width: 1100px;
  padding: var(--pz-3) var(--pz-4);
  border: 1px solid var(--pz-primary); border-radius: var(--pz-radius-lg);
  background: var(--pz-surface);
}
.pz-legacy-banner strong { display: block; font-size: var(--pz-text-base); }
.pz-legacy-banner span { font-size: var(--pz-text-sm); color: var(--pz-ink-muted); }
