/* NOON Pink — v2

   One page, one job: sell a US$43 ticket to people arriving from Instagram
   on a phone.

   The structural idea is a persistent buy rail. On desktop the story scrolls
   in the left column while the ticket card stays put on the right, so nobody
   ever has to scroll back to buy. On mobile the same card sits directly under
   the hero, then a bottom bar takes over.

   Type per docs/brand/noon-pink-presentation-style-guide.md — Playfair
   Display for voice (its italic doing the work of the brush script), Inter
   for every fact and control. Palette per the brand guidelines: cream
   canvas, pink at 25-30%, gold under 5% and never as text on cream. */

:root {
  --cream: #f7e9db;
  --cream-deep: #efdcc7;
  --paper: #fffaf5;
  --white: #fff;

  --pink: #f5a9c4;
  --pink-soft: #fce8f0;
  --hibiscus: #e1559b;
  --berry: #a93a72;

  --ink: #16110f;
  --ink-soft: #241c19;
  --ink-line: rgba(255, 250, 245, 0.14);

  --gold: #c9a24b;
  --gold-light: #e8c97a;

  --muted: #6b5f5a;
  --rule: rgba(22, 17, 15, 0.16);
  --hair: rgba(22, 17, 15, 0.09);

  --rail: 26rem;
  --page: 84rem;
  --measure: 34rem;

  --track: 0.28em;
  --cta-track: 0.13em;

  --display: "Playfair Display", "Iowan Old Style", Georgia, serif;
  --body: "Inter", "Helvetica Neue", system-ui, Arial, sans-serif;
}

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: 1.5rem;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  color: var(--ink);
  background: var(--cream);
  font-family: var(--body);
  font-size: 1.0625rem;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}

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

a {
  color: inherit;
  text-underline-offset: 0.2em;
}

[hidden] {
  display: none !important;
}

:focus-visible {
  outline: 2px solid var(--berry);
  outline-offset: 3px;
}

.on-ink :focus-visible {
  outline-color: var(--gold-light);
}

.skip-link {
  position: fixed;
  top: 0.6rem;
  left: 0.6rem;
  z-index: 200;
  padding: 0.75rem 1rem;
  color: var(--paper);
  background: var(--ink);
  font-weight: 600;
  transform: translateY(-200%);
}

.skip-link:focus {
  transform: none;
}

/* ---------- Type ---------- */

h1,
h2,
h3,
p {
  margin: 0;
}

h1,
h2,
h3 {
  font-family: var(--display);
  font-weight: 700;
  letter-spacing: -0.022em;
  line-height: 1.02;
}

h1 {
  font-size: clamp(3rem, 12vw, 6.5rem);
}

h2 {
  font-size: clamp(2.1rem, 6vw, 3.6rem);
}

h3 {
  font-size: clamp(1.15rem, 2.6vw, 1.4rem);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.01em;
}

em {
  font-style: italic;
  font-weight: 500;
}

/* The campaign's script register, in type. */
.script {
  display: block;
  color: var(--berry);
  font-family: var(--display);
  font-size: clamp(1.5rem, 4vw, 2.2rem);
  font-style: italic;
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1.15;
}

.kicker {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  color: var(--berry);
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: var(--track);
  text-transform: uppercase;
}

.kicker::before {
  flex: 0 0 auto;
  width: 1.75rem;
  height: 1px;
  background: var(--gold);
  content: "";
}

.on-ink .kicker {
  color: var(--gold);
}

.lede {
  max-width: var(--measure);
  color: var(--muted);
  font-size: clamp(1.02rem, 1.5vw, 1.15rem);
}

.on-ink .lede {
  color: rgba(255, 250, 245, 0.72);
}

.fine {
  color: var(--muted);
  font-size: 0.78rem;
  line-height: 1.55;
}

.on-ink .fine {
  color: rgba(255, 250, 245, 0.74);
}

