/* ===== Cross-document view transitions =====
   Every navigation here is a real page load (only the home listings tabs do
   a fetch-swap). Without this the browser tears down the old document and
   paints a blank frame before the new one arrives, which is what makes
   clicking through feel like a hard reload no matter how smooth the CSS is.

   `navigation: auto` lets the browser hold the outgoing frame and crossfade
   into the incoming one. It is pure progressive enhancement: unsupported
   browsers (Firefox at time of writing) simply navigate as before, and it
   changes nothing about how pages are requested or rendered.

   Must stay at the top level of the stylesheet -- @view-transition is
   ignored inside any nesting. */
@view-transition {
  navigation: auto;
}

/* Give the chrome its own transition identity so it is treated as the *same*
   element either side of a navigation and stays put, instead of being
   crossfaded out and back in with the rest of the page. Holding the nav and
   footer steady while only the content changes is what separates "an app
   moved between views" from "the page reloaded". */
.nav {
  view-transition-name: site-nav;
}
.footer {
  view-transition-name: site-footer;
}

/* Pace the crossfade from the shared motion scale rather than the browser
   default, and let the outgoing frame clear before the incoming one lands so
   the two never double-expose into a muddy blend. */
::view-transition-old(root) {
  animation: vt-fade-out var(--dur-fast) var(--ease-out) both;
}
::view-transition-new(root) {
  animation: vt-fade-in var(--dur-base) var(--ease-out) both;
}
/* The persistent chrome should not fade at all -- any opacity change on it
   reintroduces exactly the flicker this is meant to remove. */
::view-transition-old(site-nav),
::view-transition-new(site-nav),
::view-transition-old(site-footer),
::view-transition-new(site-footer) {
  animation: none;
  mix-blend-mode: normal;
}

@keyframes vt-fade-out {
  to {
    opacity: 0;
  }
}
@keyframes vt-fade-in {
  from {
    opacity: 0;
    /* A few pixels of travel gives the new view a direction of arrival.
       Kept tiny -- the page renders at 0.8333 zoom, and anything larger
       reads as a slide rather than a settle. */
    transform: translateY(4px);
  }
}

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

/* Mouse-only interaction: drop the browser's default focus ring (it shows as a
   pale outline around circular icon buttons/links on click). Keyboard focus
   (:focus-visible) keeps a visible ring for accessibility. */
a:focus:not(:focus-visible),
button:focus:not(:focus-visible),
summary:focus:not(:focus-visible) {
  outline: none;
}

/* Once a pointer has been used (JS adds .pointer-active on first pointerdown),
   suppress focus outlines anywhere and for any element — no white box on click
   or hover, on any page. Tab-key focus is unaffected. */
.pointer-active :focus {
  outline: none;
}

html {
  -webkit-text-size-adjust: 100%;
  /* Global density scale (0.8333 = bar 72px -> 50px). See DEVIATIONS.md. */
  zoom: 83.3333%;
}

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.6;
  color: var(--text-body);
  background: var(--surface);
}

h1, h2, h3, h4 {
  color: var(--text-primary);
  margin: 0;
  line-height: 1.2;
}

p {
  margin: 0 0 1rem;
}

a {
  color: var(--brand-primary);
  text-decoration: none;
}

a:hover {
  color: var(--brand-primary-hover);
}

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

input,
select,
textarea,
button {
  font-family: inherit;
  font-size: inherit;
}

.container {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 0 24px;
}

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border-radius: var(--radius-pill);
  border: none;
  cursor: pointer;
  padding: 14px 24px;
  font-weight: 600;
  font-size: 17px;
  text-decoration: none;
  transition: background var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out),
    transform var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-fast) var(--ease-out);
}

/* Tactile press: the button dips slightly and the shadow tightens, which
   confirms the click landed even before the page responds. Scale rather
   than translate so the shape stays centred on its own baseline. */
.btn:active {
  transform: scale(0.97);
}

.btn-primary {
  background: var(--brand-primary);
  color: #fff;
}
.btn-primary:hover {
  background: var(--brand-primary-hover);
  color: #fff;
}
.btn-muted {
  background: var(--brand-primary-muted);
  color: #fff;
}
.btn-muted:hover {
  background: var(--brand-primary-hover);
  color: #fff;
}
.btn-ghost {
  background: var(--surface);
  color: var(--text-primary);
  border: 1px solid var(--border);
}
.btn-ghost:hover {
  border-color: var(--border);
  background: var(--surface-subtle);
}

