/* ==========================================================================
   David Spatola Entertainment
   Direction: "Split" — the DS monogram's diagonal, taken to page scale.
   Panels alternate ivory and ink and meet on that same descending-left angle.
   Gold is Pantone 874 C as it reads on screen, and appears as hairlines and
   small type. Never as fill.
   ========================================================================== */

/* --------------------------------------------------------------- tokens */
:root {
  /* Every pair that carries text was measured. Text on ink and all body copy
     clears WCAG AA comfortably. The one deliberate exception is small gold
     text on ivory at 3.57:1, which is AA for large text but under the 4.5:1
     small-text line: the client chose the Pantone gold over that threshold,
     knowingly, and --gold-deep is how far it can be pushed back toward
     readable while still being this gold. */
  --ivory:      #F6F3ED;
  --ink:        #14120F;
  --ink-2:      #221F1A;
  /* One gold, Pantone 874 C as it reads on screen: the metallic swatch's
     mid-tone rather than Pantone's flat conversion, which is a muted bronze.
     This is the brand gold and it is used everywhere gold appears. */
  --gold:       #D4AF37;
  /* The same hue, deepened, for one job only: gold text below about 1rem on
     the ivory ground, where the brand gold falls to 1.9:1 and small letters
     stop being readable. Display-size gold, anything on ink, and every rule
     and hairline use --gold. */
  --gold-deep:  #9C7C20;

  --muted:      #5F5A51;   /* secondary text on ivory 6.18:1 */
  --muted-dark: #A8A093;   /* secondary text on ink   7.22:1 */
  --hair:       rgba(20, 18, 15, 0.14);
  --hair-light: rgba(246, 243, 237, 0.16);
  --gold-hair:  rgba(212, 175, 55, 0.55);

  --ff-display: "Bodoni Moda", "Didot", "Bodoni MT", Georgia, serif;
  --ff-body:    "Jost", "Avenir Next", "Segoe UI", system-ui, sans-serif;
  /* Figures. Bodoni's numerals are all hairline and ball terminal, which is
     beautiful in a headline and hard work in a phone number. Jost's figures
     are open and even, and it is already loaded, so this costs nothing. */
  --ff-num:     "Jost", "Avenir Next", "Segoe UI", system-ui, sans-serif;

  /* Spacious end of the scale. This site sells restraint. */
  --s1: 0.5rem;  --s2: 1rem;   --s3: 1.5rem;  --s4: 2rem;
  --s5: 3rem;    --s6: 4rem;   --s7: 6rem;    --s8: 8rem;   --s9: 10rem;

  --measure: 1180px;
  --gutter: clamp(1.25rem, 5vw, 4.5rem);
  --header-h: 4.5rem;

  /* The seam. A single angle, shared by every panel boundary on the page,
     expressed in vw so the angle itself stays constant at any width. */
  --seam: 5vw;

  --ease: cubic-bezier(0.22, 0.68, 0.2, 1);
  --t-fast: 180ms var(--ease);
  --t-med:  340ms var(--ease);
  --t-slow: 720ms var(--ease);
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 1rem);
}

body {
  margin: 0;
  background: var(--ivory);
  color: var(--ink);
  font-family: var(--ff-body);
  font-size: 1.0625rem;
  font-weight: 300;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

:focus-visible {
  outline: 2px solid var(--gold-deep);
  outline-offset: 3px;
  border-radius: 1px;
}
.panel--ink :focus-visible { outline-color: var(--gold); }

.skip-link {
  position: absolute; left: var(--s2); top: -100px; z-index: 200;
  background: var(--ink); color: var(--ivory);
  padding: 0.75rem 1.25rem; font-size: 0.875rem; letter-spacing: 0.06em;
  text-decoration: none; transition: top var(--t-fast);
}
.skip-link:focus { top: var(--s2); }

.visually-hidden {
  position: absolute !important; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* ----------------------------------------------------------- typography */
.display {
  font-family: var(--ff-display);
  font-weight: 500;
  line-height: 1.02;
  letter-spacing: -0.012em;
  margin: 0;
  /* Bodoni's hairlines only survive at size. Nothing below 2rem uses it. */
}
.display--hero { font-size: clamp(2.75rem, 7.2vw, 5.75rem); }
.display--sect { font-size: clamp(2.15rem, 4.6vw, 3.75rem); }
.display--sm   { font-size: clamp(1.6rem, 2.6vw, 2.15rem); }
.display em { font-style: italic; font-weight: 400; }

.eyebrow {
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold-deep);
  margin: 0 0 var(--s3);
  display: flex; align-items: center; gap: 0.85rem;
}
.eyebrow::before {
  content: ""; width: 2.25rem; height: 1px;
  background: var(--gold); opacity: 0.8; flex: none;
}
.panel--ink .eyebrow { color: var(--gold); }
.panel--ink .eyebrow::before { background: var(--gold); }

/* The first line on each page: the hero on home, the page header elsewhere.
   Larger and heavier than a section eyebrow so it reads before the headline
   rather than after it. */
.eyebrow--lead {
  font-size: 0.875rem;
  letter-spacing: 0.2em;
  margin-bottom: var(--s3);
}
.eyebrow--lead::before { width: 3rem; opacity: 0.8; }

.lead {
  font-size: clamp(1.0625rem, 1.2vw, 1.1875rem);
  line-height: 1.7;
  color: var(--muted);
  max-width: 46ch;
  margin: var(--s3) 0 0;
}
.panel--ink .lead { color: var(--muted-dark); }

/* ------------------------------------------------------------- controls */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 0.6rem;
  min-height: 3rem;
  padding: 0.9rem 1.85rem;
  font-family: var(--ff-body);
  font-size: 0.8125rem; font-weight: 400;
  letter-spacing: 0.16em; text-transform: uppercase;
  text-decoration: none; cursor: pointer;
  border: 1px solid transparent; border-radius: 0;
  transition: background var(--t-fast), color var(--t-fast),
              border-color var(--t-fast);
}
.btn--primary { background: var(--ink); color: var(--ivory); border-color: var(--ink); }
.btn--primary:hover { background: var(--gold); border-color: var(--gold); color: var(--ink); }