/* ---------- Controls ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  min-height: 3.4rem;
  padding: 0.9rem 1.6rem;
  border: 1px solid transparent;
  border-radius: 2px;
  font-family: var(--body);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: var(--cta-track);
  text-align: center;
  text-decoration: none;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color 160ms ease, color 160ms ease, transform 160ms ease;
}

.btn:hover {
  transform: translateY(-1px);
}

.btn--primary {
  width: 100%;
  color: var(--cream);
  background: var(--berry);
}

.btn--primary:hover {
  background: var(--ink);
}

.btn--ink {
  color: var(--paper);
  background: var(--ink);
}

.btn--ink:hover {
  background: var(--berry);
}

.btn--quiet {
  color: var(--ink);
  background: transparent;
  border-color: var(--rule);
}

.btn--quiet:hover {
  background: var(--paper);
}

.link {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  color: var(--berry);
  font-size: 0.85rem;
  font-weight: 500;
}

/* Links sitting inside a sentence (the hero script line, the rail aside)
   get their target from the line box rather than a min-height, which would
   break the sentence. Padding keeps them thumb-sized without doing that. */
.script a,
.ticket__aside a {
  /* Tap target without inflating the line box: the negative margin gives
     back the height the padding adds, so wrapped sentences keep their
     normal leading. */
  display: inline-block;
  padding-block: 0.75rem;
  margin-block: -0.75rem;
}

.on-ink .link {
  color: var(--gold-light);
}

/* ---------- Masthead ---------- */

.nb {
  white-space: nowrap;
}

.masthead {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.3rem 1rem;
  padding: 0.55rem 1rem;
  color: var(--ink);
  background: rgba(245, 169, 196, 0.55);
  border-bottom: 1px solid rgba(169, 58, 114, 0.2);
  font-size: 0.63rem;
  font-weight: 500;
  letter-spacing: var(--track);
  text-align: center;
  text-transform: uppercase;
}

.masthead b {
  color: var(--berry);
  font-weight: 600;
}

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  width: min(100% - 2rem, var(--page));
  padding-block: 0.9rem;
  margin-inline: auto;
}

.topbar {
  position: relative;
  z-index: 2;
}

.topbar img {
  /* The flat single-colour mark holds its shape at masthead size. */
  width: auto;
  height: 3.4rem;
}