/* Forms */
.field {
  margin-bottom: 20px;
}
.field-label {
  display: block;
  font-size: 15px;
  font-weight: 500;
  line-height: 1.4;
  color: var(--text-primary);
  margin-bottom: 8px;
}
.field-label .req {
  color: var(--danger);
}
.input,
.select,
.textarea {
  width: 100%;
  background: var(--surface-input);
  border: none;
  border-radius: var(--radius-input);
  padding: 14px;
  font-size: 16px;
  color: var(--text-primary);
}
.textarea {
  resize: vertical;
  min-height: 120px;
}
.input:focus,
.select:focus,
.textarea:focus {
  outline: 2px solid var(--brand-primary);
  outline-offset: 1px;
}
.field-error {
  color: var(--danger);
  font-size: 14px;
  margin-top: 6px;
}

.select {
  appearance: none;
  cursor: pointer;
}

/* Pill filter buttons / checkbox pills */
.pill-group {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.pill-option {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 10px 18px;
  cursor: pointer;
  font-size: 15px;
  color: var(--text-primary);
  user-select: none;
}
.pill-option input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.pill-option .box {
  width: 18px;
  height: 18px;
  border-radius: 4px;
  border: 1.5px solid var(--text-muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  transition: background var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out);
}
.pill-option .box svg {
  width: 12px;
  height: 12px;
  stroke: #fff;
  visibility: hidden;
}
.pill-option input:checked + .box {
  background: var(--brand-primary);
  border-color: var(--brand-primary);
}
.pill-option input:checked + .box svg {
  visibility: visible;
}
.pill-option:has(input:checked) {
  background: var(--surface-subtle);
  border-color: var(--brand-primary);
}
.pill-option input:focus-visible ~ .box {
  outline: 2px solid var(--brand-primary);
  outline-offset: 2px;
}

/* Dropdown filter (pill-shaped select on listings) */
.filter-select {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 10px 36px 10px 18px;
  font-size: 15px;
  font-weight: 500;
  color: var(--text-primary);
  appearance: none;
  cursor: pointer;
  position: relative;
}

/* Dropzone */
.dropzone {
  background: var(--surface-input);
  border-radius: var(--radius-input);
  min-height: 120px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: 2px solid transparent;
  cursor: pointer;
  padding: 20px;
  text-align: center;
  transition: border-color var(--dur-base) var(--ease-out),
    background var(--dur-base) var(--ease-out);
  position: relative;
}
.dropzone.dragover {
  border: 2px dashed var(--brand-primary);
}
.dropzone .dz-icon {
  width: 24px;
  height: 24px;
  color: var(--text-muted);
}
.dropzone .dz-label {
  font-size: 16px;
  color: var(--text-muted);
}
.dropzone .dz-hint {
  font-size: 14px;
  color: var(--text-muted);
}
.dropzone.has-file .dz-file {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
}
.dropzone .remove-file {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--text-muted);
  font-size: 18px;
  line-height: 1;
}
.dropzone input[type="file"] {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
}

/* Skip-link */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--brand-primary);
  color: #fff;
  padding: 10px 16px;
  z-index: 1000;
}
.skip-link:focus {
  left: 0;
}

/* ===== Reduced motion =====
   Site-wide honouring of the OS "reduce motion" setting. Movement can
   trigger nausea and dizziness for people with vestibular disorders, so
   every transition and animation collapses to effectively nothing rather
   than merely being shortened. Colour and shadow changes still apply, so
   hover and focus states stay just as legible -- only the movement goes.
   Near-zero rather than `none` so transitionend/animationend listeners
   still fire and JS that waits on them does not stall. */
@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;
  }
  /* Suppress the movement itself, not just its duration. */
  .teacher-card:hover,
  .school-card:hover,
  .teacher-card:focus-visible,
  .school-card:focus-visible,
  .btn:active {
    transform: none;
  }
  /* View transitions animate in the pseudo-element tree, which the blanket
     rule above does not reach on every engine. Drop the travel outright and
     leave a bare opacity change, so navigation still reads as a change of
     view without anything sliding. */
  ::view-transition-new(root) {
    animation: none;
  }
  ::view-transition-old(root) {
    animation: none;
  }
}
