/* ==========================================================================
   Vegas Magic Squad
   Deco theatre marquee + the printed bill. Two materials, one world.
   ========================================================================== */

/* Both self-hosted rather than pulled from Google's CDN: the site has to open
   straight off the filesystem and drop onto any static host, and a webfont on
   a third-party origin is an extra DNS lookup and TLS handshake in front of
   the first paint. These are the latin subsets of the variable faces. */
@font-face{
  font-family:"Josefin Sans";
  src:url("fonts/JosefinSans-var-latin.woff2") format("woff2-variations");
  /* The real axis stops at 700. Declaring it honestly matters: overstate it and
     the browser is asked for a weight the file cannot produce, and some engines
     answer with a synthetic smeared bold instead of clamping. */
  font-weight:100 700; font-style:normal; font-display:swap;
}
@font-face{
  font-family:"Montserrat";
  src:url("fonts/Montserrat-var-latin.woff2") format("woff2-variations");
  font-weight:100 900; font-style:normal; font-display:swap;
}

:root{
  /* night: the street outside, the house during the show */
  --night:#07090f;
  --night-2:#0d1119;
  --night-3:#161c29;
  --night-tx:#efe9dd;
  --night-tx2:#a89c89;

  /* the brand gold, sampled from the logo */
  --gold:#c8a850;
  --gold-hi:#e6d193;
  --gold-deep:#8a6d2c;
  --gold-ink:#2a2008;

  /* bill: the printed handbill */
  --bill:#f2ece0;
  --bill-2:#e6ddcb;
  --ink:#14100c;
  --ink-2:#574c3c;

  /* second ink, bound to the primary action only */
  --red:#a8141d;
  --red-hi:#c4212b;

  --disp:"Josefin Sans","Century Gothic","Helvetica Neue",Arial,sans-serif;
  --text:"Montserrat",system-ui,-apple-system,"Segoe UI",Arial,sans-serif;

  --trim:clamp(34px,7.9vw,150px);
  --pad:clamp(20px,5vw,72px);
  --wrap:1320px;
  --ease:cubic-bezier(.16,1,.3,1);
  --bulb-size:9px;
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%; scroll-behavior:smooth; scroll-padding-top:86px}
body{
  margin:0; background:var(--night); color:var(--night-tx);
  font-family:var(--text); font-size:clamp(15px,.35vw + 14px,17px);
  line-height:1.62; -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img{max-width:100%; display:block; height:auto}
.sprite{position:absolute; width:0; height:0; overflow:hidden}
h1,h2,h3{margin:0; font-weight:400; line-height:.94}
p{margin:0}
ul,ol,dl{margin:0; padding:0; list-style:none}
a{color:inherit}

/* ---- browser surfaces, themed ---- */
::selection{background:var(--gold); color:var(--gold-ink)}
:focus-visible{outline:2px solid var(--gold-hi); outline-offset:3px; border-radius:1px}
html{scrollbar-color:var(--gold-deep) var(--night); scrollbar-width:thin}
::-webkit-scrollbar{width:11px; height:11px}
::-webkit-scrollbar-track{background:var(--night)}
::-webkit-scrollbar-thumb{background:var(--gold-deep); border:3px solid var(--night)}
::-webkit-scrollbar-thumb:hover{background:var(--gold)}

.skip{
  position:fixed; left:12px; top:-100px; z-index:200;
  background:var(--gold); color:var(--gold-ink); padding:12px 18px;
  font:600 13px/1 var(--text); letter-spacing:.14em; text-transform:uppercase;
  text-decoration:none; transition:top .18s var(--ease);
}
.skip:focus{top:12px}

.wrap{max-width:var(--wrap); margin-inline:auto; padding-inline:var(--pad)}

/* ==========================================================================
   Marquee bulbs : the one authored motion grammar
   ========================================================================== */
.bulb{
  --on:.26;
  position:relative; flex:0 0 auto;
  width:var(--bulb-size); height:var(--bulb-size); border-radius:50%;
  background:var(--gold-hi); opacity:var(--on);
  animation:chase 2.6s linear infinite; animation-delay:var(--d,0s);
}
@keyframes chase{
  0%,92%,100%{opacity:.44; box-shadow:0 0 4px 0 rgba(230,209,147,.3)}
  4%{opacity:1; box-shadow:0 0 13px 3px rgba(230,209,147,.92), 0 0 28px 9px rgba(200,168,80,.44)}
  40%{opacity:.52; box-shadow:0 0 6px 1px rgba(230,209,147,.34)}
}
.bulbs{display:flex; gap:clamp(11px,1.5vw,20px); pointer-events:none}

/* The only bulbs left are the footer strip — the hero's chasing frame was
   removed. .bulb, .bulbs and @keyframes chase above are still live for it. */

/* section rules ignite with the same filament grammar */
.ignite{--lit:0}
.ignite.is-lit{--lit:1}

/* ==========================================================================
   Buttons
   ========================================================================== */
.btn{
  --bg:transparent; --fg:var(--night-tx); --bd:currentColor;
  display:inline-flex; align-items:center; justify-content:center; gap:.6em;
  padding:.92em 1.5em; min-height:46px;
  background:var(--bg); color:var(--fg);
  border:1.5px solid var(--bd); border-radius:0;
  font-family:var(--text); font-size:clamp(11px,.9vw,12.5px); font-weight:700;
  letter-spacing:.2em; text-transform:uppercase; text-decoration:none;
  cursor:pointer; white-space:nowrap;
  transition:background .22s var(--ease), color .22s var(--ease),
             border-color .22s var(--ease), transform .12s var(--ease);
}
.btn:hover{transform:translateY(-1px)}
.btn:active{transform:translateY(1px)}
.btn--lg{padding:1.08em 1.9em; min-height:54px; font-size:clamp(11px,1vw,13px)}
.btn--block{width:100%}

.btn--red{--bg:var(--red); --fg:#fdf6ea; --bd:var(--red)}
.btn--red:hover{--bg:var(--red-hi); --bd:var(--red-hi)}

.btn--gold{--bg:var(--gold); --fg:var(--gold-ink); --bd:var(--gold)}
.btn--gold:hover{--bg:var(--gold-hi); --bd:var(--gold-hi)}

/* Currently unused: every secondary button on the page was switched to the
   solid .btn--gold. Kept because it is a real variant of the system, not dead
   weight — bring it back by swapping the class, nothing else. */
.btn--ghost{--bg:transparent; --fg:var(--gold-hi); --bd:var(--gold-deep)}
.btn--ghost:hover{--bg:rgba(200,168,80,.13); --bd:var(--gold)}

.btn[disabled]{opacity:.5; cursor:not-allowed; transform:none}
/* .btn sets display:inline-flex, which is an AUTHOR rule and therefore beats
   the user agent's [hidden]{display:none} outright - origin wins before
   specificity is even consulted. So any .btn carrying the hidden attribute
   stayed visible. The lightbox hit this and was patched locally
   (.lb__vid[hidden]); it was never fixed at the source.

   Two buttons were affected: "Read more reviews", which showed with nothing to
   reveal, and "Choose a time" on the booking confirmation, which rendered as a
   live control pointing at href="#" because CALENDAR_URL is still empty. */
.btn[hidden]{display:none !important}
.btn__spin{display:none; width:15px; height:15px; border:2px solid rgba(253,246,234,.35);
  border-top-color:#fdf6ea; border-radius:50%; animation:spin .7s linear infinite}
.is-sending .btn__spin{display:block}
@keyframes spin{to{transform:rotate(360deg)}}

/* ==========================================================================
   Nav
   ========================================================================== */
.nav{
  position:fixed; inset:0 0 auto; z-index:100;
  background:rgba(7,9,15,.9); backdrop-filter:blur(10px);
  border-bottom:1px solid rgba(200,168,80,.3);
  padding-top:env(safe-area-inset-top,0px);
}
.nav__in{
  max-width:var(--wrap); margin-inline:auto; padding-inline:var(--pad);
  height:72px; display:flex; align-items:center; gap:clamp(14px,2.4vw,34px);
}
/* Mark only — the wordmark beside it was removed. margin-right:auto is what
   pushes the links and the CTA to the right, so it stays. */
.nav__brand{display:flex; align-items:center; text-decoration:none; margin-right:auto}
.nav__brand img{width:38px; height:auto}
.nav__links{display:flex; gap:clamp(16px,2vw,30px)}
.nav__links a{
  font-size:11.5px; font-weight:600; letter-spacing:.2em; text-transform:uppercase;
  color:var(--night-tx2); text-decoration:none; padding:7px 0;
  border-bottom:1.5px solid transparent; transition:color .2s var(--ease), border-color .2s var(--ease);
}
.nav__links a:hover{color:var(--gold-hi); border-bottom-color:var(--gold)}
.nav__cta{padding:.78em 1.25em; min-height:40px}
.nav__toggle{display:none; background:none; border:1px solid rgba(200,168,80,.4); padding:10px 9px; cursor:pointer}
.nav__toggle span{display:block; width:20px; height:1.5px; background:var(--gold); margin:4px 0; transition:transform .25s var(--ease), opacity .2s}
.nav__toggle[aria-expanded="true"] span:nth-child(1){transform:translateY(5.5px) rotate(45deg)}
.nav__toggle[aria-expanded="true"] span:nth-child(2){opacity:0}
.nav__toggle[aria-expanded="true"] span:nth-child(3){transform:translateY(-5.5px) rotate(-45deg)}

/* ==========================================================================
   Hero : the marquee
   ========================================================================== */
.hero{
  position:relative; min-height:100svh; display:flex;
  padding:calc(72px + env(safe-area-inset-top,0px)) 0 0;
  overflow:hidden; isolation:isolate;
}
.hero__pic{position:absolute; inset:0; z-index:-2}
/* The looping background film. Same layer as the poster picture and later in
   the DOM, so it covers it once it has a frame. Decoration only. */
.hero__vid{
  position:absolute; inset:0; z-index:-2;
  width:100%; height:100%; object-fit:cover; pointer-events:none;
}
.hero__img{
  width:100%; height:100%;
  object-fit:cover; object-position:58% 32%;
  /* a slow push-in on load. `both` holds the end frame so it settles
     rather than snapping back, and the hero clips the overflow. */
  animation:heroZoom 3.4s cubic-bezier(.25,.46,.45,.94) both;
}
@keyframes heroZoom{
  from{transform:scale(1)}
  to{transform:scale(1.075)}
}

/* Inverted from what it was. The old scrim was heaviest at the top (94%)
   and through the middle, which is precisely where the faces sit — it was
   dimming the photograph's best asset to make room for text that has now
   moved. It is light across the top and middle, and does its darkening at the
   bottom where the copy actually sits. The nav carries its own background, so
   the top does not need much. */
.hero__scrim{
  position:absolute; inset:0; z-index:-1;
  background:
    linear-gradient(to bottom, rgba(7,9,15,.52) 0%, rgba(7,9,15,.16) 16%, rgba(7,9,15,.04) 36%, rgba(7,9,15,.30) 56%, rgba(7,9,15,.86) 78%, var(--night) 100%),
    linear-gradient(to right, rgba(7,9,15,.52) 0%, rgba(7,9,15,.06) 30%, rgba(7,9,15,.06) 70%, rgba(7,9,15,.52) 100%);
}

/* Bottom-aligned, not centred. Centred put the headline straight across the
   performers' faces — the single most valuable part of the photograph and the
   reason it was chosen. With the strapline gone and the lede down to one line,
   the whole bill now fits the lower third and leaves the faces clear. */
.hero__bill{
  position:relative; z-index:4; width:100%;
  padding:clamp(66px,9vw,132px) clamp(46px,8.4vw,142px) clamp(42px,6vw,86px);
  display:flex; flex-direction:column; justify-content:flex-end; align-items:center;
  text-align:center;
}
.hero__col{
  width:100%; max-width:1040px; margin:0 auto;
  display:flex; flex-direction:column; align-items:center;
}
/* A soft pool of night behind the headline. The hero film puts lit faces
   right behind "MAGIC" for a few seconds of every loop (the first cut's
   shot 2 took phones from 5:1 to 2.2:1; the 8-shot cut's worst is 3.9:1 at
   1440 with the pool in place). The pool is attached to the
   headline itself, so it follows it at every breakpoint, and it is radial and
   feathered so it reads as the stage falling off around the title rather than
   as a box. */
.bill__top{position:relative; isolation:isolate}
.bill__top::before{
  content:""; position:absolute; z-index:-1; pointer-events:none;
  inset:-34% -14%;
  background:radial-gradient(closest-side, rgba(7,9,15,.72) 0%, rgba(7,9,15,.6) 45%, rgba(7,9,15,.28) 75%, rgba(7,9,15,0) 100%);
}

/* The title is the logo. Its height follows the viewport's shorter side so
   the lede, buttons and reel strip still fit under it on a laptop. */
.bill__name{margin-inline:auto; line-height:0}
/* centred inside the H1: the keyword line below is wider than the logo, so
   the H1 sizes to the line and the logo would otherwise sit at its left */
.bill__name .mark{margin-inline:auto}

/* The logo mark and its entrance rig, designed in logo-intro/ (HyperFrames).
   The image is the logo; bloom, sheen and glint are the entrance layers,
   played by script.js (3b). Resting state: logo lit, a low warm bloom. */
.mark{
  position:relative; display:block;
  height:clamp(150px, min(31vh, 46vw), 340px); aspect-ratio:560 / 697;
}
.mark__img, .mark__bloom, .mark__sheen{position:absolute; inset:0; width:100%; height:100%}
.mark__img{
  display:block; object-fit:contain;
  filter:drop-shadow(0 2px 0 rgba(42,32,8,.55)) drop-shadow(0 14px 40px rgba(0,0,0,.55));
  /* Hidden until script.js plays the entrance, which cancels this. If the
     script never runs, the logo still fades in on its own. */
  animation:mark-fallback .9s ease 1.5s both;
}
@keyframes mark-fallback{from{opacity:0} to{opacity:1}}
.mark__bloom{
  background:url("images/site/logo.png") center / contain no-repeat;
  filter:blur(22px) brightness(1.35); opacity:.2; pointer-events:none; z-index:-1;
}
/* the light sweep: a soft band, clipped to the logo's own shape */
.mark__sheen{
  overflow:hidden; pointer-events:none;
  -webkit-mask:url("images/site/logo.png") center / contain no-repeat;
          mask:url("images/site/logo.png") center / contain no-repeat;
}
.mark__band{
  position:absolute; top:-20%; bottom:-20%; left:0; width:42%;
  background:linear-gradient(100deg, rgba(255,246,220,0) 22%, rgba(255,246,220,.85) 50%, rgba(255,246,220,0) 78%);
  mix-blend-mode:screen; transform:translateX(-120%) skewX(-14deg);
}
/* the glint, centred on the star's apex (measured from logo.png: 71.3%, 0.1%) */
.mark__glint{
  position:absolute; left:71.3%; top:1%; width:30%; aspect-ratio:1;
  transform:translate(-50%,-50%) scale(0); opacity:0; pointer-events:none;
}
.mark__glint svg{display:block; width:100%; height:100%; overflow:visible}
/* ONE line and one diamond. It was two stacked rules with a lozenge sitting on
   the join, which read as a bar rather than a divider.

   Deliberately the same ornament as .fleuron, the small divider under "Real
   rooms, real reactions", just at full content width: a hairline that fades to
   nothing at both ends with a rotated square centred on it. Two devices doing
   the same job in two different shapes is what made the page feel assembled.

   The <i> children are kept because the markup is shared across six sections;
   the first draws the line, the second is folded away rather than left to
   stack a second rule. The diamond is centred with absolute positioning plus
   a translate, so nothing depends on a hand-tuned margin. */
.rulepair{
  position:relative;
  display:block;
  width:100%; height:9px;
  margin:clamp(20px,2.6vw,34px) 0 clamp(18px,2.2vw,28px);
}
.rulepair i{
  display:block; position:absolute; left:0; right:0; top:50%;
  height:1px; margin-top:-0.5px;
  background:linear-gradient(90deg, transparent, var(--gold) 22%, var(--gold) 78%, transparent);
}
/* the second <i> is markup this component cannot drop; it draws nothing */
.rulepair i + i{display:none}
.rulepair::after{
  content:""; position:absolute; left:50%; top:50%;
  width:9px; height:9px;
  transform:translate(-50%,-50%) rotate(45deg);
  background:var(--gold);
}

.sec--bill .rulepair--sec i{background:linear-gradient(90deg, transparent, var(--ink) 22%, var(--ink) 78%, transparent)}
.sec--bill .rulepair--sec::after{background:var(--ink)}

/* Tight to the title. This block holds the subtitle and the buttons, and at
   58px it left the subtitle floating mid-air rather than reading as a line
   belonging to the name above it. The breathing room the hero needs is below
   the subtitle, not above it. */
/* The H1's visible keyword line, under the logo. Small, gold and tracked so
   the logo stays the title on screen while the heading still says what the
   page is about. The H1 itself is line-height:0 (it only held the logo), so
   the line sets its own. */
.bill__kw{
  display:block; margin:clamp(16px,1.6vw,24px) auto 0; max-width:34ch;
  font-family:var(--disp); font-size:clamp(17px,1.9vw,27px); font-weight:600;
  line-height:1.26; letter-spacing:.06em; text-transform:uppercase; color:var(--night-tx);
  text-shadow:0 2px 6px rgba(7,9,15,.85), 0 0 22px rgba(7,9,15,.6);
  text-wrap:balance;
}
/* the tagline that used to sit here repeated the H1 line above; with it gone,
   this margin is the gap it used to give the buttons */
.bill__foot{width:100%; margin-top:clamp(26px,3.2vw,40px)}
.bill__acts{display:flex; flex-wrap:wrap; justify-content:center; gap:14px}

/* the marquee strikes once on load, tier by tier */
.strike{opacity:0; animation:strike .72s var(--ease) forwards; animation-delay:calc(var(--s) * .13s + .1s)}
@keyframes strike{
  0%{opacity:0; filter:brightness(2.4)}
  38%{opacity:1; filter:brightness(1.5)}
  55%{opacity:.72; filter:brightness(.9)}
  100%{opacity:1; filter:brightness(1)}
}


/* ==========================================================================
   Showreel strip : three cards under the hero buttons
   Ported from the Kent Axell site. Hover behaviour and the play badge are
   carried over; the materials are this site's — square corners, gold hairline,
   gold badge. Kent's badge was red; here --red is bound to the primary action
   only, and three play badges would spend that binding, so the badge is gold.
   ========================================================================== */
.reelgrid{
  display:grid; grid-template-columns:repeat(3,1fr);
  gap:clamp(10px,1.4vw,18px);
  /* Deliberately narrow. This sits inside a 100svh hero, so the strip is
     capped rather than filling the column — otherwise the hero outgrows the
     viewport on a laptop and the bill stops reading as one poster. */
  width:100%; max-width:min(760px,100%);
  margin:clamp(26px,3.4vw,44px) auto 0;
}
.reel{
  position:relative; display:block; overflow:hidden;
  background:var(--night-2);
  border-radius:0;              /* the deco world has no rounded corners */
}
.reel img{
  width:100%; aspect-ratio:16/10; object-fit:cover;
  filter:brightness(.62) saturate(.85);
  transition:transform .8s var(--ease), filter .5s var(--ease);
}
.reel:hover img,
.reel:focus-visible img{filter:brightness(.86) saturate(1); transform:scale(1.06)}
.reel::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  box-shadow:inset 0 0 0 1px rgba(200,168,80,.26);
  transition:box-shadow .35s var(--ease);
}
.reel:hover::after,
.reel:focus-visible::after{box-shadow:inset 0 0 0 1px var(--gold)}

.reel__play{
  position:absolute; left:50%; top:50%; translate:-50% -50%;
  width:clamp(38px,3.4vw,52px); aspect-ratio:1; border-radius:50%;
  background:var(--gold); display:grid; place-items:center;
  box-shadow:0 10px 30px -10px rgba(0,0,0,.85);
  transition:transform .35s var(--ease), background-color .35s var(--ease);
}
.reel__play svg{width:42%; height:42%; fill:var(--gold-ink); margin-left:6%}
.reel:hover .reel__play,
.reel:focus-visible .reel__play{transform:scale(1.12); background:var(--gold-hi)}

.reel__label{
  position:absolute; left:10px; top:9px;
  font-family:var(--text); font-size:10px; font-weight:800;
  text-transform:uppercase; letter-spacing:.16em; color:var(--night-tx);
  background:rgba(7,9,15,.72); backdrop-filter:blur(6px);
  padding:5px 9px;
}

@media (max-width:720px){
  /* Stacking three 16:10 cards would add ~600px to a hero that is already
     100svh, so the strip becomes a swipeable rail instead. Native overflow
     scrolling on purpose: momentum, rubber-band and snap are the platform's,
     and a finger can interrupt the autoplay because the autoplay is only
     writing scrollLeft rather than driving a transform the touch can't reach. */
  .reelgrid{
    display:flex; overflow-x:auto; scroll-snap-type:x mandatory;
    max-width:none; margin-inline:0;
    padding-bottom:6px; -webkit-overflow-scrolling:touch;
    scrollbar-width:none;
    /* a swipe past the last card must not trigger the browser's back gesture */
    overscroll-behavior-x:contain;
  }
  .reelgrid::-webkit-scrollbar{display:none}
  /* start, not centre: the next card peeks in at the right edge, which is what
     tells a thumb the strip moves at all. */
  .reel{flex:0 0 72%; scroll-snap-align:start}
  /* Snapping is suspended for the length of each auto-glide — mandatory snap
     re-snaps under per-frame scrollLeft writes and the tween stutters. It goes
     back on the moment the glide lands, always exactly on a snap point. */
  .reelgrid.is-gliding{scroll-snap-type:none}
  /* Clones exist only to make the leftward loop seamless. They stay fully
     tappable — they are the same link, and a card that looks live but eats
     the tap is worse than a duplicate. They are out of the tab order and the
     a11y tree instead (script.js, aria-hidden + tabindex="-1"). */
}

/* ==========================================================================
   Legal pages : privacy policy, terms & conditions
   Long-form reading, so the measure is tight and the rhythm is generous.
   Everything else is borrowed from the existing system.
   ========================================================================== */
.legalpage{padding-top:calc(72px + env(safe-area-inset-top,0px))}
/* 404: the legal-page shell, centred, with the three ways out most people want */
.notfound .sec{min-height:min(78vh,760px); display:grid; align-items:center}
.notfound__in{text-align:center}
.notfound__h{margin-inline:auto; margin-bottom:.4em}
.notfound__p{max-width:46ch; margin:0 auto; font-size:clamp(16px,.3vw + 15px,18px); line-height:1.65; color:var(--night-tx2)}
.notfound__acts{display:flex; flex-wrap:wrap; justify-content:center; gap:12px; margin-top:clamp(26px,3vw,40px)}
.notfound__home{--fg:var(--gold-hi); --bd:rgba(200,168,80,.45)}
.notfound__home:hover{--bd:var(--gold)}
.legal{max-width:68ch; margin-inline:auto}
.legal__lede{
  margin:0 0 clamp(30px,4vw,46px);
  padding:18px 20px;
  background:var(--night-2);
  border-left:3px solid var(--gold);
  font-size:16px; line-height:1.68; color:var(--night-tx);
}
.legal h3{
  margin:clamp(30px,4vw,44px) 0 .5em;
  font-family:var(--disp); font-size:clamp(17px,2vw,21px); font-weight:700;
  letter-spacing:.02em; color:var(--gold-hi);
}
.legal p{margin:0 0 1em; font-size:15.5px; line-height:1.72; color:var(--night-tx2)}
.legal p a{color:var(--gold-hi); text-underline-offset:3px}
.legal p a:hover{color:var(--gold)}
/* The [CONFIRM] markers must be impossible to publish by accident. */
.legal strong{color:var(--gold-hi); font-weight:600}
.legal__list{
  margin:0 0 1.2em; padding:0; list-style:none;
  display:flex; flex-direction:column; gap:.55em;
}
.legal__list li{
  position:relative; padding-left:20px;
  font-size:15.5px; line-height:1.6; color:var(--night-tx2);
}
.legal__list li::before{
  content:""; position:absolute; left:0; top:.68em;
  width:10px; height:1px; background:var(--gold-deep);
}
.legal__cta{
  display:flex; flex-wrap:wrap; gap:14px; justify-content:center;
  margin:clamp(40px,5.5vw,64px) 0 0;
}

/* Footer legal links, on every page */
.foot__legalnav{display:flex; flex-wrap:wrap; gap:8px 22px}
.foot__legalnav a{
  color:var(--night-tx2); text-decoration:none;
  border-bottom:1px solid rgba(200,168,80,.28);
  transition:color .2s var(--ease), border-color .2s var(--ease);
}
.foot__legalnav a:hover{color:var(--gold-hi); border-bottom-color:var(--gold)}

/* The consent line under the booking form */
.formlegal{
  margin:14px 0 0; font-size:12.5px; line-height:1.6; color:var(--night-tx2);
}
.formlegal a{color:var(--gold-hi); text-underline-offset:3px}
.formlegal a:hover{color:var(--gold)}

/* ==========================================================================
   Deliberate headlines
   The base .h2 allows up to 4.4rem and caps the measure at 18ch. At that size
   "LET'S FIND THE RIGHT" is wider than the 720px form column, so the browser
   broke it wherever it happened to fit — stranding "RIGHT" alone on a line and
   pushing "ENTERTAINMENT" past the column edge.

   Fixed two ways at once: the line breaks are authored rather than left to
   chance, and the ceiling is lowered so the longest authored line fits the
   column it sits above. --col is set per section, so the headline, the
   sub-headline and the form all share one width and their edges line up.
   ========================================================================== */
/* .h2.hl, not .hl. This rule used to be written as plain .hl and was dead:
   .h2 is the same specificity and sits later in this sheet, so .h2 won every
   property the two shared — font-size, max-width, line-height. The headline
   was rendering at .h2's 5.4vw inside .h2's 18ch box, which is what broke it
   onto four ragged lines. Two classes beats one, whatever the order.

   Only the three properties that need to differ are set here. line-height,
   letter-spacing and margin-bottom are deliberately left to .h2 so this
   headline keeps the same weight and spacing as every other on the site.

   THE SIZE IS DERIVED, NOT GUESSED. Measured in the browser, the longest line
   is "entertainment for you" at 14.07em, and its container is a .wrap, so the
   width available is 0.9 x viewport up to 1320px. One line therefore fits
   while font-size stays under viewport*0.9/14.07 = 6.4vw. 5.8vw holds about
   10% in reserve, which is the margin for the fallback face if Josefin has
   not loaded. The 4.4rem cap is .h2's own maximum, so desktop is unchanged. */
.h2.hl{
  max-width:none;
  margin-inline:auto;
  text-align:center;
  font-size:clamp(1.75rem, 5.8vw, 4.4rem);
}
/* One authored line each, and nowrap so neither can split further. The nowrap
   is safe only because the font-size above is derived from the longest line —
   without that pairing, nowrap is just a way to overflow the page. */
.hl__l{display:block; white-space:nowrap}

@media (max-width:479px){
  /* Under 480 the two lines cannot both fit at a size worth reading — holding
     them would mean dropping below about 1.75rem, which the design will not
     take. So the authored breaks come off, the spans fall back to inline, the
     whitespace between them in the markup becomes the space, and
     text-wrap:balance (from .h2) splits the phrase evenly instead.

     This is the one width where the headline is not two lines, and that is the
     intended behaviour rather than a fallback that got missed. */
  .hl__l{display:inline; white-space:normal}
}

/* ==========================================================================
   Call-request form : the one conversion point, directly under the hero
   ========================================================================== */
.callform{padding-block:clamp(44px,6vw,80px)}
.callform{--col:720px}
.callform__in{max-width:var(--col); margin-inline:auto}
.callform__head{text-align:center; margin-bottom:clamp(24px,3.2vw,36px)}
.callform__sub{
  margin:0 auto; max-width:var(--col);
  font-size:16px; line-height:1.62; color:var(--night-tx2);
}
.opt{
  margin-left:6px; font-family:var(--text); font-size:10px; font-weight:700;
  letter-spacing:.14em; text-transform:uppercase; color:var(--night-tx2);
}
.callform__direct{
  margin:clamp(22px,3vw,30px) 0 0; text-align:center;
  font-size:13.5px; color:var(--night-tx2);
}
.callform__direct a{color:var(--gold-hi); text-underline-offset:3px}
.callform__direct a:hover{color:var(--gold)}

/* Step two. Hidden until the lead is saved, then revealed in place - it
   replaces nothing, so a visitor can see their request was received without
   the page having navigated anywhere. */
.callform__done{
  margin:clamp(22px,3vw,32px) 0 0; padding:clamp(22px,3vw,30px);
  background:var(--night-2); border:1px solid rgba(200,168,80,.3);
  text-align:center;
}
.callform__done:focus{outline:none}
.callform__done:focus-visible{outline:2px solid var(--gold); outline-offset:3px}
.callform__doneh{
  margin:0 0 .5em; font-family:var(--disp); font-weight:700;
  font-size:clamp(18px,2.2vw,24px); color:var(--gold-hi); letter-spacing:.01em;
}
.callform__donep{margin:0 auto; max-width:46ch; font-size:15px; color:var(--night-tx2)}
.callform__donecta{margin:clamp(16px,2.2vw,24px) 0 0}

/* ==========================================================================
   Final call : returns to the form above rather than opening a second one
   ========================================================================== */
.finalcall{padding-block:clamp(48px,7vw,96px); text-align:center}
.finalcall{--col:620px}
/* Full wrap width, not --col, so the headline inside has room for its two
   lines. Nothing else here widens with it: .finalcall__sub carries its own
   max-width:var(--col), and the CTA is a centred button in a centred section. */
.finalcall__in{max-width:var(--wrap); margin-inline:auto}
.finalcall__sub{
  margin:0 auto; max-width:var(--col); font-size:16px; line-height:1.62;
  color:var(--night-tx2);
}
.finalcall__cta{margin:clamp(24px,3vw,34px) 0 0}

/* Performers intro: the copy that stops three names reading as the whole
   roster, or as a fixed package. */
.lineup__lede{
  max-width:60ch; margin:0 auto clamp(14px,1.8vw,20px);
  text-align:center; font-size:16px; line-height:1.68; color:var(--night-tx2);
}
.lineup__note{
  margin:0 auto clamp(26px,3.4vw,40px); text-align:center;
  font-family:var(--disp); font-size:12px; font-weight:600;
  letter-spacing:.18em; text-transform:uppercase; color:var(--gold);
}

/* ==========================================================================
   Video lightbox
   A native <dialog>, so Escape, the focus trap and the inert backdrop come
   from the platform rather than from code that has to remember them.
   ========================================================================== */
.lb{
  border:0; padding:0; background:transparent;
  max-width:min(1100px, 94vw); width:100%;
  /* Keeps the panel inside the viewport so a <dialog> tall enough to pin to
     the top edge cannot push anything past it. */
  max-height:94vh;
  color:var(--night-tx);
}
.lb::backdrop{background:rgba(3,4,8,.88); backdrop-filter:blur(4px)}
.lb__in{position:relative; display:flex; flex-direction:column; gap:12px}

/* The title row is sized to match the close button, so the two sit on one
   line without the button needing to be nudged upwards. A negative `top` was
   doing that job before, and it hung the button's border outside the panel —
   which the viewport clipped the moment the dialog grew tall enough to sit
   against the top of the screen. */
/* Gallery images carry no title. The row still has to clear the close button
   when it IS empty, so the height stays — but the padding only matters when
   there is text to keep off the button. */
.lb__title{
  margin:0;
  min-height:40px; display:flex; align-items:center;
  padding-right:52px;
  font-family:var(--disp); font-size:clamp(13px,1.5vw,17px);
  font-weight:700; letter-spacing:.14em; text-transform:uppercase;
  color:var(--gold-hi);
}
/* Both slots set display:block, and a class rule beats the user agent's
   [hidden]{display:none} — so toggling .hidden did nothing and the empty
   video player stayed on screen above every gallery image. Specificity of
   (0,2,0) here puts that right. */
.lb__vid[hidden],
.lb__img[hidden]{display:none}

/* The image slot matches the video slot, so switching between them does not
   move the panel or the close button. */
.lb__img{
  width:100%; height:auto;
  max-height:min(76vh, calc(94vh - 72px));
  display:block; object-fit:contain; background:#000;
  border:1px solid rgba(200,168,80,.35);
}
.lb__vid{
  width:100%; height:auto;
  /* room for the title row, the flex gap and the dialog's own margin, so the
     panel always fits and never overflows off the top */
  max-height:min(76vh, calc(94vh - 72px));
  display:block; background:#000;
  border:1px solid rgba(200,168,80,.35);
}
.lb__x{
  position:absolute; top:0; right:0;
  width:40px; height:40px; line-height:1;
  display:grid; place-items:center;
  font-size:26px; font-family:var(--text);
  background:transparent; color:var(--gold-hi);
  border:1px solid rgba(200,168,80,.4);
  cursor:pointer;
  transition:background .2s var(--ease), color .2s var(--ease);
}
.lb__x:hover{background:var(--gold); color:var(--gold-ink)}
.lb__x:focus-visible{outline:2px solid var(--gold); outline-offset:2px}

@media (max-width:600px){
  .lb{max-width:100vw}
  .lb__title{font-size:11px; padding-right:48px; min-height:36px}
  .lb__x{width:36px; height:36px; font-size:22px}
  .lb__vid{max-height:min(66vh, calc(94vh - 68px))}
}

/* ==========================================================================
   Sections + guillotine trims
   ========================================================================== */
.sec{position:relative; padding-block:clamp(64px,9vw,140px)}
.sec--night{background:var(--night); color:var(--night-tx)}
.sec--bill{background:var(--bill); color:var(--ink)}
.trim-top{
  clip-path:polygon(0 var(--trim), 100% 0, 100% 100%, 0 100%);
  margin-top:calc(var(--trim) * -1);
  padding-top:calc(clamp(64px,9vw,140px) + var(--trim));
}

.h2{
  font-family:var(--disp); font-weight:700; text-transform:uppercase; color:var(--ink);
  font-size:clamp(1.85rem,5.4vw,4.4rem); line-height:.96; letter-spacing:.006em;
  margin-bottom:clamp(28px,4vw,56px); max-width:18ch; text-wrap:balance;
}
.h2--gold{color:var(--gold-hi)}
.h2--big{font-size:clamp(2.1rem,6.6vw,5.6rem)}

/* ==========================================================================
   The room : full-bleed proof
   ========================================================================== */
/* Column, not row: the tilted band now lives inside this section as a second
   in-flow child after .room__in, and a row axis would sit the two side by side.
   justify-content:flex-end keeps the copy bottom-anchored as it was. */
.sec--room{
  position:relative; isolation:isolate; min-height:clamp(440px,76vh,780px);
  display:flex; flex-direction:column; justify-content:flex-end;
  /* The gold band inside is width:114% with -7% inline margins, so it runs from
     -7% to 107% of this section. The left 7% is invisible because nothing
     scrolls past zero, but the right 7% became real scrollable width and read
     as a dead gap down the side of the page. This section is full-bleed, so
     its edges ARE the viewport edges and clipping here confines the band
     exactly.

     clip, not hidden, and that distinction matters: `overflow-x: hidden` forces
     overflow-y to compute to auto, turning this into a scroll container — the
     same trap that clipped the quote cards' hover lift earlier. `clip` leaves
     the vertical axis visible, which the rotated band needs. */
  overflow-x:clip;
}
.room__img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; object-position:50% 45%; z-index:-2}
.room__scrim{
  position:absolute; inset:0; z-index:-1;
  background:linear-gradient(to top, var(--night) 2%, rgba(7,9,15,.86) 24%, rgba(7,9,15,.26) 62%, rgba(7,9,15,.6) 100%);
}
.room__in{padding-block:clamp(44px,6vw,92px); width:100%}
.room__in .h2{margin-bottom:.45em; max-width:16ch}
.room__cap{
  font-size:11px; font-weight:700; letter-spacing:.22em; text-transform:uppercase;
  color:var(--night-tx2);
}

/* ==========================================================================
   Booking
   ========================================================================== */
.booking__grid{display:grid; grid-template-columns:minmax(0,1.5fr) minmax(0,1fr); gap:clamp(34px,5vw,86px); align-items:start}
.booking__sub{margin-top:-1.7em; margin-bottom:clamp(26px,3.2vw,40px); color:var(--night-tx2); max-width:52ch}

.f2{display:grid; grid-template-columns:1fr 1fr; gap:clamp(14px,1.6vw,22px)}
.field{display:flex; flex-direction:column; gap:7px; margin-bottom:clamp(14px,1.6vw,22px)}
.field label{
  font-size:11px; font-weight:800; letter-spacing:.2em; text-transform:uppercase;
  color:var(--gold); display:flex; align-items:center; gap:.7em;
}
.req{
  font-size:11px; letter-spacing:.1em; color:var(--night-tx2); font-weight:700;
  border:1px solid rgba(168,156,137,.4); padding:1px 6px;
}
.field input,.field textarea,.field select{
  width:100%; font-family:var(--text); font-size:15.5px; color:var(--night-tx);
  background:var(--night-2); border:1px solid rgba(200,168,80,.3); border-radius:0;
  padding:13px 15px; transition:border-color .2s var(--ease), background .2s var(--ease);
  font-variant-numeric:tabular-nums;
}
.field textarea{resize:vertical; min-height:104px; line-height:1.55}
.field input::placeholder,.field textarea::placeholder{color:var(--night-tx2)}
.field input:hover,.field textarea:hover,.field select:hover{border-color:rgba(200,168,80,.55)}
.field input:focus,.field textarea:focus,.field select:focus{
  outline:none; border-color:var(--gold); background:var(--night-3);
  box-shadow:0 1px 0 0 var(--gold)
}
.field input[aria-invalid="true"],.field select[aria-invalid="true"],.field textarea[aria-invalid="true"]{
  border-color:var(--red-hi); box-shadow:0 1px 0 0 var(--red-hi)
}
/* Available to screen readers, invisible on screen. The dial-code select has
   its own label because "Phone" belongs to the number field, and a select with
   no label of its own is announced as just "combo box". */
.sr-only{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0;
}

.selwrap{position:relative; display:block}
.selwrap select{appearance:none; padding-right:44px; cursor:pointer}

/* Dial code and number read as one control. auto/1fr rather than a fixed
   width so the select sizes to its longest visible option instead of
   truncating "United Arab Emirates +971" to nothing useful. */
.telwrap{display:grid; grid-template-columns:auto minmax(0,1fr); gap:8px; align-items:start}
.selwrap--dial{min-width:0}
.selwrap--dial select{
  padding-right:36px; padding-left:12px;
  max-width:11.5rem; text-overflow:ellipsis;
}
.selwrap--dial .selwrap__c{right:11px}

@media (max-width:420px){
  /* Side by side, the number field is left with about 150px on a small phone,
     which is not enough to see a number you are typing. Stack instead. */
  .telwrap{grid-template-columns:1fr; gap:10px}
  .selwrap--dial select{max-width:none}
}
.selwrap__c{
  position:absolute; right:14px; top:50%; transform:translateY(-50%);
  width:17px; height:17px; fill:none; stroke:var(--gold); stroke-width:1.6;
  stroke-linecap:square; pointer-events:none;
}
.field input[type="date"]::-webkit-calendar-picker-indicator{filter:invert(78%) sepia(35%) saturate(520%) hue-rotate(2deg); cursor:pointer}
.err{min-height:0; font-size:12.5px; color:#f08a90; font-weight:600}

/* Hint under a field — the "email or phone" rule spans both, so both point at
   the one note with aria-describedby rather than each carrying its own. */
.hint{font-size:12.5px; line-height:1.5; color:var(--night-tx2)}

/* The SMS consent row. Grid rather than an inline checkbox so the label wraps
   as a proper block beside the box instead of running under it, and so the
   error can sit full-width beneath both. */
/* minmax(0,1fr), not 1fr: a 1fr track floors at min-content, so one long
   unbroken word in the consent sentence could push the box wider than the
   form. 18px rather than auto for the first track keeps the two consent
   blocks' text aligned with each other whatever the checkbox renders at. */
.field--check{
  display:grid; grid-template-columns:18px minmax(0,1fr); gap:0 12px;
  align-items:start;
  margin-top:clamp(14px,1.8vw,20px);
  padding:16px 18px;
  background:var(--night-2);
  border:1px solid rgba(200,168,80,.22);
}
.field--check + .field--check{margin-top:10px}
.field--check input[type="checkbox"]{
  width:18px; height:18px; margin:2px 0 0;
  accent-color:var(--gold); cursor:pointer; flex:none;
}
/* display:block is the whole point of this rule, not a leftover.
   .field label is display:flex so the REQUIRED / OPTIONAL chip can sit beside
   the label text, and this block carries .field too — so the consent label
   inherited it and every <a> inside became a flex ITEM. The result was the
   sentence in one narrow column with "Privacy Policy" and "Terms" stacked in a
   second column beside it. Block puts them back in the text where they belong.
   The child combinator keeps this off any future nested label. */
.field--check > label{
  display:block;
  font-size:13px; line-height:1.6; color:var(--night-tx2);
  font-weight:400; letter-spacing:0; text-transform:none; cursor:pointer;
  text-wrap:pretty;
}
.field--check > label a{color:var(--gold-hi); text-underline-offset:3px}
.field--check > label a:hover{color:var(--gold)}
.field--check input[type="checkbox"]:focus-visible{outline:2px solid var(--gold); outline-offset:3px}
.err:empty{display:none}

.formnote{margin-top:16px; font-size:13.5px; color:var(--night-tx2); min-height:1.2em}
.formnote.is-ok{color:var(--gold-hi)}
.formnote.is-bad{color:#f08a90}

.booking__side{border-left:1px solid rgba(200,168,80,.3); padding-left:clamp(20px,2.4vw,36px)}
.side2__h{
  font-family:var(--disp); text-transform:uppercase; color:var(--gold-hi);
  font-weight:700; font-size:clamp(1.1rem,1.8vw,1.55rem); letter-spacing:.02em; margin-bottom:.85em;
}
.side2__h + *{margin-bottom:clamp(28px,3.4vw,44px)}
/* An intro line now sits between the heading and the list. The rule above was
   written when the list came straight after the heading, so without these two
   the big gap lands between the lede and the list instead of after it.
   Higher specificity than `.side2__h + *`, so no !important is needed. */
.side2__h + .side2__lede{
  margin:0 0 1em; font-size:14.5px; line-height:1.55; color:var(--night-tx2);
}
.side2__lede + .checks{margin-bottom:clamp(28px,3.4vw,44px)}
.checks{display:flex; flex-direction:column; gap:.62em}
.checks li{position:relative; padding-left:20px; font-size:14.5px; color:var(--night-tx2)}
.checks li::before{content:""; position:absolute; left:0; top:.64em; width:10px; height:1px; background:var(--gold-deep)}
.direct{display:flex; flex-direction:column; gap:.75em}
.direct li{display:flex; align-items:center; gap:11px}
.direct a{color:var(--night-tx); text-decoration:none; border-bottom:1px solid rgba(200,168,80,.4); font-size:15px}
.direct a:hover{color:var(--gold-hi); border-bottom-color:var(--gold)}
.ic{width:19px; height:19px; flex:0 0 auto; fill:none; stroke:var(--gold); stroke-width:1.5; stroke-linecap:square; stroke-linejoin:miter}
.ic--solid{fill:currentColor; stroke:none}
.placeholder-flag{
  margin-top:1.1em; font-size:11px; font-weight:800; letter-spacing:.18em;
  text-transform:uppercase; color:var(--gold-hi); background:transparent;
  border:1px dashed var(--gold-deep); padding:6px 10px; display:inline-block;
}
.placeholder-flag--wide{margin:0 0 14px; letter-spacing:.1em; line-height:1.45; display:block}
/* REMAINING 3: sized to what it annotates, not to the footer column */
.foot__flag{
  flex:0 0 100%; max-width:max-content; margin-top:4px;
  font-size:11px; font-weight:800; letter-spacing:.12em;
  text-transform:uppercase; color:var(--gold-hi); background:transparent;
  border:1px dashed var(--gold-deep); padding:6px 10px;
}

/* ==========================================================================
   Footer
   ========================================================================== */
.foot{position:relative; background:var(--night-2); border-top:1px solid rgba(200,168,80,.32); padding-top:clamp(46px,5vw,76px)}
.bulbs--strip{position:absolute; top:-3.5px; left:var(--pad); right:var(--pad); justify-content:space-between}
/* The same strip on the seam between the hero and the booking section. It
   sits in the flow at zero height, so its bulbs centre on the seam, and draws
   the footer's gold rail behind them full-bleed. z-index lifts it over the
   edges of both sections. */
.bulbs--seam{position:relative; z-index:2; top:auto; left:auto; right:auto; height:0; align-items:center; margin-inline:var(--pad)}
.bulbs--seam::before{
  content:""; position:absolute; z-index:-1; top:-.5px; height:1px;
  left:calc(var(--pad) * -1); right:calc(var(--pad) * -1);
  background:rgba(200,168,80,.32);
}
.foot__grid{
  display:grid; grid-template-columns:minmax(0,1.5fr) minmax(0,1fr) auto;
  gap:clamp(28px,4vw,60px); align-items:start;
  padding-bottom:clamp(34px,4vw,58px);
}
.foot__brand img{width:clamp(96px,9vw,128px); margin-bottom:18px}
.foot__brand p{color:var(--night-tx2); font-size:14.5px; max-width:34ch}
.foot__nav{display:flex; flex-direction:column; gap:.6em}
.foot__nav a{
  font-size:11.5px; font-weight:700; letter-spacing:.2em; text-transform:uppercase;
  color:var(--night-tx2); text-decoration:none; width:max-content;
  border-bottom:1px solid transparent;
}
.foot__nav a:hover{color:var(--gold-hi); border-bottom-color:var(--gold)}
.foot__social{display:flex; gap:12px; flex-wrap:wrap; align-items:flex-start}
.foot__social a{
  display:grid; place-items:center; width:42px; height:42px;
  border:1px solid rgba(200,168,80,.34); color:var(--gold);
  transition:background .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease);
}
.foot__social a:hover{background:var(--gold); color:var(--gold-ink); border-color:var(--gold)}
.foot__social .ic{width:17px; height:17px}
.foot__legal{
  display:flex; flex-wrap:wrap; gap:8px 28px; justify-content:space-between;
  padding-block:20px clamp(22px,3vw,34px);
  border-top:1px solid rgba(200,168,80,.18);
  font-size:12px; color:var(--night-tx2); letter-spacing:.04em;
}
.foot__legal p{margin:0}

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width:1080px){
  .booking__grid{grid-template-columns:1fr}
  .booking__side{border-left:0; border-top:1px solid rgba(200,168,80,.3); padding-left:0; padding-top:clamp(26px,4vw,38px)}
  .foot__grid{grid-template-columns:1fr 1fr; }
  .foot__social{grid-column:1 / -1}
}
/* 1040, not 900: the menu carries seven items now, and seven uppercase labels
   at .2em tracking plus the brand and the CTA stop fitting a 72px bar somewhere
   just under 1000px. Collapsing earlier is better than a nav that wraps. */
@media (max-width:1040px){
  .nav__links{
    position:fixed; inset:calc(72px + env(safe-area-inset-top,0px)) 0 auto; flex-direction:column; gap:0;
    background:var(--night); border-bottom:1px solid rgba(200,168,80,.3);
    padding:8px var(--pad) 22px; display:none;
  }
  .nav__links.is-open{display:flex}
  .nav__links a{padding:14px 0; border-bottom:1px solid rgba(200,168,80,.14); font-size:13px}
  .nav__toggle{display:block; order:3}
}
/* The CTA keeps its own, lower threshold. The links collapse at 1040 because
   seven of them stop fitting, but brand + CTA + toggle still sit comfortably
   in the bar well below that, and dropping the one conversion button off a
   tablet for no spatial reason would be a regression. */
@media (max-width:900px){
  .nav__cta{display:none}
}
@media (max-width:720px){
  .f2{grid-template-columns:1fr}
  .foot__grid{grid-template-columns:1fr}
}
@media (max-width:460px){
  .bill__acts .btn{width:100%}
}


/* ==========================================================================
   Client wall : the bill curves into a gold band
   Ported from the Kent Axell site. The loop mechanic is carried over intact;
   the materials are this site's. The panel is --bill so the brand logos, all
   of which are drawn for white grounds, survive — several (Chase, Capital One)
   are near-black and would vanish on --night.
   ========================================================================== */
.clients{
  /* Both golds are pinned by contrast, not taste. --gold-deep carries white
     text at 4.88:1. The eyebrow sits on --bill instead, where --gold-deep only
     reaches 4.15:1, so it needs a darker value — this one clears 4.89:1. */
  --gold-bill:#7d6228;
  background:var(--gold-deep);
  position:relative;
  padding-bottom:clamp(30px,4vw,64px);
}
.clients__panel{
  /* Linen: fine horizontal threads crossed by fainter vertical ones on warm
     cream, after the client-logo panel on magiskedaniel.no. Drawn here from
     SVG noise (stretched along each axis), not copied from that site. */
  background-color:#f7f4ed;   /* the threads darken it ~3 levels, landing on the reference's #f4f1ea */
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='f' x='0' y='0' width='100%25' height='100%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.006 0.62' numOctaves='2' seed='7' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.36 0 0 0 0 0.3 0 0 0 0 0.2 0.15 0 0 0 -0.055'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23f)'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='f' x='0' y='0' width='100%25' height='100%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.62 0.006' numOctaves='2' seed='11' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.36 0 0 0 0 0.3 0 0 0 0 0.2 0.1 0 0 0 -0.038'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23f)'/%3E%3C/svg%3E");
  color:var(--ink);
  padding-block:clamp(56px,8vw,104px) clamp(78px,11vw,150px);
  /* shallow ellipse: full height at the centre, shorter at the edges */
  border-radius:0 0 50% 50% / 0 0 clamp(28px,5vw,72px) clamp(28px,5vw,72px);
}
.clients__in{text-align:center}
/* The skyline sits on a horizon line that fades out at both ends, and rises
   out of it when the panel is lit (script.js section 2 adds .ignite/.is-lit;
   --lit is 0 until then, and 1 when motion is reduced or JS is off). */
.skyline{
  position:relative; display:flex; justify-content:center; overflow:hidden;
  margin:0 auto clamp(22px,2.6vw,34px); padding-bottom:1px;
}
.skyline::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:1px;
  background:linear-gradient(90deg, rgba(138,107,43,0), rgba(138,107,43,.42) 18%, rgba(138,107,43,.42) 82%, rgba(138,107,43,0));
  transform:scaleX(var(--lit,1)); transition:transform .9s var(--ease);
}
.skyline__img{
  width:clamp(240px,34vw,470px); height:auto;
  transform:translateY(calc((1 - var(--lit,1)) * 102%));
  transition:transform 1.1s var(--ease) .25s;
}
.clients__eyebrow{
  font-size:11px; font-weight:800; letter-spacing:.26em; text-transform:uppercase;
  color:var(--gold-bill); margin-bottom:1.4em;
}
.clients__title{margin-inline:auto; margin-bottom:0; max-width:20ch}