.topnav {
  display: none;
  gap: 1.6rem;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

.topnav a {
  text-decoration: none;
}

.topnav a:hover {
  color: var(--berry);
}

/* ---------- Hero ----------
   hero-model-wide.webp is composed for exactly this: model and trunk in the
   left third, watercolour ground and copy space across the right. So the art
   is the hero's background and the copy sits in the space left for it. */

.hero {
  position: relative;
  padding-top: 1.5rem;
}

/* Mobile: copy first, then the art in normal flow. */
.hero__art img {
  display: block;
  width: 100%;
  height: auto;
}

.hero__copy {
  display: grid;
  gap: 1rem;
  width: min(100% - 2rem, var(--page));
  margin-inline: auto;
}

/* The cabanas hero text needs the same internal rhythm the home hero
   gets from .hero__copy — the global heading reset leaves it with none. */
.hero__text {
  display: grid;
  gap: 1rem;
}

.hero h1 {
  /* Big, and allowed to be big. */
  font-size: clamp(3.2rem, 13vw, 7rem);
  line-height: 0.98;
}

/* "dressed in pink" is, in fact, pink. Hibiscus holds 3.4:1 on cream,
   comfortably past the 3:1 large-text line at this size. */
.hero h1 em {
  color: var(--hibiscus);
}

.hero .lede {
  max-width: 30rem;
}

.hero__buy {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.1rem;
}

.hero__buy .btn {
  flex: 0 0 auto;
  width: auto;
}

.hero__price {
  color: var(--muted);
  font-size: 0.84rem;
}

.hero__price b {
  color: var(--ink);
  font-weight: 600;
}

/* The five facts, as a rule-bounded strip rather than pills. */
.facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 0;
  margin: 0;
  padding: 0.8rem 0;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  list-style: none;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

.facts li {
  display: flex;
  align-items: center;
  white-space: nowrap;
}

/* Leading and glued to its item (the masthead pattern): when the row
   wraps, the separator travels with the item instead of dangling at a
   line end. */
.facts li:not(:first-child)::before {
  width: 3px;
  height: 3px;
  margin-inline: 1.1rem;
  background: var(--gold);
  border-radius: 50%;
  content: "";
}

/* ---------- Shell: story + persistent buy rail ---------- */

.shell {
  display: grid;
  gap: 2.5rem;
  width: min(100% - 2rem, var(--page));
  margin: 0 auto;
  padding-block: 2.5rem 4rem;
}

.story {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(3.5rem, 7vw, 6rem);
  min-width: 0;
}

.rail {
  min-width: 0;
}

/* ---------- The ticket card ---------- */

.ticket {
  background: var(--paper);
  border: 1px solid rgba(169, 58, 114, 0.18);
  border-top: 3px solid var(--gold);
  box-shadow: 0 24px 60px -34px rgba(169, 58, 114, 0.5);
}

.ticket__head {
  padding: 1.5rem 1.4rem 1.25rem;
  border-bottom: 1px solid var(--hair);
}

.ticket__tier {
  display: block;
  color: var(--berry);
  font-size: 0.64rem;
  font-weight: 600;
  letter-spacing: var(--track);
  text-transform: uppercase;
}

.ticket__price {
  display: block;
  margin-top: 0.5rem;
  font-family: var(--display);
  font-size: clamp(2.1rem, 5vw, 2.7rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1;
}

.ticket__until {
  margin-top: 0.6rem;
  color: var(--berry);
  font-size: 0.74rem;
  font-weight: 500;
}

.ticket__body {
  padding: 1.25rem 1.4rem 1.5rem;
}

.ticket__includes {
  display: grid;
  gap: 0;
  margin: 0 0 1.25rem;
  padding: 0;
  list-style: none;
}

.ticket__includes li {
  padding: 0.6rem 0 0.6rem 1.5rem;
  border-bottom: 1px solid var(--hair);
  font-size: 0.86rem;
  line-height: 1.5;
  text-indent: -1.5rem;
}

.ticket__includes li::before {
  display: inline-block;
  width: 1.5rem;
  color: var(--gold);
  content: "\2014";
  text-indent: 0;
}

.ticket__includes strong {
  font-weight: 600;
}

/* Checkout mount. The widget renders Party Passport's own UI in an iframe
   and accepts two colours, so the card supplies the frame and the iframe
   supplies the mechanics. */
.checkout {
  margin-top: 0.25rem;
}

/* When the iframe is live it brings its own card, padding and ground —
   wrapper chrome here just double-frames it. */

.checkout [data-checkout-frame]:empty {
  display: none;
}

.checkout iframe {
  display: block;
  width: 100%;
  border: 0;
}

.ticket__note {
  margin-top: 0.9rem;
  color: var(--muted);
  font-size: 0.72rem;
  line-height: 1.5;
}

.ticket__aside {
  margin-top: 0.9rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--hair);
  font-size: 0.78rem;
}

.ticket__aside a {
  color: var(--berry);
  font-weight: 500;
}

/* ---------- Story blocks ---------- */

.block {
  display: grid;
  gap: 1.1rem;
  min-width: 0;
}

.block__head {
  /* No rule here: the kicker's gold dash marks the section start, and the
     story column's own gap does the separating. Two lines was one too many. */
  display: grid;
  gap: 0.85rem;
}

/* Photography goes edge to edge within the story column rather than
   sitting politely inside a grid cell. */
.plates {
  display: grid;
  gap: 0.5rem;
  grid-template-columns: repeat(2, 1fr);
}

.plates figure {
  margin: 0;
}

.plates img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
}

.plates figure:first-child {
  grid-column: 1 / -1;
}

.plates figure:first-child img {
  aspect-ratio: 3 / 2;
}

.plates figcaption {
  padding-top: 0.5rem;
  color: var(--muted);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* One pull quote per page, sized to actually land. */
.quote {
  margin: 0;
  padding: clamp(1.75rem, 4vw, 2.75rem) 0;
  border-top: 1px solid var(--gold);
  border-bottom: 1px solid var(--gold);
  text-align: center;
}

.quote blockquote {
  max-width: 20ch;
  margin: 0 auto;
  font-family: var(--display);
  font-size: clamp(1.7rem, 5vw, 2.9rem);
  font-style: italic;
  font-weight: 500;
  letter-spacing: -0.015em;
  line-height: 1.14;
}

.quote cite {
  display: block;
  margin-top: 1.1rem;
  color: var(--berry);
  font-size: 0.65rem;
  font-style: normal;
  font-weight: 600;
  letter-spacing: var(--track);
  text-transform: uppercase;
}

.quote cite span {
  display: block;
  margin-top: 0.35rem;
  color: var(--muted);
  font-weight: 400;
  letter-spacing: 0.1em;
  text-transform: none;
}

/* Guests in their own photographs, quotes over a gradient — the
   testimonial treatment from the April page. */
.voices {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 6px;
  margin-top: 1.5rem;
}

.voice {
  position: relative;
  overflow: hidden;
  min-height: 20rem;
  margin: 0;
  background: var(--berry);
}

.voice img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 20%;
  transition: transform 0.6s ease;
}