.btn--ghost { background: transparent; color: var(--ink); border-color: var(--hair); }
.btn--ghost:hover { border-color: var(--ink); }

.panel--ink .btn--primary { background: var(--gold); color: var(--ink); border-color: var(--gold); }
.panel--ink .btn--primary:hover { background: var(--ivory); border-color: var(--ivory); }
.panel--ink .btn--ghost { color: var(--ivory); border-color: var(--hair-light); }
.panel--ink .btn--ghost:hover { border-color: var(--ivory); }

/* ------------------------------------------------------------ masthead */
.masthead {
  position: fixed; inset: 0 0 auto; z-index: 100;
  height: var(--header-h);
  display: flex; align-items: center; gap: var(--s4);
  padding: 0 var(--gutter);
  background: var(--ivory);
  border-bottom: 1px solid transparent;
  transition: border-color var(--t-med), box-shadow var(--t-med);
}
.masthead.is-stuck {
  border-bottom-color: var(--gold-hair);
  box-shadow: 0 1px 24px rgba(20, 18, 15, 0.05);
}
/* Subpages have content directly under the header instead of a full-bleed
   hero, so the rule is always there. Set in the markup, independent of the
   scroll class, which only adds the shadow. */
.masthead--solid { border-bottom-color: var(--gold-hair); }

.brand {
  display: flex; align-items: center; gap: 0.75rem;
  text-decoration: none; margin-right: auto;
}
.brand__mark { width: 2.125rem; height: 2.125rem; flex: none; display: block; }
.brand__name {
  font-family: var(--ff-display);
  font-size: 1.0625rem; font-weight: 500;
  letter-spacing: 0.09em; text-transform: uppercase;
  line-height: 1; white-space: nowrap;
}
.brand__name span { color: var(--gold-deep); }

.nav { display: flex; align-items: center; gap: var(--s4); }
.nav__link {
  position: relative;
  font-size: 0.75rem; letter-spacing: 0.15em; text-transform: uppercase;
  color: var(--muted); text-decoration: none; padding: 0.7rem 0;
  transition: color var(--t-fast);
}
.nav__link::after {
  content: ""; position: absolute; left: 0; bottom: 0;
  width: 100%; height: 1px; background: var(--gold-deep);
  transform: scaleX(0); transform-origin: right;
  transition: transform var(--t-med);
}
/* aria-current is "true" for the scroll-spied anchors on the home page and
   "page" for whichever subpage is open, so match the attribute itself. */
.nav__link:hover, .nav__link[aria-current] { color: var(--ink); }
.nav__link:hover::after,
.nav__link[aria-current]::after { transform: scaleX(1); transform-origin: left; }

.masthead__cta { font-size: 0.75rem; padding: 0.7rem 1.4rem; min-height: 2.5rem; }

/* ------------------------------------------------------- menu button */
/* Hidden outright on desktop, and only ever shown when the .js class is on
   <html>. Without scripting the button could not open anything, so it stays
   out of the tab order entirely rather than sitting there doing nothing. */
.navtoggle { display: none; }
.navtoggle__bar,
.navtoggle__bar::before,
.navtoggle__bar::after {
  display: block; width: 1.375rem; height: 1px;
  background: var(--ink);
  transition: transform var(--t-med), background var(--t-fast);
}
.navtoggle__bar { position: relative; }
.navtoggle__bar::before,
.navtoggle__bar::after { content: ""; position: absolute; left: 0; }
.navtoggle__bar::before { top: -6px; }
.navtoggle__bar::after  { top: 6px; }

/* Open: the two outer rules meet in the middle and cross, the centre one
   disappears under them. */
.navtoggle[aria-expanded="true"] .navtoggle__bar { background: transparent; }
.navtoggle[aria-expanded="true"] .navtoggle__bar::before {
  transform: translateY(6px) rotate(45deg);
}
.navtoggle[aria-expanded="true"] .navtoggle__bar::after {
  transform: translateY(-6px) rotate(-45deg);
}

.nav__call { display: none; }

/* ---------------------------------------------------------------- panel */
/* Every panel after the first cuts into the one above it on the shared
   angle, so the boundary interlocks exactly with no gap to maintain. */
.panel {
  position: relative;
  padding: var(--s8) var(--gutter);
}
.panel--seam {
  margin-top: calc(var(--seam) * -1);
  padding-top: calc(var(--s8) + var(--seam));
  clip-path: polygon(0 var(--seam), 100% 0, 100% 100%, 0 100%);
}
/* The gold hairline riding the seam: a 1.5px parallelogram pinned to the
   panel's own clipped edge, so the two can never drift apart. */
.panel--seam::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0;
  height: calc(var(--seam) + 3px);
  background: var(--gold-hair);
  clip-path: polygon(0 var(--seam), 100% 0,
                     100% 1.5px, 0 calc(var(--seam) + 1.5px));
  pointer-events: none;
}
.panel--ink { background: var(--ink); color: var(--ivory); }
.panel--paper { background: var(--ivory); color: var(--ink); }

/* Music notes behind every section. site.js places them into empty space
   only; this is just the layer they draw on. Each section is isolated so the
   layer's negative z-index puts it above the section's own background but
   under all of its content, including the hero's ink panel and photograph. */
.hero, .panel { isolation: isolate; }
.notes {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  /* The brand gold, faint enough to read as texture. The two opacities differ
     a lot because this gold is light: on ivory it needs almost half strength
     to register at all, while on ink a fifth is already plenty. */
  fill: var(--gold);
  opacity: 0.46;
}
.panel--ink .notes { fill: var(--gold); opacity: 0.17; }
.panel__inner { max-width: var(--measure); margin-inline: auto; width: 100%; }

.section-head { max-width: 40rem; margin-bottom: var(--s6); }

/* ----------------------------------------------------------------- hero */
.hero {
  position: relative;
  min-height: calc(100svh - var(--header-h));
  margin-top: var(--header-h);
  display: flex; align-items: center;
  overflow: hidden;
}
/* Ink panel, right. Its left edge descends to the left at the same angle
   as the monogram's diagonal — the whole conceit of the page in one shape.
   The two ends are variables because the copy column has to stay clear of
   the seam at every width; dark type on the ink panel is unreadable. */