/* ---- continuous left-scrolling logo loop ---- */
.logoloop{
  /* A centred window, not full bleed: shows ~5 logos at desktop and loops the
     rest through, so it reads as a curated set rather than a banner. */
  max-width:min(860px,100%);
  margin:clamp(38px,5.5vw,64px) auto 0;
  overflow:hidden;
  /* Fade the ends so logos dissolve instead of being chopped. A narrow window
     needs a wider fade than a full-bleed one — a hard edge shows more. */
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 11%,#000 89%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 11%,#000 89%,transparent);
}
.logoloop__track{display:flex; width:max-content; animation:logoloop 42s linear infinite}
/* -50% lands set 2 exactly where set 1 began, so the restart is invisible. */
@keyframes logoloop{to{transform:translateX(-50%)}}
/* Pause on hover so a logo can actually be looked at, and hovered. */
.logoloop:hover .logoloop__track,
.logoloop:focus-within .logoloop__track{animation-play-state:paused}

.logoloop__set{
  display:flex; align-items:center; flex:none;
  gap:clamp(26px,3.2vw,44px);
  padding-right:clamp(26px,3.2vw,44px);  /* keeps spacing even across the seam */
}
.logoloop__set li{display:flex; align-items:center; justify-content:center}
.logoloop__set img{
  height:clamp(26px,3.2vw,38px);
  /* Cap the wide wordmarks — Chase, ConEd and Make-A-Wish run ~200px uncapped
     and would dominate the narrow window. */
  width:auto; max-width:150px; object-fit:contain;
  /* resting: desaturated, so the row reads as one texture not a clip-art wall */
  filter:grayscale(1); opacity:.52;
  transition:filter .4s var(--ease), opacity .4s var(--ease), transform .4s var(--ease);
}
.logoloop__set li:hover img,
.logoloop__set li:focus-within img{filter:grayscale(0); opacity:1; transform:scale(1.12)}

