/* The cloud card is a legibility requirement, not decoration — see spec 7.0.
   --ink measures 3.7:1 on the storm plate and 4.1:1 on dusk, both below AA.
   On the card it reaches ~10.5:1.

   A soft rounded rectangle, deliberately plain. Earlier versions wore
   scalloped bumps (read as a postage stamp), larger irregular ones (torn
   paper), and a real SVG cloud silhouette. The cloud looked right but its
   usable interior is only about 72% x 58% of its bounding box, so content
   spilled out of the lobes at every width between roughly 544px and 900px —
   and these sections carry the longest content on the site, the About Tara
   bio being two full paragraphs. The decoration is gone; the artwork does
   the work instead. */
.u-card {
  position: relative;
  background: var(--cloud-card);
  border-radius: var(--radius-card);
  /* Padding scales with the viewport. A fixed 3rem side padding ate 96px of a
     343px card on a phone, leaving 247px of content; this leaves 306px. */
  padding: clamp(1.25rem, 4vw, 1.75rem) clamp(1.1rem, 5vw, 3rem);
  /* width as well as max-width. With max-width alone, a centred grid item
     shrinks to fit its content, so short sections came out narrower than long
     ones — events at 617px and the footer at 478px against 736px elsewhere. */
  width: 100%;
  max-width: 46rem;
  filter: drop-shadow(0 3px 18px rgb(35 31 32 / 0.14));
}

/* The hero deliberately has NO card. An earlier version put one there and it
   went through three shapes — scalloped (read as a postage stamp), larger
   irregular scallops (torn paper), and a real SVG cloud silhouette. The cloud
   looked right on desktop but the title spilled outside its lobes at every
   width from about 544px to 900px, and worse, a white panel in the middle of
   an animated sky competes with the animation it is sitting on.
   The hero needs no card anyway: --ink on --sky-clear measures 6.63:1, which
   passes AA. Cards exist for the storm (3.71:1) and dusk (4.06:1) plates. */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--tap-min);
  padding: var(--space-xs) var(--space-m);
  font-family: var(--font-display);
  font-size: var(--step-1);
  color: var(--ink);
  background: var(--cloud-card);
  border: 2.5px solid var(--ink);
  border-radius: 999px;
  text-decoration: none;
  cursor: pointer;
  /* Sticker treatment: a hard offset shadow rather than a soft blur, and an
     overshoot easing so it springs rather than glides. */
  box-shadow: 3px 3px 0 var(--ink);
  transition: transform 140ms cubic-bezier(0.34, 1.56, 0.64, 1),
              box-shadow 140ms ease;
}

.btn:hover {
  transform: translate(-2px, -2px) rotate(-1.2deg);
  box-shadow: 6px 6px 0 var(--ink);
}
/* Touch has no hover, so the pressed state is the only tap confirmation. */
/* Presses flat into the page — the only tap confirmation touch users get. */
.btn:active {
  transform: translate(2px, 2px) rotate(0deg);
  box-shadow: 1px 1px 0 var(--ink);
}

/* --near-black, not --ink: --ink on --sky measures 4.40:1, and --step-1
   clamps down to 21.3px, which is below the 24px "large text" threshold. So
   it needs 4.5:1 and misses. --near-black on --sky is 6.82:1. Darkening the
   fill instead would have made it worse, the label being dark already. */
.btn--primary {
  background: var(--sky);
  border-color: var(--ink);
  color: var(--near-black);
}

/* Hidden until the reader is past the hero, then slides down.
   `visibility` is animated alongside `translate` on purpose: a bar that is
   merely translated off-screen still takes keyboard focus, so a Tab press
   would jump to links nobody can see. visibility:hidden removes it from the
   tab order until it is genuinely on screen. */
.site-nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
  padding: 0.6rem clamp(1rem, 4vw, 2.5rem);
  background: rgb(252 254 254 / 0.92);
  backdrop-filter: blur(8px);
  box-shadow: 0 1px 12px rgb(35 31 32 / 0.12);
  translate: 0 -100%;
  visibility: hidden;
  transition: translate 240ms ease, visibility 240ms;
}

:root.has-left-hero .site-nav {
  translate: 0 0;
  visibility: visible;
}

.site-nav__brand {
  font-family: var(--font-display);
  font-size: 1.15rem;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}

.site-nav__list {
  display: flex;
  align-items: center;
  gap: clamp(0.5rem, 1.6vw, 1.5rem);
  list-style: none;
  margin: 0;
  padding: 0;
}

.site-nav__list a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
  padding: 0 0.35rem;
  color: var(--ink);
  font-size: 0.95rem;
  text-decoration: none;
}