.hero {
  --hero-top: 66%;
  --hero-bot: 50%;
  --hero-copy: 30rem;
}
.hero__media {
  position: absolute; inset: 0;
  background: var(--ink);
  clip-path: polygon(var(--hero-top) 0, 100% 0, 100% 100%, var(--hero-bot) 100%);
}
.hero__seam {
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: var(--gold-hair);
  clip-path: polygon(var(--hero-top) 0, calc(var(--hero-top) + 1.5px) 0,
                     calc(var(--hero-bot) + 1.5px) 100%, var(--hero-bot) 100%);
}
.hero__photo {
  /* Flush right, so the side of his head meets the edge of the screen. If
     this width changes, update the `sizes` attribute on the hero image in
     index.html to match. */
  position: absolute; right: 0; bottom: 0;
  width: clamp(22rem, 38vw, 34rem);
  height: auto;
  object-fit: cover;
  /* Fades into the ink on the top and the left only, so the crop edge never
     reads as a pasted rectangle while the right side stays solid. */
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 22%, #000 100%),
                      linear-gradient(to left, #000 55%, transparent 100%);
  -webkit-mask-composite: source-in;
          mask-image: linear-gradient(to bottom, transparent, #000 22%, #000 100%),
                      linear-gradient(to left, #000 55%, transparent 100%);
          mask-composite: intersect;
}
.hero__copy {
  position: relative; z-index: 3;
  width: 100%; max-width: var(--measure);
  margin-inline: auto;
  padding: var(--s6) var(--gutter);
}
.hero__inner { max-width: var(--hero-copy); }
.hero .lead { max-width: none; }

.hero__title { margin-bottom: var(--s3); }
.hero__title .line { display: block; }
.hero__title .line--sub {
  font-size: clamp(1.35rem, 2.7vw, 2.15rem);
  font-weight: 400;
  letter-spacing: -0.005em;
  color: var(--muted);
  margin-top: 0.35rem;
}

.hero__actions {
  display: flex; flex-wrap: wrap; gap: var(--s2);
  margin-top: var(--s5);
}
/* The demo toggle swaps between "Hear him play" and "Pause the music", which
   differ by about 18px. Reserving the wider of the two stops the button
   resizing under the cursor at the moment it is clicked. */
[data-start-demo] { min-width: 12.5rem; }

.hero__proof {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: 0.75rem var(--s3);
  margin-top: var(--s5);
  padding-top: var(--s3);
  border-top: 1px solid var(--hair);
  font-size: 0.8125rem; letter-spacing: 0.03em; color: var(--muted);
}
.stars { display: inline-flex; gap: 2px; color: var(--gold-deep); }
.stars svg { width: 0.875rem; height: 0.875rem; fill: currentColor; }
.hero__proof b { font-family: var(--ff-num); font-weight: 500; color: var(--ink); }
.hero__reviews {
  color: inherit; text-decoration: none;
  border-bottom: 1px solid var(--hair);
  padding-block: 0.35rem 0.1rem;
  transition: color var(--t-fast), border-color var(--t-fast);
}
.hero__reviews:hover { color: var(--ink); border-bottom-color: var(--gold-deep); }

.hero__scroll {
  position: absolute; left: calc(var(--gutter) - 0.5rem); bottom: 1.5rem; z-index: 3;
  display: inline-flex; align-items: center; gap: 0.6rem;
  /* Padding is here to carry the hit area past the 24px minimum; the text
     itself is only 11px. */
  padding: 0.65rem 0.5rem;
  font-size: 0.6875rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--muted); text-decoration: none;
}
.hero__scroll svg { width: 0.75rem; height: 1.25rem; stroke: currentColor; fill: none; }
.hero__scroll:hover { color: var(--gold-deep); }
.hero__scroll svg { animation: nudge 2.6s var(--ease) infinite; }
@keyframes nudge {
  0%, 62%, 100% { transform: translateY(0); opacity: 0.55; }
  78%           { transform: translateY(4px); opacity: 1; }
}

/* ---------------------------------------------------------------- music */
.music__head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--s4); flex-wrap: wrap; margin-bottom: var(--s6);
}
.music__head .lead { margin-top: var(--s3); }

.tracks { list-style: none; margin: 0; padding: 0; }

.track { position: relative; }

.track__btn {
  width: 100%;
  display: grid;
  grid-template-columns: 2.25rem 1fr auto 2.75rem;
  align-items: center;
  gap: var(--s3);
  padding: 1.35rem 0;
  background: none; border: 0;
  font-family: inherit; color: inherit; text-align: left;
  cursor: pointer;
  transition: color var(--t-fast);
}
.track__num {
  font-family: var(--ff-num);
  font-size: 0.875rem; color: var(--muted-dark);
  font-variant-numeric: tabular-nums;
  transition: color var(--t-fast);
}
.track__name {
  font-family: var(--ff-display);
  font-size: clamp(1.25rem, 2.1vw, 1.6rem);
  font-weight: 400; line-height: 1.2;
  display: block;
}
.track__meta {
  display: block;
  font-size: 0.75rem; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--muted-dark); margin-top: 0.3rem;
}
.track__time {
  font-size: 0.8125rem; color: var(--muted-dark);
  font-variant-numeric: tabular-nums;
}
.track__icon {
  width: 2.75rem; height: 2.75rem; border-radius: 50%;
  display: grid; place-items: center;
  border: 1px solid var(--hair-light);
  transition: border-color var(--t-fast), background var(--t-fast),
              color var(--t-fast);
}
.track__icon svg { width: 0.75rem; height: 0.75rem; fill: currentColor; }
.track__icon .ico-pause { display: none; }

.track__btn:hover .track__icon { border-color: var(--gold); color: var(--gold); }
.track__btn:hover .track__num { color: var(--gold); }

/* The staff line. It is the rule under the track AND the progress bar —
   the only moving part in the whole player. */
.track__rule {
  display: block; position: relative;
  height: 1px; background: var(--hair-light);
}
.track__fill {
  position: absolute; inset: 0;
  background: var(--gold);
  transform: scaleX(0); transform-origin: left;
  will-change: transform;
}