/* ---- pull quote, on the gold band ---- */
.pullquote{
  margin:0 auto;
  padding-block:clamp(52px,7.5vw,96px) clamp(30px,4vw,54px);
  text-align:center;
}
.pullquote blockquote{
  /* px, not ch: the blockquote inherits 16px, so a ch value would be measured
     against that rather than against the display type inside it. */
  margin:0 auto; max-width:660px;
  font-family:var(--disp); text-transform:uppercase;
  /* #fff, not --night-tx: the cream only reaches 4.03:1 on the band, which the
     13px figcaption below would fail. White clears 4.88:1 for both. */
  color:#fff;
  font-size:clamp(1.2rem,3vw,2.35rem); line-height:1.16; letter-spacing:.012em;
  text-wrap:balance;
}
.pullquote figcaption{
  margin-top:1.5em; font-size:11px; font-weight:800; letter-spacing:.26em;
  text-transform:uppercase; color:#fff; opacity:.86;
}

@media (prefers-reduced-motion:reduce){
  /* Stop the loop and let the row wrap statically instead. */
  .logoloop__track{animation:none; width:100%; flex-wrap:wrap; justify-content:center}
  .logoloop__set{flex-wrap:wrap; justify-content:center}
  .logoloop__set + .logoloop__set{display:none}  /* the duplicate only exists to loop */
  .logoloop{-webkit-mask-image:none; mask-image:none}
  .logoloop__set li:hover img,
  .logoloop__set li:focus-within img{transform:none}
}