.voice:hover img {
  transform: scale(1.04);
}

.voice figcaption {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 1.2rem;
  background: linear-gradient(
    to top,
    rgba(22, 17, 15, 0.88) 0%,
    rgba(22, 17, 15, 0.35) 55%,
    rgba(22, 17, 15, 0) 100%
  );
}

.voice blockquote {
  margin: 0 0 0.5rem;
  color: var(--paper);
  font-family: var(--display);
  font-size: 1.02rem;
  font-style: italic;
  line-height: 1.4;
}

.voice--wide blockquote {
  font-size: clamp(1.2rem, 2.4vw, 1.5rem);
}

.voice cite {
  color: var(--gold-light);
  font-size: 0.63rem;
  font-style: normal;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}

.voice cite span {
  display: block;
  margin-top: 0.2rem;
  color: rgba(255, 250, 245, 0.85);
  font-weight: 400;
  letter-spacing: 0.06em;
  text-transform: none;
}

@media (min-width: 36rem) {
  .voices {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .voice--wide {
    grid-column: span 2;
    min-height: 24rem;
  }
}

/* Numbered index, hairline-separated. */
.index {
  display: grid;
  gap: 0;
  margin: 0;
  padding: clamp(1.25rem, 3vw, 2rem);
  background: var(--pink);
  list-style: none;
}

.index li {
  display: grid;
  gap: 0.3rem 1.75rem;
  padding: 1.15rem 0;
  border-bottom: 1px solid rgba(22, 17, 15, 0.16);
}

.index li:last-child {
  border-bottom: 0;
}

.index p {
  color: var(--muted);
  font-size: 0.93rem;
}

/* The day: the numbered index paired with the pour artwork. */
.day {
  display: grid;
  gap: 1rem;
}

.day__art {
  display: flex;
  flex-direction: column;
  margin: 0;
}

.day__art img {
  flex: 1;
  width: 100%;
  min-height: 0;
  object-fit: cover;
}

.day__art figcaption {
  padding-top: 0.55rem;
  color: var(--muted);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: var(--track);
  text-transform: uppercase;
}

@media (min-width: 48rem) {
  .day {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
    align-items: stretch;
  }

  /* Half a column wide here, so the two-column li template from 36rem
     would crush the paragraph. Stack instead. */
  .day .index li {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* The flyer, framed like a print piece with the share ask beside it. */
.flyer {
  display: grid;
  gap: 1.5rem;
}

.flyer__art {
  max-width: 21rem;
  margin: 0;
}

.flyer__art img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid rgba(169, 58, 114, 0.18);
  box-shadow: 0 24px 60px -34px rgba(169, 58, 114, 0.5);
}

.flyer__actions {
  display: grid;
  gap: 0.8rem;
  align-content: center;
  justify-items: start;
}

@media (min-width: 48rem) {
  .flyer {
    /* A fixed art column and a fluid actions column: at wide viewports the
       flyer grows instead of leaving a dead zone beside the button. */
    grid-template-columns: minmax(0, 26rem) minmax(0, 1fr);
    align-items: center;
  }

  .flyer__art {
    max-width: none;
  }

  .flyer__actions {
    max-width: 30rem;
  }
}

/* Pink band */
.band {
  padding: clamp(2rem, 5vw, 3rem) 1.4rem;
  background: var(--pink);
}

.band > div {
  display: grid;
  gap: 0.85rem;
  min-width: 0;
}

/* Sized against the viewport but rendered in a part-column, so cap it. */
.band h2 {
  font-size: clamp(1.9rem, 5vw, 2.4rem);
}

.band .lede {
  color: rgba(22, 17, 15, 0.76);
}

/* Berry reaches only 3.21:1 on Bloom Pink. Ink is the readable accent here. */
.band .kicker {
  color: var(--ink);
}

.band__mark {
  color: var(--berry);
  font-family: var(--display);
  font-size: clamp(3.5rem, 13vw, 6rem);
  font-style: italic;
  font-weight: 500;
  line-height: 0.9;
}

/* The commitment, as an editorial centerpiece on a hibiscus ground:
   the awareness ribbon in paper, the figure set large. Ink holds 5:1
   on hibiscus; paper only clears the large-text line, so it's reserved
   for the figure. */
.commitment {
  margin: 0;
  padding: clamp(1.8rem, 4.5vw, 2.6rem) 1.25rem;
  background: var(--hibiscus);
  text-align: center;
}

.commitment__ribbon {
  width: 1.9rem;
  height: auto;
  margin-bottom: 0.9rem;
  color: var(--paper);
}

.commitment small {
  display: block;
  color: var(--ink);
  font-size: 0.67rem;
  font-weight: 700;
  letter-spacing: var(--track);
  text-transform: uppercase;
}

.commitment b {
  display: block;
  margin-top: 0.45rem;
  color: var(--paper);
  font-family: var(--display);
  font-size: clamp(2.3rem, 6.5vw, 3.4rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1;
}

.commitment p {
  max-width: 52ch;
  margin: 0.85rem auto 0;
  color: var(--ink);
  font-size: 0.86rem;
  line-height: 1.6;
}

/* FAQ */
.faq {
  border-top: 1px solid var(--rule);
}

.faq details {
  border-bottom: 1px solid var(--hair);
}

.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 4rem;
  padding: 0.9rem 0;
  cursor: pointer;
  font-family: var(--display);
  font-size: 1.05rem;
  font-weight: 600;
  line-height: 1.3;
  list-style: none;
}

.faq summary::-webkit-details-marker {
  display: none;
}

.faq summary::after {
  flex: 0 0 auto;
  color: var(--berry);
  content: "+";
  font-family: var(--body);
  font-size: 1.4rem;
  font-weight: 300;
  line-height: 1;
}

.faq details[open] summary::after {
  content: "\2212";
}

.faq p {
  max-width: 44rem;
  padding: 0 2rem 1.3rem 0;
  color: var(--muted);
  font-size: 0.95rem;
}

/* Secondary asks — tables, and the list */
.card {
  /* Top tighter than the sides: the heading should lead, not the padding. */
  padding: 1.1rem clamp(1.4rem, 4vw, 1.9rem) clamp(1.4rem, 4vw, 1.9rem);
  background: var(--pink);
  border-top: 2px solid var(--ink);
}

/* Bloom Pink is a light ground, but --muted is tuned for cream and only
   reaches 3.5:1 on it. Ink at reduced alpha keeps the hierarchy and passes. */
.card .lede,
.card .fine,
.card .field label,
.index p {
  color: rgba(22, 17, 15, 0.78);
}

.card h3 {
  margin-bottom: 0.5rem;
}

.card .lede {
  font-size: 0.95rem;
}

.field {
  display: grid;
  gap: 0.3rem;
  margin-top: 0.85rem;
}

.field label {
  color: var(--muted);
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

.field input {
  min-height: 3rem;
  padding: 0.7rem 0.8rem;
  color: var(--ink);
  background: var(--white);
  border: 1px solid var(--rule);
  border-radius: 2px;
  font-family: var(--body);
  font-size: 1rem;
}

.field-row {
  display: grid;
  gap: 0.85rem;
}

.form-status {
  margin-top: 0.85rem;
  padding: 0.8rem 0.9rem;
  background: var(--cream);
  border-left: 2px solid var(--gold);
  font-size: 0.85rem;
}

.form-status[data-state="error"] {
  border-left-color: #b3261e;
}

.form-status[data-state="success"] {
  border-left-color: #2f7d52;
}

/* ---------- Footer ---------- */

.foot {
  /* The deep bottom padding exists only to clear the mobile buybar, which is
     display:none from 64rem up. */
  padding: 3rem 0 6.5rem;
  color: var(--paper);
  background: var(--berry);
}

.foot__inner {
  display: grid;
  gap: 2rem;
  width: min(100% - 2rem, var(--page));
  margin-inline: auto;
}

.foot img {
  width: 11rem;
  height: auto;
}

.foot .script {
  /* Fits "Something special happens at NOON." on one line rather than
     orphaning "NOON." */
  max-width: 36ch;
  margin-top: 1.35rem;
  color: var(--pink-soft);
  font-size: 1.2rem;
}

.foot small {
  margin-top: 0.8rem;
}

.foot__links {
  display: grid;
  gap: 2rem 1.5rem;
}

.foot nav {
  display: grid;
  gap: 0.2rem;
  align-content: start;
  /* Larger on touch so 12.8px text isn't floating in a 44px tap target. */
  font-size: 0.95rem;
}

.foot__heading {
  margin-bottom: 0.3rem;
  color: var(--pink-soft);
  font-family: var(--body);
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: var(--track);
  text-transform: uppercase;
}

.foot nav a {
  display: inline-flex;
  align-items: center;
  width: fit-content;
  /* 44px thumb target on touch; on pointer devices the generous min-height
     read as broken spacing, so tighten it there. */
  min-height: 2.75rem;
  color: var(--paper);
  text-decoration-color: rgba(255, 250, 245, 0.45);
}

.foot nav a:hover {
  color: var(--pink-soft);
  text-decoration-color: currentColor;
}

.foot small {
  color: rgba(255, 250, 245, 0.9);
  font-size: 0.72rem;
}

/* ---------- Mobile buy bar ---------- */

.buybar {
  position: fixed;
  right: 0.5rem;
  bottom: calc(0.5rem + env(safe-area-inset-bottom));
  left: 0.5rem;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.6rem 0.6rem 0.6rem 0.95rem;
  color: var(--paper);
  background: var(--berry);
  border: 1px solid rgba(255, 250, 245, 0.25);
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.35);
  opacity: 0;
  pointer-events: none;
  transform: translateY(150%);
  transition: opacity 200ms ease, transform 200ms ease;
}

.buybar.is-visible {
  opacity: 1;
  pointer-events: auto;
  transform: none;
}

.buybar__copy strong,
.buybar__copy span {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.buybar__copy strong {
  font-family: var(--display);
  font-size: 0.92rem;
  font-weight: 600;
}

.buybar__copy span {
  color: var(--paper);
  font-size: 0.66rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.buybar .btn {
  flex: 0 0 auto;
  width: auto;
  min-height: 2.8rem;
  padding: 0.5rem 1rem;
  font-size: 0.66rem;
  color: var(--berry);
  background: var(--cream);
}

.buybar .btn:hover {
  color: var(--ink);
  background: var(--paper);
}

/* ---------- Reveal ---------- */

[data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 600ms ease, transform 600ms ease;
}

[data-reveal].is-revealed {
  opacity: 1;
  transform: none;
}

/* ---------- Responsive ---------- */

@media (min-width: 36rem) {
  .field-row {
    grid-template-columns: 1fr 1fr;
  }

  .index li {
    grid-template-columns: minmax(0, 11rem) minmax(0, 1.6fr);
    align-items: baseline;
  }

}

/* The watercolour ground lives here rather than on the body: sized to
   cover, it can't end mid-page and paint a visible band under the copy.
   On desktop the hero art overlays all of it. */
.cover {
  background: var(--cream) url("assets/images/ground-watercolor.webp") top center / cover no-repeat;
}

/* The cover layout needs a viewport wide enough for the art's composed
   copy space, so it starts at 64rem. Below that, the wide art sits in
   flow under the copy, same as mobile. */
@media (min-width: 64rem) {
  .cover {
    position: relative;
  }

  .hero {
    /* Static so .cover is the art's containing block and the artwork can
       run up under the topbar. */
    position: static;
    display: flex;
    align-items: center;
    min-height: min(84vh, 46rem);
    padding: 0;
  }

  .hero__art {
    position: absolute;
    inset: 0;
    z-index: 0;
    /* The parallax drift must not slide the art out past the bottom blend. */
    overflow: hidden;
  }

  .hero__art::after {
    position: absolute;
    inset: auto 0 0;
    height: 5rem;
    background: linear-gradient(to bottom, rgba(247, 233, 219, 0), var(--cream));
    content: "";
  }

  .hero__art img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* Pin the top: on viewports wider than the art's 16:9 the vertical crop
       takes the floor, never the model's face. */
    object-position: left top;
  }

  .hero__copy {
    position: relative;
    z-index: 1;
    grid-template-columns: 50% minmax(0, 1fr);
  }

  .hero__copy > * {
    grid-column: 2;
  }
}

/* Wide viewports leave the art more room, so the copy moves left in two
   steps that track the full-size headline returning at 80rem. */
@media (min-width: 80rem) and (max-width: 89.99rem) {
  .hero__copy {
    grid-template-columns: 45% minmax(0, 1fr);
  }

  /* The full 7rem headline needs the 90rem column; step it so
     "dressed in pink." holds one line here too. */
  .hero h1 {
    font-size: clamp(4.5rem, 7.5vw, 6.2rem);
  }
}

@media (min-width: 90rem) {
  .hero__copy {
    grid-template-columns: 42% minmax(0, 1fr);
  }
}

@media (min-width: 48rem) {
  .topnav {
    display: flex;
  }

  .topbar,
  .hero__text,
  .shell,
  .foot__inner {
    width: min(100% - 3rem, var(--page));
  }

  /* Three columns rather than two: a 1fr link block beside a narrow brand
     block left ~570px of dead space in the middle. */
  .foot__inner {
    grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr) minmax(0, 1fr);
    gap: 3rem;
    align-items: start;
  }

  .foot__links {
    display: contents;
  }

  /* No buybar to clear above 64rem — see .foot. */
  .foot {
    padding-bottom: 3rem;
  }

  .foot nav {
    gap: 0.55rem;
    font-size: 0.8rem;
  }

  .foot nav a {
    min-height: 0;
  }


  /* An editorial mosaic rather than equal tiles: the crowd runs big,
     the portrait fashion shot takes the tall right column, and the
     remaining three sit in a strip beneath. No orphans. */
  .plates {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-template-rows: 14rem 14rem 15rem;
  }

  .plates figure {
    position: relative;
    overflow: hidden;
  }

  .plates img {
    height: 100%;
    aspect-ratio: auto;
    transition: transform 0.6s ease;
  }

  .plates figure:hover img {
    transform: scale(1.04);
  }

  .plates figure:first-child {
    grid-column: 1 / 3;
    grid-row: 1 / 3;
  }

  .plates figure:nth-child(4) {
    grid-column: 3;
    grid-row: 1 / 3;
  }

  .plates figcaption {
    position: absolute;
    bottom: 0;
    left: 0;
    padding: 0.45rem 0.7rem;
    color: var(--paper);
    background: rgba(22, 17, 15, 0.62);
  }

  .foot__links {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.5rem;
  }
}

/* Between the two-column breakpoint and 80rem the hero headline is sized
   against the viewport but rendered in a half column, so it wrapped to four
   lines and pushed the buy CTA below the fold. Cap it until there is room. */
@media (min-width: 64rem) and (max-width: 79.99rem) {
  .hero h1 {
    font-size: clamp(2.7rem, 4.4vw, 3.5rem);
  }

  .hero__text {
    padding-block: 3rem;
  }
}

@media (min-width: 80rem) {
  /* minmax(0,…) removes the fr min-content floor that caused B1. */
  .band {
    display: grid;
    grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
    gap: 1.75rem;
    align-items: center;
    padding: clamp(2.5rem, 5vw, 3.5rem) clamp(2rem, 4vw, 3rem);
  }
}

@media (min-width: 64rem) {
  .hero__inner {
    /* The template was declared without display:grid, so the two-column
       hero never engaged and the media stacked below a half-empty row. */
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(26rem, 0.85fr);
    align-items: stretch;
  }

  .hero__text {
    width: auto;
    padding: 4.5rem 3rem 4.5rem max(1.5rem, calc((100vw - var(--page)) / 2));
  }

  .hero__media {
    min-height: 38rem;
  }

  /* The point of the whole layout: the buy stays on screen.

     The rail comes first in the DOM so that on mobile the checkout sits
     directly under the hero. On desktop that would put it in column one,
     so both children are placed explicitly. Tab order still reaches the
     buy card first, which is the right priority for a page whose job is
     selling one ticket. */
  .shell {
    grid-template-columns: minmax(0, 1fr) var(--rail);
    gap: 4rem;
    align-items: start;
  }

  .story {
    grid-column: 1;
    grid-row: 1;
  }

  .rail {
    position: sticky;
    top: 1.5rem;
    grid-column: 2;
    grid-row: 1;
  }

  /* The rail is always visible on desktop, so the bar is mobile-only. */
  .buybar {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }

  [data-reveal] {
    opacity: 1;
    transform: none;
  }
}

@media (forced-colors: active) {
  .btn,
  .ticket,
  .card,
  .commitment {
    border: 1px solid CanvasText;
  }

  [data-reveal] {
    opacity: 1;
    transform: none;
  }
}