.track.is-active .track__name { color: var(--gold); }
.track.is-active .track__num { color: var(--gold); }
.track.is-active .track__icon {
  background: var(--gold); border-color: var(--gold); color: var(--ink);
}
.track.is-playing .track__icon .ico-play { display: none; }
.track.is-playing .track__icon .ico-pause { display: block; }

.music__note {
  margin-top: var(--s5);
  font-size: 0.8125rem; color: var(--muted-dark);
  display: flex; align-items: center; gap: 0.6rem;
}

/* --------------------------------------------------------------- events */
/* Fixed column counts rather than auto-fit: there are exactly six cards, and
   3 and 2 both divide into 6 evenly. auto-fit would fit four across on a wide
   screen and leave two empty cells on the second row. */
.events__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: var(--hair);
  border: 1px solid var(--hair);
}
.event { display: flex; flex-direction: column; }
.event {
  background: var(--ivory);
  padding: var(--s4) var(--s4) var(--s5);
  transition: background var(--t-med);
}
.event:hover { background: #FBF9F5; }
.event__name {
  font-family: var(--ff-display);
  font-size: 1.4rem; font-weight: 400; line-height: 1.25;
  margin: 0 0 0.75rem;
}
.event__keys {
  font-size: 0.6875rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--gold-deep); margin: 0 0 var(--s2);
}
.event__copy { margin: 0; font-size: 0.9375rem; color: var(--muted); line-height: 1.7; }

/* -------------------------------------------------------------- reviews */
.reviews {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
  gap: var(--s6);
  margin-bottom: var(--s7);
}
/* Two reviews side by side on desktop, one on a phone. 780px is where the grid
   above drops to a single column, so the extra review is cut at exactly the
   point it would otherwise start stacking and pushing the rating out of view. */
@media (max-width: 780px) {
  .review--wide-only { display: none; }
}
/* Reviews sit on ivory on the home page and would sit on ink if the section
   ever moves, so both grounds are defined rather than assumed. */
.review { position: relative; padding-top: var(--s4); }
.review::before {
  content: ""; position: absolute; top: 0; left: 0;
  width: 3.5rem; height: 1px; background: var(--gold);
}
.panel--ink .review::before { background: var(--gold); }
.review__text {
  font-family: var(--ff-display);
  font-size: clamp(1.25rem, 1.9vw, 1.5rem);
  font-weight: 400; font-style: italic; line-height: 1.5;
  margin: 0 0 var(--s3);
}
.review__who { font-size: 0.8125rem; letter-spacing: 0.04em; color: var(--muted); margin: 0; }
.review__who b { display: block; font-weight: 400; color: var(--ink); letter-spacing: 0.09em;
                 text-transform: uppercase; font-size: 0.75rem; margin-bottom: 0.25rem; }
.panel--ink .review__who { color: var(--muted-dark); }
.panel--ink .review__who b { color: var(--ivory); }

.rating {
  display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
  padding-top: var(--s4); border-top: 1px solid var(--hair);
}
.panel--ink .rating { border-top-color: var(--hair-light); }
.rating__score {
  font-family: var(--ff-num); font-size: 3rem; font-weight: 300; line-height: 1;
  color: var(--gold);
}
.panel--ink .rating__score { color: var(--gold); }
.rating__meta { font-size: 1.0625rem; font-weight: 400; color: var(--ink); }
.panel--ink .rating__meta { color: var(--ivory); }
.panel--ink .stars { color: var(--gold); }

.rating__link {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 0.6rem;
  padding: 0.7rem 0 0.45rem;
  font-size: 0.875rem; font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--gold-deep); text-decoration: none;
  border-bottom: 1px solid var(--gold-deep);
  transition: border-color var(--t-fast), color var(--t-fast);
}
.rating__link svg { width: 0.875rem; height: 0.875rem; flex: none; }
.rating__link:hover { color: var(--ink); border-bottom-color: var(--ink); }
.panel--ink .rating__link { color: var(--gold); }
.panel--ink .rating__link:hover { color: var(--ivory); border-bottom-color: var(--ivory); }
@media (max-width: 760px) { .rating__link { margin-left: 0; } }

/* ---------------------------------------------------------------- areas */
/* Six groups, so fixed counts of 3, 2 and 1 always fill every row. */
.areas__cols {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s5) var(--s4);
}
@media (max-width: 1024px) { .areas__cols { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px)  { .areas__cols { grid-template-columns: minmax(0, 1fr); } }
.areas__group h2, .areas__group h3 {
  font-size: 0.6875rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--gold-deep); margin: 0 0 var(--s2);
  padding-bottom: 0.6rem; border-bottom: 1px solid var(--hair);
  font-weight: 500;
}
/* One line under each region heading. It carries the phrase people search
   ("NYC pianist", "PA pianist") and tells a reader what the list below is. */
.areas__note {
  margin: 0 0 var(--s2);
  font-size: 0.8125rem; line-height: 1.6; color: var(--muted);
}
.areas__list { list-style: none; margin: 0; padding: 0; columns: 1; }
.areas__list li { font-size: 0.9375rem; color: var(--muted); padding: 0.28rem 0; }

/* -------------------------------------------------------------- contact */
.contact__grid {
  display: grid; grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: var(--s7);
  align-items: start;
}
.contact__direct { display: grid; gap: var(--s4); margin-top: var(--s5); }
.contact__item { display: block; text-decoration: none; }
.contact__label {
  display: block;
  font-size: 0.6875rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--gold); margin-bottom: 0.4rem;
}
.contact__value {
  font-family: var(--ff-display); font-size: 1.5rem; font-weight: 400;
  transition: color var(--t-fast);
}
.contact__value--num { font-family: var(--ff-num); font-weight: 300; letter-spacing: 0.02em; }
a.contact__item:hover .contact__value { color: var(--gold); }

.form { display: grid; gap: var(--s3); }
.form__row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s3); }
.field { display: grid; gap: 0.45rem; }
/* The form sits on ink, so labels, entries and box outlines are all white
   (the site's ivory) rather than the grey used for secondary text elsewhere. */