/* ==========================================================================
   FAQ : Kent's raised panel, inverted onto the bill
   Structure and type are carried over unchanged — his display face is
   a grotesque; this site's --disp is now Josefin Sans, so the headings and
   summaries are the same face at the same weights. Only the ground flips:
   his panel is a dark card on dark, this one is a printed panel on the bill,
   so every value is re-derived for contrast rather than inverted by eye.
   ========================================================================== */
.faqwrap{
  /* --gold-deep reaches only 3.62:1 on --bill-2 and 4.15:1 on --bill, so small
     gold text inside this panel needs a darker value: this clears 4.88:1 on
     the panel and 5.59:1 on a row. */
  --gold-faq:#74591f;
}
.faqpanel{
  background:var(--bill-2);
  padding:clamp(28px,4.4vw,58px) clamp(20px,3.4vw,52px);
  box-shadow:0 30px 70px -56px rgba(20,16,12,.7);
}
.faqpanel__head{margin-bottom:clamp(26px,3.4vw,44px)}
.faqpanel__head .h2{margin-bottom:.3em; max-width:20ch}
.faqpanel__sub{
  font-size:11px; font-weight:800; letter-spacing:.26em; text-transform:uppercase;
  color:var(--gold-faq);
}

.faq{display:grid; gap:9px}
.faq details{
  background:var(--bill);
  border:1px solid rgba(20,16,12,.14);
  transition:border-color .3s var(--ease), background-color .3s var(--ease);
}
.faq details[open]{border-color:var(--gold-deep); background:#F8F4EB}
.faq summary{
  list-style:none; cursor:pointer;
  display:flex; align-items:center; justify-content:space-between; gap:20px;
  padding:16px clamp(15px,2.2vw,24px);
  font-family:var(--disp);
  font-size:clamp(14px,1.5vw,15.5px); font-weight:600;
  letter-spacing:.005em; line-height:1.5;
  color:var(--ink);
  transition:color .25s var(--ease);
}
.faq summary::-webkit-details-marker{display:none}
.faq summary:hover{color:var(--gold-faq)}
.faq summary::after{
  content:""; flex:none;
  width:9px; height:9px;
  border-right:1.6px solid var(--gold-deep); border-bottom:1.6px solid var(--gold-deep);
  rotate:45deg; translate:0 -2px;
  transition:rotate .32s var(--ease), translate .32s var(--ease);
}
.faq details[open] summary::after{rotate:225deg; translate:0 2px}
.faq__body{
  padding:0 clamp(15px,2.2vw,24px) 19px;
  color:var(--ink-2); font-size:14.5px; line-height:1.6; font-weight:400;
  max-width:78ch;
}
.faq__body p{margin:0}

.faq__cta{margin:clamp(26px,3.4vw,44px) 0 0; text-align:center}



/* ==========================================================================
   Gallery : the proof wall
   Ported from the Kent Axell site (.grid6). Same 3-up grid, same hover scale
   and hairline that goes gold. Square corners and this site's gold, and the
   reserved slots use the project's own convention — visibly empty rather than
   dressed up, so a missing photograph reads as missing.
   ========================================================================== */
.gallery__head{margin-bottom:clamp(26px,3.4vw,44px)}
.gallery__head .h2{margin-bottom:.3em; max-width:20ch}
.gallery__sub{
  font-size:11px; font-weight:800; letter-spacing:.26em; text-transform:uppercase;
  color:var(--gold);
}
.shots{display:grid; grid-template-columns:repeat(3,1fr); gap:clamp(10px,1.5vw,18px)}
.shot{margin:0; position:relative; overflow:hidden; background:var(--night-2)}
/* The whole tile is the hit area — a gallery photograph that only responds on
   a small corner icon is a photograph most people never open. */
.shot__link{display:block; position:relative; cursor:zoom-in}
.shot__link:focus-visible{outline:2px solid var(--gold); outline-offset:-2px}
.shot__zoom{
  position:absolute; right:10px; bottom:10px;
  width:34px; height:34px; display:grid; place-items:center;
  background:rgba(7,9,15,.72); backdrop-filter:blur(6px);
  border:1px solid rgba(200,168,80,.38);
  opacity:0; translate:0 6px;
  transition:opacity .3s var(--ease), translate .3s var(--ease), background-color .3s var(--ease);
  pointer-events:none;
}
.shot__zoom svg{width:17px; height:17px; fill:none; stroke:var(--gold-hi); stroke-width:1.7; stroke-linecap:round}
.shot__link:hover .shot__zoom,
.shot__link:focus-visible .shot__zoom{opacity:1; translate:0 0}
/* Touch has no hover, so the affordance is simply always on there. */
@media (hover:none){
  .shot__zoom{opacity:1; translate:0 0}
}
.shot img{
  width:100%; aspect-ratio:4/3; object-fit:cover;
  filter:saturate(.88) brightness(.94);
  transition:transform .85s var(--ease), filter .5s var(--ease);
}
.shot:hover img{transform:scale(1.07); filter:saturate(1.04) brightness(1)}
.shot::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  box-shadow:inset 0 0 0 1px rgba(200,168,80,.22);
  transition:box-shadow .35s var(--ease);
}
.shot:hover::after{box-shadow:inset 0 0 0 1px var(--gold)}

/* The tenth photograph, and the control that reveals it.

   Desktop only. At three columns a tenth tile starts a fourth row holding one
   image and two gaps, which reads as a loading failure rather than a gallery.
   On a phone the grid is one column, so a tenth is simply one more swipe and
   there is nothing to hide it from - the media query below switches the
   clipping off and the button with it.

   .is-clipped is applied by script.js, never in the markup, so a reader with
   no JavaScript gets all ten. */
.shots.is-clipped > .shot--extra{display:none}
.shots__more{margin:clamp(18px,2.2vw,26px) 0 0; text-align:center}

@media (max-width:900px){
  /* two columns: ten tiles is five clean rows, nothing to hold back */
  .shots.is-clipped > .shot--extra{display:block}
  .shots__more{display:none}
}

.gallery__cta{margin:clamp(28px,3.6vw,48px) 0 0; text-align:center}

@media (max-width:900px){
  .shots{grid-template-columns:repeat(2,1fr)}
}

/* ==========================================================================
   About : the line-up
   Started as Kent Axell's section#about — three alternating portrait/copy
   blocks — and only his sechead survives that, because the section was cut
   down to a single horizontal row of three: portrait, name, billing, one
   shared CTA. The bios moved to squad.html.
   Portraits are full uncropped 4:5 frames — no mask, no bottom fade, no glow
   behind them — so the artwork reads exactly as supplied.
   ========================================================================== */
.about{
  background:var(--night);          /* #07090f — flat, no gradient */
  color:var(--night-tx);
  padding-block:clamp(56px,8vw,104px);
  position:relative;
}
.about::before,
.about::after{
  content:""; position:absolute; left:0; right:0; height:1px;
  background:linear-gradient(90deg,transparent,rgba(200,168,80,.30),transparent);
}
.about::before{top:0} .about::after{bottom:0}

/* Three abreast, and they stay three abreast at every width — the whole point
   of the line-up is that you take in the trio at once, and a stack of three
   portraits is just the old layout again with the words removed. */
.lineup{
  list-style:none; margin:0; padding:0;
  display:grid; grid-template-columns:repeat(3,1fr);
  gap:clamp(24px,2.6vw,32px);
  align-items:start;
}
/* --------------------------------------------------------------------------
   Performer cards
   The anatomy of the reference layout - portrait, tag, name, scannable icon
   rows, a line of detail, a CTA per card - rebuilt on this site's materials:
   square corners, a gold hairline, the night panel fill. No rounded cards, no
   wave divider, no borrowed palette.
   -------------------------------------------------------------------------- */
/* Nothing on these cards moves. The lift on hover and the slow zoom on the
   portrait were both removed with the carousel: the section is a static list
   now, and a card that rises under the cursor is the one piece of carousel
   motion that would have survived the rest being taken out. Colour is the
   only thing that changes. */
.pcard{
  display:flex; flex-direction:column;
  background:var(--night-2);
  border:1px solid rgba(200,168,80,.22);
  border-radius:0;
  overflow:hidden;
  transition:border-color .35s var(--ease);
}
.pcard:hover{border-color:var(--gold-deep)}

.pcard__fig{margin:0; position:relative; overflow:hidden}
/* The crop is per-image, because the sources are not one shape. A portrait
   shot natively at 4:5 fills the box untouched and ignores both values; a
   landscape stage frame shows barely half its width, so where that half is
   taken from decides whether the performer is in the card or beside it.
   Each img sets --obj-x / --obj-y when it needs something other than centre;
   the default suits an upright portrait. */
.pcard__fig img{
  display:block; width:100%; height:auto; aspect-ratio:4/5;
  object-fit:cover;
  object-position:var(--obj-x,50%) var(--obj-y,22%);
  filter:saturate(.92) brightness(.92);
}

/* The reference's FEATURED flag, centred at the top edge as it is there, but
   carrying something true instead of a paid placement: which of the three
   disciplines this performer is. 11px, not the 9.5px it was — the detector
   flagged that size as below its legibility floor and it was right. */
.pcard__tag{
  position:absolute; top:12px; left:50%; translate:-50% 0;
  padding:6px 12px; white-space:nowrap;
  background:var(--gold); color:var(--gold-ink);
  font-family:var(--text); font-size:11px; font-weight:800;
  letter-spacing:.16em; text-transform:uppercase;
}

/* The wave. This is the reference's one genuinely distinctive structural move,
   and the earlier pass left it out; it is in now, drawn in this world's
   materials rather than its blue.

   Two stacked paths on the same curve, the lower offset by 6px, so the body
   colour rises into the photograph behind a gold ribbon that follows it. That
   is the site's hairline grammar bent into a curve, not a new device.

   The two colours are written as literals because a data URI cannot read a CSS
   custom property. They are --gold and --night-2; if either token moves, this
   string has to move with it. */
.pcard__fig::after{
  content:""; position:absolute; left:0; right:0; bottom:-1px;
  height:clamp(20px,4.4vw,32px);
  pointer-events:none;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 36' preserveAspectRatio='none'%3E%3Cpath d='M0 13C60 -3 140 -3 200 9s140 12 200 -2V36H0z' fill='%23c8a850'/%3E%3Cpath d='M0 19C60 3 140 3 200 15s140 12 200 -2V36H0z' fill='%230d1119'/%3E%3C/svg%3E") no-repeat center / 100% 100%;
}

.pcard__body{
  display:flex; flex-direction:column; align-items:flex-start;
  gap:12px; padding:14px 18px 20px;
}
.pcard__name{
  margin:0;
  font-family:var(--disp); font-weight:700;
  font-size:clamp(19px,2.1vw,24px); letter-spacing:0; line-height:1.14;
  color:var(--gold-hi);
}

/* Icon rows, the part that makes the card scannable. The gold hairline above
   mirrors the reference's divider without importing its wave. */