.site-nav__list a:hover {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* The nav CTA is a button, so it wears the button's language: hard offset
   shadow, chunky border, springs on hover and presses flat. */
.site-nav__cta {
  background: var(--sky);
  border: 2.5px solid var(--ink);
  border-radius: 999px;
  padding: 0 1rem !important;
  font-weight: 600;
  box-shadow: 3px 3px 0 var(--ink);
  transition: transform 140ms cubic-bezier(0.34, 1.56, 0.64, 1),
              box-shadow 140ms ease;
}

.site-nav__cta:hover {
  transform: translate(-2px, -2px) rotate(-1.2deg);
  box-shadow: 5px 5px 0 var(--ink);
  text-decoration: none;
}

.site-nav__cta:active {
  transform: translate(2px, 2px);
  box-shadow: 1px 1px 0 var(--ink);
}

/* The brand is the first thing to go when space runs out — the section
   links are what the bar is for. */
@media (max-width: 46rem) {
  .site-nav__brand { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .site-nav { transition: none; }
}

.signup { display: grid; gap: var(--space-xs); max-width: 30rem; }
.signup__label { font-weight: 600; }

.signup__input {
  min-height: var(--tap-min);
  padding: 0 var(--space-s);
  font: inherit;
  color: var(--ink);
  background: #fff;
  border: 2.5px solid var(--ink);
  border-radius: 0.75rem;
  /* Same offset shadow as the buttons, so the field reads as part of the same
     hand-made set rather than a default form control dropped in. */
  box-shadow: 3px 3px 0 var(--ink);
  transition: box-shadow 140ms ease, transform 140ms ease;
}

.signup__input:focus-visible {
  transform: translate(-1px, -1px);
  box-shadow: 5px 5px 0 var(--ink);
}

.signup__input:user-invalid {
  border-color: #B3261E;
  box-shadow: 3px 3px 0 #B3261E;
}

.signup__status:empty { display: none; }
.signup__status { font-weight: 600; }
.signup__status[data-state="error"] { color: #B3261E; }


/* ---- mobile navigation ---------------------------------------------------
   Below 46rem the row of links plus a floating CTA pill does not fit without
   crowding, so it collapses to a hamburger and a full-width dropdown. The CTA
   becomes a menu item like the rest rather than a pill competing with the
   toggle for the same corner. */
.site-nav__toggle { display: none; }

@media (max-width: 46rem) {
  .site-nav {
    flex-wrap: wrap;
    justify-content: flex-start;
    padding: 0.5rem 1rem;
  }

  .site-nav__brand { display: block; flex: 1; font-size: 1rem; }

  .site-nav__toggle {
    display: grid;
    place-items: center;
    width: var(--tap-min);
    height: var(--tap-min);
    margin-left: auto;
    background: none;
    border: 2px solid var(--ink);
    border-radius: 0.6rem;
    cursor: pointer;
  }

  .site-nav__bars,
  .site-nav__bars::before,
  .site-nav__bars::after {
    display: block;
    width: 20px;
    height: 2.5px;
    background: var(--ink);
    border-radius: 2px;
    transition: transform 200ms ease, opacity 150ms ease;
  }

  .site-nav__bars { position: relative; }
  .site-nav__bars::before,
  .site-nav__bars::after { content: ""; position: absolute; left: 0; }
  .site-nav__bars::before { top: -7px; }
  .site-nav__bars::after { top: 7px; }

  /* Morphs into a close X, so the control says what it will do next. */
  .site-nav.is-open .site-nav__bars { background: transparent; }
  .site-nav.is-open .site-nav__bars::before { transform: translateY(7px) rotate(45deg); }
  .site-nav.is-open .site-nav__bars::after { transform: translateY(-7px) rotate(-45deg); }

  /* visibility as well as max-height: a collapsed menu at height 0 still
     takes keyboard focus, so Tab would walk through invisible links. */
  .site-nav__list {
    flex-basis: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    overflow: hidden;
    max-height: 0;
    visibility: hidden;
    transition: max-height 260ms ease, visibility 260ms;
  }

  .site-nav.is-open .site-nav__list { max-height: 24rem; visibility: visible; }

  .site-nav__list li { border-top: 1px solid rgb(94 51 50 / 0.15); }

  .site-nav__list a {
    min-height: 52px;
    width: 100%;
    font-size: 1.05rem;
    padding: 0 0.25rem;
  }

  .site-nav__cta {
    background: none !important;
    border-radius: 0 !important;
    padding: 0 0.25rem !important;
    font-weight: 600;
  }
}

@media (prefers-reduced-motion: reduce) {
  .site-nav__list,
  .site-nav__bars,
  .site-nav__bars::before,
  .site-nav__bars::after { transition: none; }
}


/* Skip link — WCAG 2.4.1.
   Off-screen rather than display:none, because a hidden element cannot
   receive focus and the link would never be reachable. It returns to the
   page on :focus-visible only, so pointer users never see it. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 0.75rem 1.25rem;
  background: var(--paper, #fff);
  color: var(--near-black);
  font-family: var(--font-display);
  border: 2px solid var(--near-black);
  border-radius: 0 0 0.5rem 0;
  text-decoration: none;
}

.skip-link:focus-visible {
  left: 0;
  outline: 3px solid var(--sky);
  outline-offset: 2px;
}

/* The skip target must not draw its own focus ring when reached by the link —
   tabindex="-1" makes <main> focusable for that jump only. */
main:focus { outline: none; }