.field__label {
  font-size: 0.6875rem; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ivory);
}
.field__label .req { color: var(--gold); }
.field input, .field select, .field textarea {
  width: 100%;
  min-height: 3rem;
  /* Tells the browser to draw its own widgets (date picker, select menu,
     autofill, spinners) for a dark surface rather than a light one. */
  color-scheme: dark;
  padding: 0.8rem 0.95rem;
  font-family: var(--ff-body); font-size: 1rem; font-weight: 300;
  color: #FFFFFF;
  background: var(--ink-2);
  border: 1px solid rgba(246, 243, 237, 0.62);
  border-radius: 0;
  transition: border-color var(--t-fast), background var(--t-fast);
  -webkit-appearance: none; appearance: none;
}
.field textarea { min-height: 7rem; resize: vertical; line-height: 1.6; }
.field select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23F6F3ED' stroke-width='1.4' fill='none'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  background-size: 12px 8px;
  padding-right: 2.5rem;
}
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--gold); background: #1A1714; outline-offset: 1px;
}
.field input::placeholder, .field textarea::placeholder { color: rgba(246, 243, 237, 0.55); }
.field__help { font-size: 0.75rem; color: var(--ivory); opacity: 0.85; }
.field__error {
  font-size: 0.8125rem; color: #E8A5A5; min-height: 0;
  display: none;
}
.field.is-invalid .field__error { display: block; }
.field.is-invalid input, .field.is-invalid select, .field.is-invalid textarea {
  border-color: #C97A7A;
}

/* Honeypot. Off-screen rather than display:none so bots still fill it. */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* Said before the button, not after: the visitor should know the form hands
   off to their own email app before they press it, not discover it. */
.form__note {
  margin-top: var(--s2);
  padding: 0.9rem 1.1rem;
  border-left: 2px solid var(--gold);
  background: var(--ink-2);
  font-size: 0.9375rem; line-height: 1.6; color: var(--ivory);
}
.form__note p { margin: 0; }
.form__note p + p { margin-top: 0.4rem; }
.form__note strong { font-weight: 500; }
.form__note a { color: var(--gold); text-underline-offset: 3px; white-space: nowrap; }
.form__note a:hover { color: var(--ivory); }

.form__submit { margin-top: var(--s2); justify-self: start; }
.form__submit[aria-busy="true"] { opacity: 0.6; pointer-events: none; }

.form__status {
  font-size: 0.9375rem; padding: 0.9rem 1.1rem;
  border-left: 2px solid var(--gold);
  background: var(--ink-2); color: var(--ivory);
  display: none;
}
.form__status.is-shown { display: block; }
.form__status.is-error { border-left-color: #C97A7A; }
.form__status-action {
  color: var(--gold);
  text-decoration: underline;
  text-underline-offset: 3px;
  white-space: nowrap;
}
.form__status-action:hover { color: var(--ivory); }

.form__fine { font-size: 0.75rem; color: var(--ivory); line-height: 1.6; margin: 0; }
.form__fine a { color: var(--ivory); }

/* --------------------------------------------------------------- footer */
.footer {
  background: var(--ink); color: var(--muted-dark);
  padding: var(--s6) var(--gutter) var(--s4);
  border-top: 1px solid var(--hair-light);
}
.footer__inner { max-width: var(--measure); margin-inline: auto; }
.footer__top {
  display: grid; grid-template-columns: minmax(0, 1.4fr) repeat(2, minmax(0, 1fr));
  gap: var(--s5);
  padding-bottom: var(--s5);
  border-bottom: 1px solid var(--hair-light);
}
.footer__blurb { font-size: 0.875rem; line-height: 1.75; margin: var(--s2) 0 0; max-width: 34ch; }
.footer h2 {
  font-size: 0.6875rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--gold); margin: 0 0 var(--s2); font-weight: 500;
}
.footer ul { list-style: none; margin: 0; padding: 0; }
.footer li { padding: 0.3rem 0; font-size: 0.875rem; }
.footer a { text-decoration: none; transition: color var(--t-fast); }
.footer a:hover { color: var(--ivory); }
.footer__base {
  display: flex; justify-content: space-between; flex-wrap: wrap; gap: var(--s2);
  padding-top: var(--s4); font-size: 0.75rem;
}
.footer__legal { display: flex; gap: var(--s3); flex-wrap: wrap; }
/* Maker's credit: the last line of the footer, quieter than everything above. */
.footer__credit {
  margin: var(--s3) 0 0;
  font-size: 0.75rem; letter-spacing: 0.02em;
}
.footer .footer__credit a {
  color: var(--ivory);
  text-decoration: underline;
  text-decoration-color: var(--hair-light);
  text-underline-offset: 3px;
  transition: color var(--t-fast), text-decoration-color var(--t-fast);
}
.footer .footer__credit a:hover { color: var(--gold); text-decoration-color: var(--gold); }

/* --------------------------------------------------- mobile action bar */
/* On a phone the primary action is the phone call, so it gets a permanent
   home rather than living somewhere up in a collapsed menu. */
.actionbar {
  display: none;
  position: fixed; inset: auto 0 0; z-index: 90;
  grid-template-columns: 1fr 1fr;
  background: var(--ivory);
  border-top: 1px solid var(--gold-hair);
  padding-bottom: env(safe-area-inset-bottom);
}
.actionbar a {
  display: flex; align-items: center; justify-content: center; gap: 0.5rem;
  min-height: 3.5rem; text-decoration: none;
  font-size: 0.75rem; letter-spacing: 0.16em; text-transform: uppercase;
}
.actionbar a + a { background: var(--ink); color: var(--ivory); }
.actionbar svg { width: 0.9375rem; height: 0.9375rem; fill: currentColor; }

/* --------------------------------------------------- home closing callout */
/* The last thing on the home page is the phone number, because a call is the
   conversion. Nothing else competes with it in this panel. */
/* On the subpages this class sits on the same element as .panel__inner, which
   centres itself at the measure. Overriding the margin keeps the callout flush
   with the left edge of every other section instead of drifting to the middle. */
.callout { max-width: 40rem; margin-inline: 0; }

/* Copy on the left, a photograph on the right: the grand piano on the home
   page, the dancing couple on events and areas. */