.pcard__meta{
  list-style:none; margin:0; padding:12px 0 0; width:100%;
  border-top:1px solid rgba(200,168,80,.18);
  display:flex; flex-direction:column; gap:8px;
}
.pcard__meta li{
  display:grid; grid-template-columns:18px 1fr; gap:10px; align-items:center;
  font-size:13.5px; line-height:1.45; color:var(--night-tx2);
}
.pcard__meta svg{
  width:15px; height:15px; fill:none;
  stroke:var(--gold); stroke-width:1.5;
  stroke-linecap:round; stroke-linejoin:round;
}
.pcard__note{
  margin:0; padding-top:12px; width:100%;
  border-top:1px solid rgba(200,168,80,.18);
  font-size:13.5px; line-height:1.6; color:var(--night-tx);
}
/* Full width, as the reference's quote button is. It is the card's one
   action and the widest element in the body, so it reads as the floor of
   the card rather than a chip sitting on it. */
.pcard__cta{margin-top:4px; width:100%}
.lineup__cta{margin:clamp(34px,4.6vw,56px) 0 0; text-align:center}

/* his typographic system: light word-groups, <strong> carries the punch */
.about .sechead{text-align:center; margin-bottom:clamp(30px,4vw,48px)}
.about .sechead h2{
  font-family:var(--disp); font-weight:300; text-transform:uppercase;
  font-size:clamp(28px,4vw,50px);
  letter-spacing:.004em; line-height:.98; text-wrap:balance;
  color:var(--night-tx); margin:0;
}
.about .sechead h2 strong{font-weight:700; letter-spacing:.004em; color:var(--gold-hi)}
.about .sechead__sub{
  margin:14px 0 0;
  font-family:var(--disp);
  font-size:clamp(12px,1.4vw,15px);
  font-weight:500; text-transform:uppercase; letter-spacing:.18em;
  color:var(--night-tx2);
}

/* little gold diamond divider */
.btn--sm{padding:12px 22px; min-height:0; font-size:11px; letter-spacing:.14em}

/* --------------------------------------------------------------------------
   The line-up wraps. Nothing scrolls sideways.
   Three abreast is right while each card has room for its three meta rows and
   a button without hyphenating; below that it drops to two, then to one.

   620px rather than the gallery's 900px for the final drop, because these
   cards carry text and the gallery tiles carry none: two 290px cards still
   read, two 140px ones do not.
   -------------------------------------------------------------------------- */