.book {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.92fr);
  gap: var(--s7);
  align-items: center;
}
.book__media { margin: 0; }
.book__media img {
  width: 100%; height: auto;
  /* The photo's own edges are already dark, so a short fade on the side that
     faces the copy is enough to seat it in the panel without a hard join. */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 16%);
          mask-image: linear-gradient(to right, transparent, #000 16%);
}
/* The couple is a tall portrait. At the full column width it would stand far
   taller than the copy beside it, so it is held to a narrower frame. */
/* Unlike the piano shot, its edges are bright sky and pale grass, so a fade
   on one side would leave three hard white borders against the ink. Every
   edge is softened instead, strongest on the side facing the copy. */
.book__media--portrait { width: 100%; max-width: 26rem; justify-self: end; }
.book__media--portrait img {
  -webkit-mask-image: linear-gradient(to right, transparent, #000 18%, #000 90%, transparent),
                      linear-gradient(to bottom, transparent, #000 12%, #000 88%, transparent);
  -webkit-mask-composite: source-in;
          mask-image: linear-gradient(to right, transparent, #000 18%, #000 90%, transparent),
                      linear-gradient(to bottom, transparent, #000 12%, #000 88%, transparent);
          mask-composite: intersect;
}
@media (max-width: 900px) {
  .book { grid-template-columns: minmax(0, 1fr); gap: var(--s5); }
  .book__media--portrait { justify-self: start; }
  /* Stacked, the photo sits under the copy, so the fade moves to the top
     edge. A left fade would read as a mistake here. */
  .book__media img {
    -webkit-mask-image: linear-gradient(to bottom, transparent, #000 14%);
            mask-image: linear-gradient(to bottom, transparent, #000 14%);
  }
  /* The couple keeps its soft edges all round; only the strong side moves
     from the left to the top. */
  .book__media--portrait img {
    -webkit-mask-image: linear-gradient(to bottom, transparent, #000 16%, #000 90%, transparent),
                        linear-gradient(to right, transparent, #000 10%, #000 90%, transparent);
            mask-image: linear-gradient(to bottom, transparent, #000 16%, #000 90%, transparent),
                        linear-gradient(to right, transparent, #000 10%, #000 90%, transparent);
  }
}
.callout__number {
  display: inline-block;
  margin-top: var(--s4);
  font-family: var(--ff-num);
  font-size: clamp(2.25rem, 5.6vw, 3.875rem);
  font-weight: 300;
  line-height: 1.1;
  letter-spacing: 0.01em;
  white-space: nowrap;
  color: var(--gold);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color var(--t-fast), border-color var(--t-fast);
}
.callout__number:hover { color: var(--ivory); border-bottom-color: var(--ivory); }
.callout__alt {
  margin: var(--s4) 0 0;
  font-size: 0.9375rem;
  color: var(--muted-dark);
}
.callout__alt a { color: var(--gold); text-underline-offset: 3px; }
.callout__alt a:hover { color: var(--ivory); }

/* ---------------------------------------------------------- breadcrumbs */
.crumbs {
  font-size: 0.75rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--muted); margin: 0 0 var(--s3);
}
.crumbs ol { list-style: none; display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0; padding: 0; }
.crumbs li { display: flex; align-items: center; gap: 0.5rem; }
.crumbs li + li::before { content: "/"; color: var(--hair); }
.crumbs a { color: var(--muted); text-decoration: none; }
.crumbs a:hover { color: var(--gold-deep); }
.crumbs [aria-current] { color: var(--ink); }
.panel--ink .crumbs, .panel--ink .crumbs a { color: var(--muted-dark); }
.panel--ink .crumbs [aria-current] { color: var(--ivory); }

/* ------------------------------------------------- centred page header */
/* Events and areas open on a centred header. The eyebrow gains a matching
   rule on its right so the pair stays symmetrical around the words. */
.crumbs--center ol { justify-content: center; }
.section-head--center { margin-inline: auto; text-align: center; }
.section-head--center .eyebrow { justify-content: center; }
.section-head--center .eyebrow::after {
  content: ""; width: 3rem; height: 1px;
  background: currentColor; opacity: 0.8; flex: none;
}
.section-head--center .eyebrow::before { background: currentColor; }
.section-head--center .lead { margin-inline: auto; }

/* ------------------------------------------------- included-with-booking */
.included {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s5) var(--s6);
  margin-top: var(--s6);
  padding-top: var(--s6);
  border-top: 1px solid var(--hair);
}
.panel--ink .included { border-top-color: var(--hair-light); }
.included__item h2, .included__item h3 {
  font-family: var(--ff-display);
  font-size: 1.25rem; font-weight: 400; margin: 0 0 0.6rem;
}
.included__item p { margin: 0; font-size: 0.9375rem; color: var(--muted); line-height: 1.7; }
.panel--ink .included__item p { color: var(--muted-dark); }
@media (max-width: 700px) { .included { grid-template-columns: minmax(0, 1fr); gap: var(--s4); } }

/* ------------------------------------------------------------------ blog */
/* Posts are typography only, by decision: the site is built around two real
   photographs of David, and AI article images would undercut both. */
.posts { display: grid; gap: var(--s6); max-width: 46rem; }
.posts--compact { gap: var(--s4); margin-top: var(--s5); }
.post { position: relative; padding-top: var(--s4); border-top: 1px solid var(--hair); }
.post__date {
  font-size: 0.75rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--muted); margin: 0 0 0.75rem;
}
.post__title {
  font-family: var(--ff-display);
  font-size: clamp(1.5rem, 2.6vw, 2.15rem);
  font-weight: 400; line-height: 1.2; margin: 0;
}
.posts--compact .post__title { font-size: clamp(1.25rem, 1.9vw, 1.5rem); }
.post__title a { text-decoration: none; transition: color var(--t-fast); }
.post__title a:hover { color: var(--gold); }
.post__excerpt { margin: var(--s2) 0 0; font-size: 0.9375rem; color: var(--muted); line-height: 1.75; }

.blog-empty { max-width: 34rem; }
.blog-empty p { color: var(--muted); margin: 0 0 var(--s4); }
.blog-empty a { color: var(--gold-deep); text-underline-offset: 3px; }
.blog-empty .btn { text-decoration: none; }

/* The article itself. Measure is deliberately narrow: 66 characters is where
   long-form reading stops being work. */
.article { max-width: 42rem; }
.article__head { margin-bottom: var(--s5); }
/* Headlines here are sentences, not two-word section titles, so they run at a
   smaller size than the rest of the site's display type. */
.article__head h1 { font-size: clamp(1.9rem, 3.4vw, 2.75rem); line-height: 1.12; }
.postmeta {
  display: flex; flex-wrap: wrap; gap: 0.75rem var(--s3);
  margin: var(--s3) 0 0; padding-top: var(--s3);
  border-top: 1px solid var(--hair);
  font-size: 0.8125rem; letter-spacing: 0.03em; color: var(--muted);
}

.prose { font-size: 1.0625rem; line-height: 1.8; color: var(--ink); }
.prose > *:first-child { margin-top: 0; }
.prose p { margin: 0 0 var(--s3); }
.prose h2 {
  font-family: var(--ff-display); font-weight: 500;
  font-size: clamp(1.5rem, 2.4vw, 1.9rem); line-height: 1.2;
  margin: var(--s5) 0 var(--s2);
}
.prose h3 {
  font-size: 1.125rem; font-weight: 500; letter-spacing: 0.01em;
  margin: var(--s4) 0 var(--s1);
}
.prose h4 { font-size: 1rem; font-weight: 500; margin: var(--s3) 0 var(--s1); }
.prose ul, .prose ol { margin: 0 0 var(--s3); padding-left: 1.25rem; }
.prose li { margin: 0.35rem 0; }
.prose a { color: var(--gold-deep); text-underline-offset: 3px; }
.prose a:hover { color: var(--ink); }
.prose strong { font-weight: 500; }
.prose blockquote {
  margin: var(--s4) 0; padding: 0 0 0 var(--s3);
  border-left: 2px solid var(--gold);
  font-family: var(--ff-display); font-style: italic;
  font-size: clamp(1.25rem, 1.9vw, 1.5rem); line-height: 1.5; color: var(--ink);
}
.prose blockquote p { margin: 0; }
.prose code {
  font-size: 0.9em; padding: 0.1em 0.35em;
  background: rgba(20, 18, 15, 0.06);
}
.prose pre { overflow-x: auto; padding: var(--s2); background: rgba(20, 18, 15, 0.06); }
.prose pre code { background: none; padding: 0; }

.article__foot {
  margin-top: var(--s6); padding-top: var(--s4);
  border-top: 1px solid var(--hair);
}
.article__foot p { font-size: 0.9375rem; color: var(--muted); margin: 0; max-width: 40rem; }
.article__foot .hero__actions { margin-top: var(--s4); }

/* Soro's embed widget. Its markup is its own, so this stays deliberately
   light: hold it to the reading measure, hand it the site's typography, and
   leave its internals alone. Revisit once static posts replace it. */
.soroblog { max-width: 46rem; }
#soro-blog { font-size: 1.0625rem; line-height: 1.75; color: var(--ink); }
#soro-blog h1, #soro-blog h2, #soro-blog h3 {
  font-family: var(--ff-display); font-weight: 400; line-height: 1.2;
  letter-spacing: -0.005em; color: var(--ink);
}
#soro-blog h1 { font-size: clamp(1.9rem, 3.4vw, 2.75rem); }
#soro-blog h2 { font-size: clamp(1.5rem, 2.4vw, 1.9rem); }
#soro-blog a { color: var(--gold-deep); text-underline-offset: 3px; }
#soro-blog a:hover { color: var(--ink); }
#soro-blog img { max-width: 100%; height: auto; }
/* Their cards should not carry rounded corners or drop shadows into a site
   that has neither. */
#soro-blog * { border-radius: 0 !important; box-shadow: none !important; }

/* ------------------------------------------------------------ 404 / legal */
.doc { max-width: 46rem; margin-inline: auto; }
.doc h2 {
  font-family: var(--ff-display); font-weight: 500;
  font-size: clamp(1.5rem, 2.4vw, 1.9rem);
  margin: var(--s5) 0 var(--s2);
}
.doc h3 { font-size: 1rem; font-weight: 500; margin: var(--s4) 0 var(--s1); letter-spacing: 0.01em; }
.doc p, .doc li { color: var(--muted); }
.doc ul { padding-left: 1.15rem; }
.doc li { padding: 0.2rem 0; }
.doc a { color: var(--gold-deep); text-underline-offset: 3px; }
.doc__meta { font-size: 0.8125rem; color: var(--muted); }

.err { min-height: 70vh; display: grid; place-items: center; text-align: center; }
.err__code {
  font-family: var(--ff-num); font-weight: 300; font-size: clamp(5rem, 18vw, 11rem);
  line-height: 0.9; color: var(--gold); margin: 0;
}

/* ---------------------------------------------------------- reveal motion */
/* One gesture, used consistently: content lifts a short distance while a
   clip opens from the bottom. Nothing bounces, nothing overshoots. */
.reveal {
  opacity: 0;
  transform: translateY(14px);
  clip-path: inset(0 0 12% 0);
  transition: opacity var(--t-slow), transform var(--t-slow), clip-path var(--t-slow);
}
.reveal.is-in { opacity: 1; transform: none; clip-path: inset(0 0 0 0); }
.reveal--d1 { transition-delay: 90ms; }
.reveal--d2 { transition-delay: 180ms; }
.reveal--d3 { transition-delay: 270ms; }

/* Hero opening sequence: the split slides into place, then the lines arrive.
   Both layers keep the clip-paths set above; only transform and opacity move. */
.js .hero__media { animation: seam-in 1100ms var(--ease) both; }
.js .hero__seam { animation: seam-in 1100ms var(--ease) both; }
@keyframes seam-in {
  from { transform: translateX(6%); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
.js .hero__line {
  opacity: 0; transform: translateY(18px);
  animation: line-in 900ms var(--ease) forwards;
}
.js .hero__line--1 { animation-delay: 260ms; }
.js .hero__line--2 { animation-delay: 380ms; }
.js .hero__line--3 { animation-delay: 500ms; }
.js .hero__line--4 { animation-delay: 620ms; }
.js .hero__line--5 { animation-delay: 740ms; }
@keyframes line-in { to { opacity: 1; transform: none; } }

/* ---------------------------------------------------------- breakpoints */
/* As the viewport narrows the seam retreats right and the copy column
   tightens with it, so the text never crosses onto the ink. */
@media (max-width: 1200px) {
  .hero { --hero-top: 72%; --hero-bot: 57%; --hero-copy: 27rem; }
}

@media (max-width: 1024px) {
  /* 26rem, not less: below that the two hero buttons no longer sit on one line. */
  .hero { --hero-top: 80%; --hero-bot: 65%; --hero-copy: 26rem; }
  .events__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .contact__grid { grid-template-columns: 1fr; gap: var(--s6); }
  .footer__top { grid-template-columns: 1fr 1fr; }
  .footer__brand { grid-column: 1 / -1; }
}

@media (max-width: 860px) {
  .hero { --hero-top: 88%; --hero-bot: 74%; --hero-copy: 22rem; }
  .masthead__cta { display: none; }

  /* No-JS fallback. The row of links does not fit, so the header keeps the one
     worth having on its own, and the footer carries the full page list. */
  .nav { gap: 0; }
  .nav__link { display: none; }
  .nav__link--keep { display: inline-block; }

  /* With scripting the button owns navigation, so the lone link steps aside. */
  .js .navtoggle {
    display: grid; place-items: center;
    width: 2.75rem; height: 2.75rem;
    margin-right: -0.5rem;          /* optical alignment to the gutter */
    padding: 0; border: 0; background: none;
    color: var(--ink); cursor: pointer;
  }
  .js .nav__link--keep { display: none; }

  /* The panel. Fixed under the header rather than pushing it taller, so the
     page behind never reflows when it opens. */
  .js .nav {
    position: fixed;
    top: var(--header-h); left: 0; right: 0;
    flex-direction: column;
    align-items: stretch;
    padding: 0 var(--gutter) var(--s3);
    background: var(--ivory);
    border-bottom: 1px solid var(--gold-hair);
    box-shadow: 0 20px 44px rgba(20, 18, 15, 0.12);
    /* Closed. visibility, not just opacity, so the links leave the tab order
       and cannot be reached or read while the panel is shut. */
    visibility: hidden;
    opacity: 0;
    transform: translateY(-0.625rem);
    transition: opacity 260ms var(--ease), transform 260ms var(--ease),
                visibility 0s linear 260ms;
  }
  .js .nav.is-open {
    visibility: visible;
    opacity: 1;
    transform: none;
    transition: opacity 260ms var(--ease), transform 260ms var(--ease),
                visibility 0s;
  }

  .js .nav .nav__link {
    display: block;
    padding: 1.15rem 0;
    font-size: 0.8125rem;
    color: var(--ink);
    border-bottom: 1px solid var(--hair);
  }
  /* The sliding underline belongs to the desktop row; in a bordered stack it
     would just double the rule. */
  .js .nav .nav__link::after { display: none; }
  .js .nav .nav__link[aria-current] { color: var(--gold-deep); }

  /* The header's phone button is hidden at this width, so the number lives at
     the foot of the panel instead. */
  .js .nav__call {
    display: block;
    margin-top: var(--s3);
    font-family: var(--ff-num);
    font-weight: 300;
    font-size: 1.625rem;
    color: var(--gold-deep);
    text-decoration: none;
  }
}

/* Phone: the diagonal turns horizontal. The photo sits on top in ink with a
   diagonal lower edge, the copy below on ivory. Same motif, different
   composition — not the desktop layout squeezed into a column. */
@media (max-width: 760px) {
  :root { --seam: 8vw; --header-h: 3.75rem; }

  body { padding-bottom: 3.5rem; }
  .actionbar { display: grid; }

  .hero {
    min-height: 0;
    display: block;
    padding-bottom: var(--s5);
  }
  .hero__media {
    position: relative; inset: auto;
    /* Kept deliberately short so the headline and the first lines of the
       promise clear the fold on a small phone. */
    height: 38vh; min-height: 14rem; max-height: 20rem;
    clip-path: polygon(0 0, 100% 0, 100% calc(100% - var(--seam)), 0 100%);
  }
  .hero__seam {
    inset: auto 0 0; height: calc(var(--seam) + 3px);
    clip-path: polygon(0 100%, 100% calc(100% - var(--seam)),
                       100% calc(100% - var(--seam) + 1.5px), 0 calc(100% + 1.5px));
  }
  .hero__photo {
    position: absolute; right: 0; top: 0; bottom: auto;
    width: auto; height: 100%;
    -webkit-mask-image: linear-gradient(to left, #000 58%, transparent 100%);
            mask-image: linear-gradient(to left, #000 58%, transparent 100%);
  }
  .hero__copy { padding-top: var(--s5); }
  .hero__inner { max-width: none; }
  .hero__scroll { display: none; }
  .hero__actions .btn { flex: 1 1 100%; }

  .panel { padding: var(--s7) var(--gutter); }
  .panel--seam { padding-top: calc(var(--s7) + var(--seam)); }

  .track__btn {
    grid-template-columns: 1.75rem 1fr 2.25rem;
    gap: var(--s2);
    padding: 1.15rem 0;
  }
  .track__time { display: none; }
  .track__icon { width: 2.25rem; height: 2.25rem; }

  .form__row { grid-template-columns: 1fr; }
  .footer__top { grid-template-columns: 1fr; gap: var(--s4); }
  .rating__score { font-size: 2.5rem; }
}

@media (max-width: 620px) {
  .events__grid { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 420px) {
  .brand__name { font-size: 0.8125rem; letter-spacing: 0.07em; }
}

/* ----------------------------------------------------------- reduced motion */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .reveal { opacity: 1; transform: none; clip-path: none; }
  .js .hero__line { opacity: 1; transform: none; }
}

/* ------------------------------------------------------------------ print */
@media print {
  .masthead, .actionbar, .hero__scroll, .track__icon, .form, .notes { display: none; }
  .panel--ink { background: #fff; color: #000; }
  .panel--seam { clip-path: none; margin-top: 0; }
}