@media (max-width:900px){
  .lineup{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:620px){
  .lineup{grid-template-columns:1fr}
}


/* ==========================================================================
   Testimonials
   Started as Kent Axell's .quotes__rail and kept his card: gradient fill, gold
   stars, footer attribution over a hairline, in this site's palette. The rail
   part is gone — it is a wrapping grid now, collapsed to the first three with
   a button for the rest.
   ========================================================================== */
.quotes .sechead{text-align:center; margin-bottom:clamp(20px,2.8vw,32px)}
.quotes .sechead h2{
  font-family:var(--disp); font-weight:300; text-transform:uppercase;
  font-size:clamp(28px,4vw,50px);
  letter-spacing:.004em; line-height:.98; text-wrap:balance;
  color:var(--night-tx); margin:0;
}
.quotes .sechead h2 strong{font-weight:700; letter-spacing:.004em; color:var(--gold-hi)}
.quotes .sechead__sub{
  margin:14px 0 0; font-family:var(--disp);
  font-size:clamp(12px,1.4vw,15px);
  font-weight:500; text-transform:uppercase; letter-spacing:.18em;
  color:var(--night-tx2);
}

/* the placeholder banner — deliberately not styled to blend in */
.quotes__note{
  max-width:64ch; margin:0 auto clamp(26px,3.4vw,42px); text-align:center;
  color:var(--night-tx2); font-size:13.5px; line-height:1.6;
}

/* The rail is a real horizontal scroll container, and everything else is built
   on top of that rather than around it. With no JS at all it is still a rail a
   visitor can swipe; script.js clones the set twice and adds the drift and the
   mouse-drag on top. Native scrolling is what makes the thing draggable, so it
   is the one property here that must not be traded away. */
/* --------------------------------------------------------------------------
   The reviews wrap. Nothing scrolls sideways, nothing drifts.
   Same column rhythm as the line-up, and for the same reason: three while each
   card has room for a paragraph plus its attribution row, two on tablets, one
   per row on phones.

   Was a drifting, draggable, cloned rail at every width. Removed on request.
   -------------------------------------------------------------------------- */
.quotes{--qgap:clamp(24px,2.6vw,32px)}
/* stretch, and the author row pushed to the floor of each card with
   margin-top:auto. This was align-items:start for a while, because three real
   reviews of wildly different lengths left a lot of empty panel when forced to
   match. With eight reviews clipped to a 236-character preview the lengths are
   near enough even, and a ragged row of boxes reads as a bug where a ragged
   row of paragraphs did not. The footers now line up across each row. */
.quotes__grid{
  display:grid; grid-template-columns:repeat(3,1fr);
  gap:var(--qgap);
  align-items:stretch;
}
@media (max-width:900px){
  .quotes__grid{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:620px){
  .quotes__grid{grid-template-columns:1fr}
}

/* Collapsed to the first three until the button says otherwise. The class is
   put on by script.js card by card, so the default state of this markup is
   "all of them showing" — see the note above the list in index.html.
   display:none rather than visibility or height, so a hidden card is out of
   the tab order and out of the accessibility tree while it is away. */
.quote.is-hidden{display:none}

/* Revealed cards fade and rise once, on the batch that uncovered them. It is
   a transition on a class rather than an animation so an interrupted reveal
   retargets instead of restarting, and the end state is the plain card — if
   the class never lands, nothing is invisible. */
.quote.is-entering{opacity:0; transform:translateY(14px)}
.quote.is-enter-done{
  opacity:1; transform:none;
  transition:opacity .42s var(--ease), transform .42s var(--ease);
}
@media (prefers-reduced-motion:reduce){
  .quote.is-entering{opacity:1; transform:none}
  .quote.is-enter-done{transition:none}
}

.quotes__more{margin:clamp(26px,3.4vw,42px) 0 0; text-align:center}

/* The chevron points down at "show more" and flips when the list is open.
   .btn already carries the gold-on-dark, the uppercase and the .2em tracking
   that match the TESTIMONIALS eyebrow, so this adds only the arrow. */
.quotes__chev{flex:none; transition:transform .28s var(--ease)}
.quotes__btn[aria-expanded="true"] .quotes__chev{transform:rotate(180deg)}
@media (prefers-reduced-motion:reduce){
  .quotes__chev{transition:none}
}
/* Stated rather than inherited from the global :focus-visible, so a later
   change to that rule cannot quietly take the ring off this control. */
.quotes__btn:focus-visible{outline:2px solid var(--gold-hi); outline-offset:3px}

.quote{
  margin:0; overflow:hidden;
  background:linear-gradient(var(--night-2), var(--night));
  border:1px solid rgba(200,168,80,.18);
  padding:clamp(24px,3vw,34px);
  display:flex; flex-direction:column; gap:16px;
  transition:border-color .35s var(--ease);
}
/* Colour only. The 3px lift went with the carousel — see .pcard. */
.quote:hover{border-color:var(--gold-deep)}
.stars{
  color:var(--gold-hi); font-size:17px; letter-spacing:.2em; line-height:1;
  /* the glow is what actually reads as "lit" — raising the colour alone just
     makes them paler against the dark card */
  text-shadow:0 0 10px rgba(230,209,147,.45);
}
/* White, not the muted secondary. These are real people's words and the one
   piece of proof the page has; they were reading as caption-grade text. */
/* flex:1, so the text box takes every pixel between the stars and the author
   row and the footer has nothing to float above. How much text goes IN that
   box is script.js's job (4b-ii): it counts how many lines fit and writes the
   number to --lines. The 13px that used to be a flex `gap` is now a margin on
   the second paragraph onward — identical spacing, but -webkit-line-clamp
   needs a -webkit-box, and a -webkit-box is not a flex container. */
.quote__body{flex:1 1 auto; min-height:0; display:block}
.quote__body p + p{margin-top:13px}

/* The clamp itself. Applied only when the text actually overflows, so a short
   review is a plain block with no ellipsis and no control under it. The count
   is a custom property rather than a fixed number because the right count is
   whatever this card's row happens to be tall enough for. */
.quote__body.is-clamped{
  display:-webkit-box; -webkit-box-orient:vertical;
  -webkit-line-clamp:var(--lines,6); line-clamp:var(--lines,6);
  overflow:hidden;
}
/* line-clamp puts the ellipsis on line N but does not shorten the box. The
   box here is flex:1, so it is taller than N lines by whatever did not divide
   evenly - and that remainder painted the top of line N+1 underneath the
   ellipsis, a sliced half-line sitting on the author rule. script.js measures
   the clamped height in this state and pins it as a max-height; the leftover
   then goes to the footer's auto margin, where it is invisible. */
.quote__body.is-measuring{flex:0 0 auto !important; max-height:none !important}
.quote p{color:#fff; font-size:14.5px; font-weight:400; line-height:1.75; margin:0}

/* The "more" control. A real button, not a link: it reveals text in place and
   goes nowhere, and a link that does not navigate is a lie to a screen reader.
   Styled to sit inside the sentence it ends. */
.quote__more{
  appearance:none; -webkit-appearance:none;
  background:none; border:0; padding:0;
  /* sits under the clamped text rather than inside it. -webkit-line-clamp
     clips by line box, so anything trailing the last visible line is clipped
     with it — an inline "more" would disappear exactly when it is needed. */
  margin:10px 0 0; align-self:flex-start;
  font:inherit; font-size:14.5px; line-height:1.75;
  color:var(--gold-hi); cursor:pointer;
  text-decoration:underline; text-underline-offset:3px;
}
.quote__more[hidden]{display:none}
.quote__more:hover{color:var(--gold)}
.quote__more:focus-visible{outline:2px solid var(--gold); outline-offset:2px}
.quote__body:focus{outline:none}
.quote__body:focus-visible{outline:2px solid var(--gold); outline-offset:4px}
/* margin-top:auto, not flex:1 on the body above it. Stretching the body would
   push its own paragraphs apart and leave a photograph floating mid-card; the
   slack belongs above the footer, in one place. */
.quote footer{
  margin-top:auto;
  display:flex; align-items:center; gap:12px;
  padding-top:14px; border-top:1px solid rgba(200,168,80,.18);
}
.quote__who{display:flex; flex-direction:column; gap:2px; min-width:0}

/* Monogram, not a face. Every name on these cards is invented, and a stock
   portrait or a cropped guest from the gallery would put a fabricated quote
   against a real, identifiable person. Initials in a disc is what Google
   reviews show for someone with no photo, so it reads as intended rather than
   as missing — and it swaps one-for-one with a real headshot later.
   --av is set per card below so the discs do not all look like one person. */
.quote__avatar{
  flex:none; width:42px; height:42px; border-radius:50%;
  display:grid; place-items:center;
  font-family:var(--disp); font-size:14px; font-weight:700;
  letter-spacing:.04em; color:var(--gold-ink);
  background:linear-gradient(145deg, hsl(var(--av,44 55% 62%)), hsl(var(--av,44 55% 62%) / .72));
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.16);
  user-select:none;
}
/* Spread around the site's gold rather than off into arbitrary hues, so seven
   discs read as a set instead of a paint chart. */
.quotes__grid > .quote:nth-child(7n+1) .quote__avatar{--av:44 55% 62%}
.quotes__grid > .quote:nth-child(7n+2) .quote__avatar{--av:34 48% 58%}
.quotes__grid > .quote:nth-child(7n+3) .quote__avatar{--av:50 52% 64%}
.quotes__grid > .quote:nth-child(7n+4) .quote__avatar{--av:24 44% 56%}
.quotes__grid > .quote:nth-child(7n+5) .quote__avatar{--av:40 60% 66%}
.quotes__grid > .quote:nth-child(7n+6) .quote__avatar{--av:14 38% 55%}
.quotes__grid > .quote:nth-child(7n+7) .quote__avatar{--av:47 46% 60%}
.quote footer b{
  font-family:var(--disp); font-size:13px; font-weight:700;
  letter-spacing:.03em; color:var(--night-tx);
}
/* Scoped to the role line specifically. As `.quote footer span` this also
   matched the monogram — and at (0,2,1) it outranked .quote__avatar, so the
   initials came out as an 11px uppercase gold role label. */
.quote__who > span{
  font-family:var(--disp); font-size:11px; font-weight:500;
  text-transform:uppercase; letter-spacing:.16em; color:var(--gold);
}
/* The label sits beside its badge rather than under it, and the tracking on
   the last letter is not allowed to push the row apart. */
.quote__src{display:flex; align-items:center; gap:6px}
/* The one blue on the page, and deliberately not a palette token: it is
   borrowed trust-signal blue, not part of this site's colour. Keeping it out
   of :root keeps it from spreading. */
.vbadge{flex:none; color:#1d9bf0}

/* A real reviewer's own photograph instead of a monogram. The monogram exists
   because the placeholder names are invented and a stock face against a made-up
   person would be a lie with a picture on it; a real review has a real face and
   gets to use it.

   Self-hosted, not hot-linked from googleusercontent: a third-party request on
   every page load hands Google every visitor's IP and breaks silently the day
   that URL rotates. box-sizing so the ring does not grow the disc. */
.quote__avatar--photo{
  box-sizing:border-box;
  background:none;
  object-fit:cover;
  border:1px solid rgba(200,168,80,.42);
  box-shadow:none;
}

/* .quote.is-sample and .quote--real both lived here and are gone. Every review
   on the page is real now, so there is nothing to mark as unfinished and
   nothing to distinguish from it. If placeholders ever return they need a
   signal far louder than the 1px dashed edge this was: near-black on
   near-black, effectively invisible at every breakpoint. */

/* A photograph on the two shortest reviews.
   The cards are align-items:stretch, so every card is as tall as the tallest —
   which means the short ones were already carrying dead space, and a picture
   that ADDS height would have grown all seven. So the photo takes the flex
   slack instead of the paragraph: .quote p gives up flex:1 and the figure
   claims it. The two cards with photos end up exactly as tall as they were,
   and the picture simply occupies the gap the short quote left behind. */
/* A pair, side by side. As grid items the two images stretch to the row height
   on their own, which is why neither needs absolute positioning any more. */
/* auto-fit, so one photograph fills the width and two still sit side by side.
   The old fixed 1fr 1fr left a single image stranded in the left half. */
/* Fixed ratio rather than "take whatever slack is left". The old rule existed
   to soak up the dead space that stretch created; with the cards sized to
   their content there is no slack to soak, and a photograph that changes
   height with its neighbours' word count is not a photograph, it is a spacer. */
.quote__shot{
  flex:0 0 auto;
  margin:0; display:grid; grid-template-columns:repeat(auto-fit,minmax(45%,1fr)); gap:8px;
}
/* 16/10 and capped at 220px. The photograph was the thing setting the height
   of its whole row, which is what left the text-only cards beside it with a
   hundred pixels of nothing. A shorter frame means less for them to fill. */
.quote__shot img{
  display:block; width:100%; height:auto; aspect-ratio:16/10;
  max-height:220px;
  object-fit:cover;
  filter:brightness(.82) saturate(.95);
}



/* ==========================================================================
   Tilted band : Kent Axell's .marquee--tilt-b
   Renamed to .band — the name .marquee belonged to the hero's bulb frame,
   which has since been removed; .band is the better name regardless.
   Everything else is his: gold ground, 114% width bled equally either side,
   2deg rotation, a duplicated set scrolling -50% so the loop is seamless, and
   the separator drawn out of three bars rather than typed.
   The 114% overflow is clipped by .sec--room{overflow-x:clip}, which is now
   this band's parent. body{overflow-x:hidden} is still set as a backstop for
   Safari below 16, which does not support overflow clip.
   ========================================================================== */
.band{
  background:var(--gold);
  color:var(--gold-ink);          /* 7.0:1 on the gold — his #14100A equivalent */
  padding-block:13px;
  width:114%; margin-inline:-7%;
  position:relative; z-index:5;
  box-shadow:0 14px 44px -22px rgba(0,0,0,.85);
  overflow:hidden;
  user-select:none;
}
.band--tilt-b{rotate:2deg; margin-block:clamp(30px,5vw,54px)}

.band__track{display:flex; width:max-content; animation:bandslide 34s linear infinite}
.band__track--rev{animation-direction:reverse}
@keyframes bandslide{to{transform:translateX(-50%)}}

.band__set{display:flex; align-items:center; gap:34px; padding-right:34px; flex:none}
.band__set span{
  font-family:var(--disp); font-size:clamp(18px,2.6vw,33px);
  font-weight:700; text-transform:uppercase; letter-spacing:-.016em;
  white-space:nowrap;
}
/* Separator asterisk, drawn rather than typed. U+2733 has an emoji
   presentation that iOS renders as a green square, and the text variation
   selector is not reliably honoured — so no character is used at all.
   Three bars at 60° give a six-spoke asterisk in currentColor, identical on
   every platform, with the weight set here rather than by a font. */
.band__set i{
  flex:none; position:relative; display:block;
  width:clamp(12px,1.45vw,18px);      /* scales with the band text */
  height:clamp(2.8px,.34vw,4.2px);
  border-radius:2px;
  background:currentColor;
  opacity:.7;
  font-size:0;                        /* belt and braces: no glyph can render */
}
.band__set i::before,
.band__set i::after{
  content:""; position:absolute; inset:0;
  border-radius:inherit; background:currentColor;
}
.band__set i::before{rotate:60deg}
.band__set i::after{rotate:120deg}

@media (max-width:720px){
  .band{padding-block:10px}
}
@media (prefers-reduced-motion:reduce){
  .band__track{animation:none}
}

/* ==========================================================================
   Squad page : the full profiles behind the line-up
   The alternating portrait/copy rhythm the homepage #about used to carry,
   rehoused here now that the homepage shows only the line-up.
   ========================================================================== */
.squadpage{padding-top:calc(72px + env(safe-area-inset-top,0px))}
.squadpage__lede{
  max-width:60ch; margin:0 auto clamp(40px,5.5vw,72px);
  text-align:center; font-size:16.5px; line-height:1.7;
  color:var(--night-tx2);
}
.squadpage__lede + .profile{margin-top:0}
.profile{
  display:grid; grid-template-columns:.8fr 1.2fr;
  gap:clamp(28px,5vw,64px); align-items:center;
}
.profile + .profile{margin-top:clamp(48px,6.4vw,90px)}
.profile--flip .profile__fig{order:2}
.profile__fig{margin:0}
/* Uncropped, same as the line-up portraits. */
.profile__fig img{
  display:block; width:100%; height:auto; max-width:420px; margin-inline:auto;
  box-shadow:0 26px 46px rgba(0,0,0,.58);
}
.profile__bill{
  margin:0 0 6px;
  font-family:var(--disp); font-size:12px; font-weight:700;
  text-transform:uppercase; letter-spacing:.2em; color:var(--gold);
}
.profile__name{
  margin:0 0 18px;
  font-family:var(--disp); font-weight:700;
  font-size:clamp(26px,3.6vw,42px); letter-spacing:0; line-height:1.06;
  color:var(--night-tx);
}
.profile__copy p{color:var(--night-tx2); font-size:15.5px; line-height:1.64; margin:0}
.profile__copy p + p{margin-top:1em}
.profile__tag{color:var(--night-tx) !important; margin-top:1.2em !important}
.profile__tag strong{color:var(--gold-hi); font-weight:500}
/* The one genuine first-party line on the site, so it is set as a quotation
   rather than as another paragraph. */
.profile__quote{
  margin:1.4em 0 0; padding-left:18px;
  border-left:2px solid var(--gold-deep);
  color:var(--night-tx); font-size:15.5px; line-height:1.64; font-style:italic;
}
.profile__quote strong{color:var(--gold-hi); font-weight:500; font-style:normal}
.squadpage__cta{margin:clamp(44px,6vw,76px) 0 0; text-align:center}

@media (max-width:820px){
  .profile{grid-template-columns:1fr; gap:clamp(18px,3vw,28px)}
  .profile--flip .profile__fig{order:0}
  .profile__fig img{max-width:320px}
}

/* ==========================================================================
   Services : "What we get booked for"
   Built to the supplied comps (Services section, desktop@1x and mobile@1x),
   measured off them: a 1200px measure, a two-up card grid with a 32px gap,
   300px photo bays (220px on phones), a closing call-out box. Gold and the
   type faces are the site's own tokens; the card surfaces, lines and text
   greys are the comp's, scoped to this section as --svc-* so nothing else on
   the page moves.
   ========================================================================== */
.services{
  /* card tones are lighter steps of the section ground #090d12 (hue 213, sat 33%) */
  --svc-card:#0e151d;      /* card body, call-out box */
  --svc-bay:#141c27;       /* photo bay behind the image */
  --svc-line:#1a2635;      /* call-out border, rules inside each card */
  --svc-pill:#202f41;      /* chip and tag outlines */
  --svc-card-edge:rgba(138,109,44,.55); /* card border: --gold-deep, the card button's colour, held back */
  --svc-cream:#f2e6c8;     /* headings */
  --svc-tx:#c3c9d5;        /* card copy */
  --svc-tx-hi:#dfe2e8;     /* ticks, chip and tag labels */
  --svc-lede:#b7becc;      /* the intro under the heading, the call-out copy */
  --svc-gutter:clamp(16px,4vw,40px);
  padding-block:clamp(60px,5vw + 40px,112px) clamp(64px,5.3vw + 43px,120px);
}
.services > .wrap{max-width:calc(1200px + var(--svc-gutter) * 2); padding-inline:var(--svc-gutter)}

/* ---- head ---- */
.svc-head{margin-bottom:clamp(44px,2vw + 36px,64px)}
.svc-head .eyebrow{font-family:var(--disp); font-size:clamp(12px,.2vw + 11px,13px); font-weight:700; letter-spacing:.32em; margin-bottom:clamp(18px,1.4vw + 12px,26px)}
.svc-head .eyebrow::after{width:clamp(34px,1.4vw + 28px,48px); background:var(--gold)}
.svc-head__h{
  font-family:var(--disp); font-weight:700; text-transform:uppercase;
  color:var(--svc-cream);
  font-size:clamp(44px,3.52vw + 30.3px,81px); line-height:.97; letter-spacing:0;
  max-width:17ch;
}
.svc-head__lede{
  margin-top:clamp(18px,1vw + 14px,28px);
  max-width:620px;
  font-size:clamp(16px,.2vw + 15.2px,18px); line-height:1.7; color:var(--svc-lede);
}

/* chips: jump links to the four cards. They wrap on a wide screen; on a
   phone they become one row that scrolls inside itself, bleeding to the
   screen edge, so the page itself never scrolls sideways. */
.svc-chips{display:flex; flex-wrap:wrap; gap:10px; margin-top:clamp(28px,.6vw + 26px,34px)}
.svc-chip{
  display:inline-flex; align-items:center; gap:9px; flex:none;
  min-height:46px; padding:0 19px;
  border:1px solid var(--svc-pill); border-radius:999px;
  font-size:14px; font-weight:600; line-height:1; color:var(--svc-tx-hi); text-decoration:none;
  transition:border-color .22s var(--ease), color .22s var(--ease), background .22s var(--ease);
}
.svc-chip__n{font-size:11px; font-weight:700; color:var(--gold)}
.svc-chip:hover{border-color:var(--gold-deep); color:#fff; background:rgba(200,168,80,.06)}
.svc-chip:focus-visible{outline-offset:2px; border-radius:999px}

/* ---- the cards ---- */
.svc-grid{display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:32px}
.svc{
  display:flex; flex-direction:column;
  background:var(--svc-card); border:1px solid var(--svc-card-edge); border-radius:4px;
  overflow:hidden; scroll-margin-top:96px;
}
.svc__fig{position:relative; margin:0; height:300px; background:var(--svc-bay); border-bottom:1px solid var(--svc-line); overflow:hidden}
.svc__fig img{
  width:100%; height:100%; object-fit:cover;
  filter:saturate(.9) brightness(.92);
  transition:transform .9s var(--ease), filter .5s var(--ease);
}
.svc:hover .svc__fig img{transform:scale(1.03); filter:saturate(1) brightness(1)}
.svc__tag{
  position:absolute; top:20px; left:20px;
  display:inline-flex; align-items:center; min-height:32px; padding:0 12px;
  background:rgba(9,13,18,.88); border:1px solid var(--svc-pill); border-radius:999px;
  font-size:11px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:var(--svc-tx-hi);
}

.svc__body{display:flex; flex-direction:column; flex:1; padding:32px 36px 40px}
.svc__h{
  display:flex; align-items:baseline; gap:12px;
  font-family:var(--disp); font-weight:700; text-transform:uppercase; color:var(--svc-cream);
  font-size:clamp(25px,.2vw + 24px,27px); line-height:1.13; letter-spacing:0;
}
.svc__n{font-size:12px; font-weight:700; letter-spacing:.06em; color:var(--gold); flex:none}
.svc__p{margin-top:18px; font-size:16px; line-height:1.72; color:var(--svc-tx)}
.svc__narrow{display:none}

.svc__ticks{display:grid; gap:12px; margin-top:22px; padding-top:22px; border-top:1px solid var(--svc-line)}
.svc__ticks li{position:relative; padding-left:24px; font-size:14px; line-height:1.55; color:var(--svc-tx-hi)}
.svc__ticks li::before{
  content:""; position:absolute; left:0; top:.32em; width:13px; height:13px;
  background:var(--gold);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.5 8.5l3.6 3.4L13.5 4.5' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.5 8.5l3.6 3.4L13.5 4.5' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* Each card's "Book a quick call": a solid button pinned to the card's foot
   (margin-top:auto), so the two cards in a row line up. Natural width on a
   wide screen, full width on a phone. Same #booking target as the call-out.
   The ticks' margin-bottom is the least space it ever sits below them. */
.svc__ticks{margin-bottom:36px}
.svc__book{
  display:inline-flex; align-items:center; justify-content:center; gap:12px; align-self:flex-start;
  margin-top:auto; min-height:52px; padding:0 28px;
  background:#8a6d2c; color:#fffdf7; border-radius:4px;
  font-family:var(--disp); font-size:14px; font-weight:700; letter-spacing:.16em; text-transform:uppercase;
  line-height:1; text-decoration:none; white-space:nowrap;
  transition:background .22s var(--ease);
}
.svc__book:hover{background:#9e7f36}
.svc__book::after,
.svc-cta__btn::after{
  content:""; width:13px; height:13px; flex:none; background:currentColor;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.5 8h11M9 3.5L13.5 8 9 12.5' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.5 8h11M9 3.5L13.5 8 9 12.5' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
  transition:transform .22s var(--ease);
}
.svc__book:hover::after,
.svc-cta__btn:hover::after{transform:translateX(3px)}

/* ---- the call-out ---- */
.svc-cta{
  display:flex; align-items:center; justify-content:space-between; gap:32px;
  margin-top:64px; padding:clamp(20px,2.7vw + 9px,48px);
  background:var(--svc-card); border:1px solid var(--svc-line); border-radius:4px;
}
.svc-cta__h{
  font-family:var(--disp); font-weight:700; text-transform:uppercase; color:var(--svc-cream);
  font-size:clamp(26px,.57vw + 23.8px,32px); line-height:1.08; letter-spacing:0;
}
.svc-cta__p{margin-top:14px; max-width:560px; font-size:16px; line-height:1.7; color:var(--svc-lede)}
.svc-cta .svc-cta__btn{
  flex:none; min-height:56px; padding:0 36px; border-radius:3px;
  font-family:var(--disp); font-size:14px; letter-spacing:.24em; gap:14px;
}

/* ---- phones ---- */
@media (max-width:760px){
  .svc__wide{display:none}
  .svc__narrow{display:block}

  .svc-chips{
    flex-wrap:nowrap; overflow-x:auto; overscroll-behavior-x:contain;
    margin-inline:calc(var(--svc-gutter) * -1); padding-inline:var(--svc-gutter);
    scroll-padding-inline:var(--svc-gutter); scrollbar-width:none;
  }
  .svc-chips::-webkit-scrollbar{display:none}

  .svc-grid{grid-template-columns:minmax(0,1fr); gap:24px}
  .svc__fig{height:220px}
  .svc__tag{top:14px; left:14px}
  .svc__body{padding:22px 20px 20px}
  .svc__h{flex-direction:column; align-items:flex-start; gap:10px; line-height:1.08}
  .svc__p{margin-top:16px; line-height:1.62}
  .svc__ticks{gap:10px; margin-top:20px; padding-top:20px}
  .svc__ticks li{padding-left:28px; font-size:15px; line-height:1.5}
  .svc__ticks{margin-bottom:22px}
  .svc__book{align-self:stretch}

  .svc-cta{flex-direction:column; align-items:stretch; gap:20px; margin-top:44px}
  .svc-cta__p{margin-top:12px}
  .svc-cta .svc-cta__btn{width:100%}
}

/* ==========================================================================
   Reduced motion : the marquee stays lit, it just stops travelling
   ========================================================================== */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.001ms !important; animation-iteration-count:1 !important; transition-duration:.001ms !important}
  .bulb{animation:none; opacity:.92; box-shadow:0 0 7px 1px rgba(230,209,147,.45)}
  .hero__img{animation:none; transform:none}
  /* the logo stands lit, no entrance and no delayed fallback fade */
  .mark__img{animation:none; opacity:1}
  /* no film at all - the poster underneath stands. script.js also removes
     the element so nothing downloads; this covers JS being off. */
  .hero__vid{display:none}
  .strike{opacity:1; animation:none}
}

/* ==========================================================================
   Portrait devices : the portrait crop of the trio
   Last in the sheet on purpose. Media queries carry no extra specificity, so
   these have to sit after the base hero rules to win.
   ========================================================================== */
/* portrait devices get the portrait crop of the trio */
@media (orientation:portrait){
  .hero__img{object-position:50% 50%}
  /* Same inversion as the landscape scrim: light where the faces are, dark
     only at the foot where the copy sits. */
  .hero__scrim{
    background:
      linear-gradient(to bottom, rgba(7,9,15,.5) 0%, rgba(7,9,15,.14) 18%, rgba(7,9,15,.04) 44%, rgba(7,9,15,.34) 62%, rgba(7,9,15,.88) 82%, var(--night) 100%),
      linear-gradient(to right, rgba(7,9,15,.22), rgba(7,9,15,.02) 42%, rgba(7,9,15,.22));
  }
  /* the landscape halos read as murk over the portrait crop */
  /* The base rule carries a stronger shadow now; this used to override it
     with a weaker one, which is the wrong way round on the crop where the
     line sits closest to the faces. */
}


/* ==========================================================================
   Performer profile page  (kent-axell.html)
   --------------------------------------------------------------------------
   Structure follows the booking-directory profile the client supplied as a
   reference: a media panel beside a fixed summary card, then overview, media,
   reviews, booking information, bio and a service list, in that order.

   None of its materials come across. No rounded cards, no purple, no badge
   chips, no drop shadows under everything. The page is built from what this
   site already owns: --night ground, --night-2 panels, 1px gold hairlines,
   Josefin uppercase heads, Montserrat body, square corners throughout.

   The reference's rating block, "verified bookings" counter and FEATURED flag
   have no rules here because they have no markup - see the note at the top of
   kent-axell.html. If a real rating is ever collected first-party, it belongs
   between .pphero__tag and .ppmeta and nothing else has to move.
   ========================================================================== */

/* Clears the fixed header, same as .squadpage and .legalpage. */
.pprofile{padding-top:calc(72px + env(safe-area-inset-top,0px))}

.ppback{margin:0 0 clamp(18px,2.2vw,26px)}
.ppback a{
  font-family:var(--text); font-size:11.5px; font-weight:700;
  letter-spacing:.17em; text-transform:uppercase;
  color:var(--night-tx2); text-decoration:none;
  border-bottom:1px solid transparent; padding-bottom:2px;
  transition:color .25s var(--ease), border-color .25s var(--ease);
}
.ppback a:hover{color:var(--gold-hi); border-bottom-color:var(--gold)}

/* --------------------------------------------------------------------------
   Profile header
   The reference runs media ~60 / card ~40. Kept, because the card has to stay
   narrow enough that the meta rows read as a scannable list rather than as
   sentences stretched across a column.
   -------------------------------------------------------------------------- */
.pphero{
  background:var(--night); color:var(--night-tx);
  padding-block:clamp(26px,3.4vw,44px) clamp(44px,6vw,78px);
}
.pphero__grid{
  display:grid; grid-template-columns:minmax(0,1.55fr) minmax(0,1fr);
  gap:clamp(20px,2.8vw,38px);
  align-items:start;
}

/* The featured clip. .reel carries the frame, hairline, play button and
   label already; only the crop changes - this is the page's lead image, not
   a thumbnail in a strip. */
.pphero__media{min-width:0}
.pphero__reel img{aspect-ratio:16/9; filter:brightness(.72) saturate(.9)}
.pphero__reel .reel__label{left:12px; top:11px; font-size:10.5px}

.pphero__card{
  background:var(--night-2);
  border:1px solid rgba(200,168,80,.26);
  padding:clamp(20px,2.2vw,28px);
  display:flex; flex-direction:column; gap:clamp(16px,1.8vw,22px);
}

.pphero__id{display:grid; grid-template-columns:auto minmax(0,1fr); gap:15px; align-items:center}
/* Square-cornered, but 4:5 rather than square — the reference's circular
   avatar is the one borrowed shape that would have looked imported, and a
   square crop of a 4:5 poster throws away a fifth of it. These portraits are
   artwork with the performer's name set into them, and the standing rule on
   this project is that they are not cropped. 4:5 is the source ratio, so
   object-fit has nothing to remove. */
.pphero__thumb{
  width:62px; height:78px; object-fit:cover;
  border:1px solid rgba(200,168,80,.42);
}
.pphero__name{
  margin:0;
  font-family:var(--disp); font-weight:700; text-transform:uppercase;
  font-size:clamp(26px,3.1vw,38px); line-height:1.02; letter-spacing:.008em;
  color:var(--gold-hi);
}
.pphero__tag{
  margin:7px 0 0;
  font-family:var(--text); font-size:10.5px; font-weight:800;
  letter-spacing:.22em; text-transform:uppercase; color:var(--gold);
}

/* Same icon-row grammar as the line-up cards on the home page, so the two
   read as one family. */
.ppmeta{
  list-style:none; margin:0; padding:clamp(15px,1.7vw,19px) 0 0; width:100%;
  border-top:1px solid rgba(200,168,80,.18);
  display:flex; flex-direction:column; gap:11px;
}
.ppmeta li{
  display:grid; grid-template-columns:18px 1fr; gap:11px; align-items:center;
  font-size:14px; line-height:1.45; color:var(--night-tx2);
}
.ppmeta svg{
  width:16px; height:16px; fill:none;
  stroke:var(--gold); stroke-width:1.5;
  stroke-linecap:round; stroke-linejoin:round;
}

.pphero__acts{
  display:flex; flex-direction:column; gap:10px;
  padding-top:clamp(15px,1.7vw,19px);
  border-top:1px solid rgba(200,168,80,.18);
}

/* --------------------------------------------------------------------------
   Section rhythm
   The page has seven sections. .sec's clamp(64px,9vw,140px) is tuned for the
   home page's four big ones and would make this scroll forever, so the
   profile sections run tighter and lean on the gold rule to separate them.
   -------------------------------------------------------------------------- */
.ppsec{padding-block:clamp(40px,5vw,66px)}
.ppsec--tight{padding-block:clamp(32px,4vw,52px)}
.ppsec .rulepair--sec{margin-bottom:clamp(18px,2.2vw,26px)}

/* Long-form sections get a measure. 68ch is the legal pages' figure and it is
   right for the same reason: this is reading, not scanning. */
.ppcol .ppbody,
.ppcol .pplede,
.ppcol .pppress{max-width:68ch}

.pph2{
  font-family:var(--disp); font-weight:700; text-transform:uppercase;
  font-size:clamp(21px,2.5vw,32px); line-height:1.04; letter-spacing:.012em;
  color:var(--gold-hi); margin:0 0 clamp(16px,1.9vw,24px);
}
.pph3{
  font-family:var(--disp); font-weight:700; text-transform:uppercase;
  font-size:clamp(15px,1.5vw,19px); line-height:1.1; letter-spacing:.05em;
  color:var(--night-tx); margin:0 0 clamp(14px,1.6vw,18px);
}
.pph3--spaced{margin-top:clamp(30px,3.6vw,44px)}
.ppsub{
  margin:-6px 0 clamp(22px,2.6vw,32px);
  font-size:14.5px; line-height:1.6; color:var(--night-tx2); max-width:52ch;
}

.pplede{
  margin:0 0 clamp(24px,3vw,36px);
  font-family:var(--disp); font-weight:300;
  font-size:clamp(18px,2.1vw,26px); line-height:1.34; letter-spacing:.004em;
  color:var(--night-tx); text-wrap:balance;
}

.ppbody p{color:var(--night-tx2); font-size:15.5px; line-height:1.72; margin:0}
.ppbody p + p{margin-top:1em}
.ppbody em{color:var(--night-tx); font-style:italic}

/* --------------------------------------------------------------------------
   Press lines
   Set as a bordered stack rather than as cards: there are only two, and two
   cards in a row reads as a grid that lost its third item.
   -------------------------------------------------------------------------- */
.pppress{list-style:none; margin:0; padding:0; display:grid; gap:clamp(14px,1.7vw,20px)}
.pppress li{border-left:2px solid var(--gold-deep); padding:2px 0 2px clamp(16px,1.8vw,22px)}
.pppress blockquote{
  margin:0;
  font-family:var(--disp); font-weight:400; font-style:italic;
  font-size:clamp(16px,1.7vw,21px); line-height:1.4; color:var(--night-tx);
}
.pppress cite{
  display:block; margin-top:8px; font-style:normal;
  font-family:var(--text); font-size:10.5px; font-weight:800;
  letter-spacing:.2em; text-transform:uppercase; color:var(--gold);
}

/* --------------------------------------------------------------------------
   Photos
   Two-up, not the home page gallery's three. There are four frames here that
   are genuinely Kent's, and four tiles across a three-column grid leave one
   hanging alone on a second row — which reads as a photo that failed to load
   rather than as the end of the set. Two columns also runs them larger, which
   a set this small can afford.
   -------------------------------------------------------------------------- */
.ppshots{margin:0; grid-template-columns:repeat(2,1fr)}

/* --------------------------------------------------------------------------
   Reviews
   Two-up rather than the reference's masonry. These four run from one line to
   four, and a masonry of four unequal cards leaves a ragged hole that reads as
   a layout bug. Equal-height cards in a grid simply do not have that problem.
   -------------------------------------------------------------------------- */
.pprev{
  list-style:none; margin:0; padding:0;
  display:grid; grid-template-columns:repeat(2,1fr);
  gap:clamp(12px,1.6vw,18px);
}
.pprev__card{
  background:linear-gradient(160deg,var(--night-2),#0a0e15);
  border:1px solid rgba(200,168,80,.22);
  padding:clamp(18px,2vw,24px);
  display:flex; flex-direction:column; align-items:flex-start; gap:11px;
  transition:border-color .35s var(--ease), transform .35s var(--ease);
}
.pprev__card:hover{border-color:var(--gold-deep); transform:translateY(-3px)}

.pprev__top{display:grid; grid-template-columns:auto minmax(0,1fr); gap:12px; align-items:center; width:100%}
/* Monogram, the same device as the testimonial rail on the home page. A real
   photograph would be better and there are none, and a stock face standing in
   for a named reviewer is a lie with a picture on it. */
.pprev__av{
  width:38px; height:38px; display:grid; place-items:center;
  background:rgba(200,168,80,.13);
  border:1px solid rgba(200,168,80,.34);
  font-family:var(--disp); font-weight:700; font-size:16px;
  letter-spacing:.02em; color:var(--gold-hi);
}
.pprev__who{display:flex; flex-direction:column; gap:2px; min-width:0}
.pprev__who b{
  font-family:var(--text); font-size:14px; font-weight:700;
  letter-spacing:.01em; color:var(--night-tx);
}
.pprev__who time{font-size:12px; letter-spacing:.04em; color:var(--night-tx2)}

.pprev__title{
  margin:0;
  font-family:var(--text); font-size:14.5px; font-weight:700;
  line-height:1.4; color:var(--gold-hi);
}
.pprev__body{margin:0; font-size:14.5px; line-height:1.75; color:var(--night-tx2)}

/* --------------------------------------------------------------------------
   At a glance
   -------------------------------------------------------------------------- */
.ppglance{
  margin:0; display:grid; grid-template-columns:repeat(3,1fr);
  gap:clamp(12px,1.6vw,20px);
}
.ppglance > div{
  border:1px solid rgba(200,168,80,.2);
  background:var(--night-2);
  padding:clamp(15px,1.7vw,20px);
}
.ppglance dt{
  display:flex; align-items:center; gap:9px;
  font-family:var(--text); font-size:10.5px; font-weight:800;
  letter-spacing:.2em; text-transform:uppercase; color:var(--gold);
  margin-bottom:9px;
}
.ppglance dt svg{
  width:15px; height:15px; flex:0 0 auto; fill:none;
  stroke:var(--gold); stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round;
}
.ppglance dd{margin:0; font-size:15px; line-height:1.5; color:var(--night-tx)}

/* --------------------------------------------------------------------------
   Services offered
   The reference's pill cloud, squared off. These are categories, not links -
   nothing to click, so nothing is dressed as a button.
   -------------------------------------------------------------------------- */
.ppchips{
  list-style:none; margin:0; padding:0;
  display:flex; flex-wrap:wrap; gap:9px;
}
.ppchips li{
  border:1px solid rgba(200,168,80,.28);
  background:rgba(200,168,80,.05);
  padding:9px 15px;
  font-family:var(--text); font-size:12px; font-weight:600;
  letter-spacing:.09em; text-transform:uppercase; color:var(--night-tx2);
}

/* The closing call is borrowed from the home page, where .h2 at up to 4.4rem
   is the largest thing in a section of its own. Here it follows six headings
   capped at 32px, and at full size it stops reading as the end of the page and
   starts reading as a different page. Brought down to sit a step above .pph2. */
.ppfinal{padding-block:clamp(46px,6vw,82px)}
.ppfinal .h2{
  font-size:clamp(26px,3.4vw,44px);
  max-width:16ch; margin-bottom:.44em;
}

/* --------------------------------------------------------------------------
   Narrow
   -------------------------------------------------------------------------- */
@media (max-width:980px){
  /* The summary card stops being a sidebar and becomes the block under the
     video. Order is explicit so the card follows its media rather than
     depending on source order surviving a future edit. */
  .pphero__grid{grid-template-columns:1fr}
  .pphero__media{order:1}
  .pphero__card{order:2}
}

@media (max-width:760px){
  .pprev{grid-template-columns:1fr}
  .ppglance{grid-template-columns:1fr}
}

@media (max-width:420px){
  .pphero__thumb{width:56px; height:56px}
  .ppchips li{padding:8px 12px; font-size:11px; letter-spacing:.07em}
}


/* --------------------------------------------------------------------------
   Line-up card: the link through to a performer profile
   Only Kent has a page so far. These rules are written for all three, so
   adding .pcard--link and wrapping the name is the whole job later.

   THE HIT AREA IS THE WHOLE CARD, and on a phone that is the entire point.
   The name alone is about 112x24px — under half the 44px minimum in both
   axes. The card no longer drifts, which removes the worst of it, but a
   target that small is still one plenty of people miss, and a miss reads as
   "the card isn't clickable", because nothing happens.

   Done with a stretched ::after rather than by wrapping the card in an <a>:
   the card already contains the booking CTA, and an anchor cannot contain
   another anchor. The overlay covers everything, then .pcard__cta is lifted
   back above it so it keeps its own tap.
   -------------------------------------------------------------------------- */
.pcard--link{position:relative; cursor:pointer}
.pcard__link{
  display:inline-flex; align-items:center; gap:.4em;
  color:inherit; text-decoration:none;
  border-bottom:1px solid transparent; padding-bottom:1px;
  transition:color .25s var(--ease), border-color .25s var(--ease);
}
.pcard__link::after{
  content:""; position:absolute; inset:0; z-index:1;
}
/* Above the overlay, so the booking CTA is still its own button. */
.pcard__cta{position:relative; z-index:2}
.pcard__link svg{
  width:.62em; height:.62em; flex:0 0 auto; fill:none;
  stroke:currentColor; stroke-width:2.2;
  stroke-linecap:round; stroke-linejoin:round;
  /* nudged down: the arrow centres on the glyph box, which sits high against
     an all-caps display face with no descenders in it. A static offset, not
     an animated one — the arrow used to slide right on hover and that is
     movement, which this section no longer does. */
  translate:0 .06em;
  opacity:.55;
  transition:opacity .25s var(--ease);
}
.pcard--link:hover .pcard__link{color:var(--gold); border-bottom-color:var(--gold-deep)}
.pcard--link:hover .pcard__link svg{opacity:1}
/* The focus ring goes on the card, because the card is what the link covers.
   A ring drawn tight around the name would point at the wrong thing. */
.pcard__link:focus-visible{outline:none; border-bottom-color:transparent}
.pcard--link:has(.pcard__link:focus-visible){outline:2px solid var(--gold); outline-offset:3px}
/* Touch has no hover, so a press needs its own feedback. Border colour only. */
.pcard--link:active{border-color:var(--gold-deep)}

/* The global .btn lifts 1px on hover and dips 1px on press. That is right
   everywhere else on the site and is left alone there; inside these cards it
   is the last moving part, so it is cancelled here and nowhere else. */
.pcard__cta:hover,
.pcard__cta:active{transform:none}

/* squad.html: the button through to the full profile */
.profile__more{margin-top:clamp(18px,2.2vw,26px)}


/* ==========================================================================
   SECTION SEPARATION : tones, dividers and decorative depth
   --------------------------------------------------------------------------
   The page was one flat near-black scroll. This gives each section its own
   ground and a little atmosphere, without adding a single image file and
   without anything that moves.

   THREE RULES EVERYTHING HERE FOLLOWS
   1. Decoration is drawn on a .deco element or a pseudo-element, never on
      content. Every one is pointer-events:none and aria-hidden, so none of it
      can take a click or reach a screen reader.
   2. Sections that carry bleeding decoration get overflow:clip — clip rather
      than hidden, because clip does not create a scroll container and so
      cannot trap scroll anchoring or sticky children.
   3. Opacity is in the 2-8% range throughout. Anything you can clearly see
      without looking for it is too strong for a background.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Tones
   Three dark grounds plus a darker footer. They sit close together on purpose:
   the job is to say "this is a different block", not to stripe the page.

   All three stay BELOW --night-2 (#0d1119), which is the fill behind every
   card and panel on the site. If a ground were lighter than its cards the
   cards would sink into it instead of lifting off it.
   -------------------------------------------------------------------------- */
:root{
  --tone-a:#07090f;   /* the existing near-black — the page's base note */
  --tone-b:#0a0e16;   /* a touch lighter, cooler. Charcoal. */
  --tone-c:#0a0811;   /* as dark as A but warm — a plum cast, not a blue one */
  --tone-foot:#050609;/* darkest. Nothing sits below the footer. */

  /* one gold, three strengths, so every decoration is mixing the same colour */
  --deco-glow:rgba(200,168,80,.07);
  --deco-line:rgba(200,168,80,.055);
  --deco-mark:rgba(200,168,80,.035);
}

/* --------------------------------------------------------------------------
   The decoration layer
   One element per section, first child, absolutely filling it. Content needs
   to sit above it, which is what .sec > .wrap gets below.
   -------------------------------------------------------------------------- */
.deco{
  position:absolute; inset:0;
  pointer-events:none;
  z-index:0;
  overflow:hidden;
}
/* Everything that is not decoration sits above it. */
.callform > .wrap,
.services > .wrap,
.gallery > .wrap,
.about > .wrap,
.quotes > .wrap,
.finalcall > .wrap{position:relative; z-index:1}

/* clip, not hidden — see rule 2 at the top of this block */
.callform,
.services,
.gallery,
.about,
.quotes,
.finalcall{position:relative; overflow:clip}

/* --------------------------------------------------------------------------
   Grain
   An SVG feTurbulence tile, not a PNG. Breaks up the flatness of a large
   dark field, which is where banding shows worst on cheap panels.
   -------------------------------------------------------------------------- */
.deco--grain::after{
  content:""; position:absolute; inset:0;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity:.035;
  mix-blend-mode:overlay;
}

/* --------------------------------------------------------------------------
   Light from above: THE decoration grammar for this page.

   There used to be five of these - edge fans, a sunburst, a spade watermark, a
   vignette and three pools on the thirds - one per section, each inventing its
   own idea. Five different ornaments across six sections is not a system, it
   is the look of something assembled, and two of them (hairline grids used as
   decoration, a glow with no source) are on every list of the tells this kind
   of page gives off.

   One gesture now, repeated: a whisper of warm light decaying from the top
   edge, as if each section sat under the same lamp. It carries the warmth, it
   costs one gradient, and it reads as intentional precisely because it does
   not change from section to section. The tones do the separating; this does
   the atmosphere.
   -------------------------------------------------------------------------- */
.deco--top::before{
  content:""; position:absolute; left:0; right:0; top:0; height:clamp(140px,22vw,260px);
  background:linear-gradient(180deg, rgba(200,168,80,.05), transparent);
}

/* The one place that gets more than the others, because it is the last thing
   asked of a visitor. Spend the boldness once. */
.deco--spot::before{
  content:""; position:absolute; inset:0;
  background:radial-gradient(54% 60% at 50% 16%, rgba(200,168,80,.11), transparent 72%);
}




/* The supplied quotation mark, drawn rather than typed. It was the "C"
   glyph in the display face, which meant its weight and proportion were
   whatever Josefin happened to give it. This is the mark the client sent: two
   heavy geometric blocks with a tail falling away to the left, mirrored
   horizontally as asked.

   A mask rather than a fill, so the colour stays a brand token instead of
   being baked into the data URI. */
.deco--quote::before{
  content:""; position:absolute;
  left:-1.5%; top:-2%;
  width:min(32vw,370px); aspect-ratio:230/100;
  background:rgba(200,168,80,.085);
  transform:scaleX(-1);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 230 100'%3E%3Cpath d='M0 0H100V58L55 100H18L62 58H0Z M130 0H230V58L185 100H148L192 58H130Z'/%3E%3C/svg%3E") no-repeat center / contain;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 230 100'%3E%3Cpath d='M0 0H100V58L55 100H18L62 58H0Z M130 0H230V58L185 100H148L192 58H130Z'/%3E%3C/svg%3E") no-repeat center / contain;
}

/* --------------------------------------------------------------------------
   Eyebrow
   A short gold label over each section heading, flanked by two rules. The
   rules are pseudo-elements, so they are inert without needing an attribute;
   the label itself is real text and stays readable, because "Our services"
   genuinely labels what follows.
   -------------------------------------------------------------------------- */
.eyebrow{
  display:flex; align-items:center; justify-content:center; gap:14px;
  margin:0 0 clamp(14px,1.8vw,20px);
  font-family:var(--text);
  font-size:10.5px; font-weight:800;
  letter-spacing:.3em; text-transform:uppercase;
  color:var(--gold);
  /* the tracking is on the right of the last letter too, which throws the
     optical centre left by half a space */
  text-indent:.3em;
}
.eyebrow::before,
.eyebrow::after{
  content:""; height:1px; width:clamp(22px,4vw,54px); flex:none;
  background:var(--gold-deep);
}
/* left-aligned heads (services, gallery) get a left-aligned eyebrow */
.eyebrow--start{justify-content:flex-start}
.eyebrow--start::before{display:none}

/* --------------------------------------------------------------------------
   Section divider
   The reusable one: a hairline that fades at both ends with a gold diamond at
   its centre. This is .fleuron, promoted out of .about and .quotes where it
   was written twice identically, so there is now one of it.
   -------------------------------------------------------------------------- */
.fleuron{
  display:block; margin:22px auto 0;
  width:100%; max-width:140px; position:relative; height:9px;
}
.fleuron::before{
  content:""; position:absolute; inset-block:50%; left:0; right:0; height:1px;
  background:linear-gradient(90deg,transparent,rgba(200,168,80,.30) 22%,rgba(200,168,80,.30) 78%,transparent);
}
.fleuron::after{
  content:""; position:absolute; left:50%; top:50%;
  width:9px; height:9px; translate:-50% -50%; rotate:45deg;
  background:var(--gold);
}
/* standalone, between two sections rather than under a heading */
.fleuron--between{
  max-width:min(560px,78%);
  margin-block:0;
  padding-block:clamp(26px,4vw,52px);
  height:auto;
}
.fleuron--between::before{inset-block:50%}
.fleuron--between::after{top:50%}

/* --------------------------------------------------------------------------
   The tones, applied
   Order down the page: form A, brands cream, services B, gallery A,
   performers C, testimonials B, final call A, footer darkest.
   -------------------------------------------------------------------------- */
/* .callform has its own ground, #0c0d13 - see the BOOKING block */
.services{background:#090d12}   /* its own ground, set by the client; the tone rotation skips it */
.gallery{background:var(--tone-a)}
.quotes{background:var(--tone-b)}
.finalcall{background:var(--tone-a)}
.foot{background:var(--tone-foot)}

/* --------------------------------------------------------------------------
   Per section
   -------------------------------------------------------------------------- */

/* BOOKING — built to the supplied comps (Booking section, desktop@1x and
   mobile@1x). Every colour here is the brief's own hex: they are this
   section's palette, scoped as --bk-* so nothing else on the page moves.
   Selectors are prefixed .callform so they win over the shared form rules
   higher up this sheet without touching them. */
.callform{
  --bk-ground:#0c0d13;
  --bk-card:#0a0e15;
  --bk-edge:#302d21;      /* form card, contact card, step dividers */
  --bk-corner:#8a6d2c;    /* corner accents, step rings, suits, eyebrow rules */
  --bk-field:#0d1119;
  --bk-field-edge:#453f29;
  --bk-check-edge:#363226;
  --bk-badge-edge:#494644;
  --bk-head:#e6d193;
  --bk-label:#c8a850;
  --bk-body:#a89c89;
  --bk-bright:#fffdf7;
  --bk-gutter:clamp(16px,4vw,40px);
  background:var(--bk-ground);
  padding-block:clamp(64px,4.6vw + 46px,112px) clamp(72px,4.6vw + 46px,120px);
}
/* the sunburst: 72 equal wedges from a point just above the top centre, so
   36 rays fan down; faded out with distance so it lives behind the head only */
.callform::before,
.callform::after{
  content:""; position:absolute; z-index:0; pointer-events:none;
  left:50%; top:0; transform:translateX(-50%);
  width:max(100%,1440px); height:clamp(520px,40vw + 140px,760px);
}
.callform::before{
  background:repeating-conic-gradient(from 0deg at 50% -48px, rgba(200,168,80,.075) 0deg 2.5deg, transparent 2.5deg 5deg);
  -webkit-mask:radial-gradient(ellipse 50% 100% at 50% 0, #000 0%, rgba(0,0,0,.55) 45%, transparent 80%);
          mask:radial-gradient(ellipse 50% 100% at 50% 0, #000 0%, rgba(0,0,0,.55) 45%, transparent 80%);
}
/* and a soft glow pooled at the top, under the headline */
.callform::after{
  background:radial-gradient(ellipse 30% 42% at 50% 0, rgba(200,168,80,.08), rgba(200,168,80,0) 72%);
}

/* ---- head ---- */
.callform .callform__head{text-align:center; margin-bottom:clamp(40px,3.4vw + 27px,76px)}
.callform__head .eyebrow{font-size:11px; letter-spacing:.32em; gap:16px; margin-bottom:clamp(14px,.8vw + 11px,22px)}
.callform__head .eyebrow::before,
.callform__head .eyebrow::after{width:clamp(18px,2.9vw + 7px,48px); background:var(--bk-corner)}
.callform__h{
  font-family:var(--disp); font-weight:700; text-transform:uppercase; color:var(--bk-head);
  font-size:clamp(37px,3.81vw + 22.1px,77px); line-height:.95; letter-spacing:0;
  max-width:920px; margin-inline:auto;
}
.callform__suits{display:flex; justify-content:center; gap:clamp(18px,1.2vw + 14px,30px); margin-top:clamp(20px,2.3vw + 11px,46px)}
.callform__suits svg{width:clamp(16px,.4vw + 14.5px,20px); height:clamp(16px,.4vw + 14.5px,20px); fill:var(--bk-corner)}
.callform .callform__sub{
  margin:clamp(16px,1.2vw + 12px,30px) auto 0; max-width:620px;
  font-size:clamp(15.5px,.24vw + 14.6px,18px); line-height:1.62; color:var(--bk-body);
}

/* ---- the two columns ---- */
.callform .callform__in{
  max-width:calc(1200px + var(--bk-gutter) * 2); padding-inline:var(--bk-gutter);
  display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:60px;
  grid-template-areas:"next form"; align-items:start;
}
.callform__formcol{grid-area:form; min-width:0}
.callform__next{grid-area:next; min-width:0; padding-top:16px}

/* ---- form card ---- */
.callform .formframe{
  position:relative;
  background:var(--bk-card); border:1px solid var(--bk-edge);
  padding:36px 32px 34px;
}
.callform .formframe::before,
.callform .formframe::after{content:""; position:absolute; pointer-events:none; width:16px; height:16px; border:2px solid var(--bk-corner)}
.callform .formframe::before{top:-1px; left:-1px; border-right:0; border-bottom:0}
.callform .formframe::after{bottom:-1px; right:-1px; border-left:0; border-top:0}

.callform .f2{gap:18px}
.callform .field{gap:10px; margin-bottom:22px}
.callform .field label{font-size:11px; font-weight:800; letter-spacing:.2em; color:var(--bk-label); gap:8px; flex-wrap:wrap}
.callform .req{
  font-size:9.5px; font-weight:600; letter-spacing:.1em; line-height:1.5;
  color:var(--bk-body); border:1px solid var(--bk-badge-edge); padding:1px 6px;
}
.callform .opt{margin-left:0; font-size:10px; font-weight:600; letter-spacing:.12em; color:var(--bk-body)}
.callform .field input,
.callform .field textarea,
.callform .field select{
  min-height:46px; padding:12px 14px; font-size:15px;
  background:var(--bk-field); border:1px solid var(--bk-field-edge); border-radius:0;
  color:var(--bk-head);
}
.callform .field textarea{min-height:116px}
.callform .field input:hover,
.callform .field textarea:hover,
.callform .field select:hover{border-color:#6b5f3a}
.callform .field input:focus,
.callform .field textarea:focus,
.callform .field select:focus{outline:none; border-color:var(--bk-label); background:var(--bk-field); box-shadow:none}
.callform .field input[aria-invalid="true"],
.callform .field select[aria-invalid="true"],
.callform .field textarea[aria-invalid="true"]{border-color:var(--red-hi); box-shadow:none}
.callform .field select{color:var(--bk-bright)}
.callform .selwrap__c{stroke:var(--bk-bright); stroke-width:1.8}
.callform .telwrap{grid-template-columns:minmax(0,190px) minmax(0,1fr); gap:6px}
.callform .selwrap--dial select{max-width:none}

/* SMS consent boxes */
.callform .field--check{
  margin-top:24px; padding:16px 16px 16px 14px; gap:0 12px;
  background:var(--bk-field); border:1px solid var(--bk-check-edge);
}
.callform .field--check + .field--check{margin-top:22px}
.callform .field--check input[type="checkbox"]{width:16px; height:16px; margin-top:3px; accent-color:var(--bk-label)}
/* resets what .callform .field label gives the field labels above */
.callform .field--check > label{display:block; font-size:12.5px; font-weight:400; line-height:1.6; letter-spacing:0; text-transform:none; color:var(--bk-body)}
.callform .field--check > label a,
.callform .formlegal a{color:var(--bk-label); text-decoration:underline; text-underline-offset:3px}
.callform .field--check > label a:hover,
.callform .formlegal a:hover{color:var(--bk-head)}

.callform #submit{
  margin-top:22px; min-height:50px; border-radius:0;
  background:#a8141d; border-color:#a8141d; color:#fff;
  font-size:13px; letter-spacing:.2em;
}
.callform #submit:hover{background:var(--red-hi); border-color:var(--red-hi)}
.callform .formnote{margin-top:12px}
.callform .formlegal{margin-top:12px; font-size:12.5px; line-height:1.6; color:var(--bk-body)}

/* ---- what happens next ---- */
.callform__nextk{
  font-size:11px; font-weight:800; letter-spacing:.22em; text-transform:uppercase; color:var(--bk-label);
}
.callform__nexth{
  margin-top:8px;
  font-family:var(--disp); font-weight:700; text-transform:uppercase; color:var(--bk-head);
  font-size:clamp(26px,.5vw + 23px,30px); line-height:1.1; letter-spacing:.01em;
}
.steps{margin-top:44px; border-top:1px solid var(--bk-edge); counter-reset:none}
.steps__i{
  display:grid; grid-template-columns:58px minmax(0,1fr); gap:16px; align-items:start;
  padding:22px 0 26px; border-bottom:1px solid var(--bk-edge);
}
.steps__i:last-child{border-bottom:0}
/* the gold disc, a gap of ground, then a thin outer ring */
.steps__n{
  display:grid; place-items:center; width:48px; height:48px; margin:5px;
  border-radius:50%; background:var(--bk-label); color:var(--bk-ground);
  font-family:var(--disp); font-weight:700; font-size:18px; line-height:1;
  box-shadow:0 0 0 4px var(--bk-ground), 0 0 0 5px var(--bk-corner);
}
.steps__t{padding-top:7px}
.steps__h{margin:0; font-family:var(--text); font-size:17px; font-weight:600; line-height:1.4; color:var(--bk-head)}
.steps__p{margin-top:4px; font-size:15px; line-height:1.67; color:var(--bk-bright)}

/* ---- prefer to reach us directly ---- */
.callform .callform__direct{
  margin:60px 0 0; padding:26px 28px 14px; text-align:left;
  background:var(--bk-card); border:1px solid var(--bk-edge);
  font-size:15px; color:var(--bk-body);
}
.callform__directh{font-size:16px; font-weight:600; color:var(--bk-head); margin-bottom:6px}
.callform .callform__link{
  display:flex; align-items:center; gap:14px; min-height:48px; width:fit-content; max-width:100%;
  color:var(--bk-label); text-decoration:underline; text-underline-offset:3px;
  font-size:15px; overflow-wrap:anywhere;
}
.callform .callform__link + .callform__link{margin-top:10px}
.callform .callform__link:hover{color:var(--bk-head)}
.callform__link svg{width:18px; height:18px; flex:none; fill:none; stroke:var(--bk-label); stroke-width:1.6; stroke-linecap:round; stroke-linejoin:round}

/* ---- one column: header, form, steps, contact ---- */
@media (max-width:900px){
  .callform .callform__in{grid-template-columns:minmax(0,1fr); grid-template-areas:"form" "next"; gap:44px}
  .callform__next{padding-top:0}
}
@media (max-width:600px){
  .callform .formframe{padding:24px 20px 22px}
  .callform .f2{grid-template-columns:minmax(0,1fr); gap:0}
  .callform .field{margin-bottom:20px}
  .callform .field--check{padding:14px 14px 14px 12px}
  .callform__nexth{position:absolute; width:1px; height:1px; margin:-1px; overflow:hidden; clip-path:inset(50%); white-space:nowrap}
  .steps{margin-top:14px}
  .steps__i{grid-template-columns:48px minmax(0,1fr); gap:14px; padding:18px 0 20px}
  .steps__n{width:40px; height:40px; margin:4px; font-size:16px}
  .steps__t{padding-top:2px}
  .steps__h{font-size:16px}
  .steps__p{font-size:15px; line-height:1.6}
  .callform .callform__direct{margin-top:32px; padding:22px 20px 10px}
}
@media (max-width:359px){
  .callform .telwrap{grid-template-columns:minmax(0,1fr); gap:10px}
}

/* GALLERY — a thin gold frame around the grid. */
.shots{
  padding:clamp(10px,1.4vw,16px);
  border:1px solid rgba(200,168,80,.17);
}

/* PERFORMERS. The curved top edge is gone, on request: the section's top is
   flat and full width.

   The curve also needed the section to be a different tone from the gallery
   above it, or there was nothing for the arc to read against. With it removed
   that tone difference becomes a visible horizontal step instead, so this
   section now takes --tone-a and meets the gallery seamlessly. The gold
   hairline that used to sit on this edge stays off for the same reason - a
   1px rule IS the seam the brief asks to remove.

   .quotes below is still --tone-b, so the alternation survives where it can
   still be seen. Nothing inside the section changes, and the gold wave on
   each performer card is untouched. */
.about{background:var(--tone-a)}
.about::before{display:none}

/* TESTIMONIALS — one large quotation mark, cropped by the heading. */
.quotes .deco--quote::before{opacity:1}

/* FINAL CALL — the loudest section. Sunburst, a stronger pool, and a gold
   rule top and bottom. */
.finalcall{
  border-top:1px solid rgba(200,168,80,.26);
  border-bottom:1px solid rgba(200,168,80,.26);
}

/* --------------------------------------------------------------------------
   Phones
   The heavy decorations come off below 768px. On a 375px screen a sunburst
   behind a headline is not atmosphere, it is a texture fighting the text.
   -------------------------------------------------------------------------- */
@media (max-width:767px){
      .deco--grain::after{opacity:.03}
  .formframe{padding:clamp(16px,4vw,22px)}
  .fleuron--between{padding-block:clamp(20px,6vw,30px)}
}

@media (prefers-reduced-motion:reduce){
  /* nothing here moves, so there is nothing to switch off — noted so the next
     person does not go looking for it */
}
