/* ============================================================================
   THE DREAM BARBERSHOP — thedreambarbershop.us
   ----------------------------------------------------------------------------
   The website wears the same clothes as the lobby TV and the owner's report:
   a near-black ground lit by the logo's own gold with the barber pole's red and
   blue, glass panels on hairline borders, Playfair Display with one italic gold
   word, Manrope for everything else, and the barbers' colours as rings.

   But this is a storefront, not a tool. Everything here is bigger, slower and
   more cinematic than the app: full-bleed photography, one idea per screen, a
   slow reveal as you scroll. Gold stays rare — a headline word, a rule, the
   buttons.

   The site is deliberately standalone: it loads nothing from the app's public/
   folder. The token block below is copied by value from public/dream.css (which
   in turn matches public/luxe.css). If a brand colour ever changes, change it
   in all three or in none.
   ============================================================================ */


/* ---------- 1. tokens ---------------------------------------------------- */
/* IDENTICAL IN VALUE to :root in public/dream.css and public/luxe.css. */
:root{
  --ground:#0B0908;
  --ink:#F2E8D6;                          /* the logo's ivory */
  --ink-2:rgba(242,232,214,.74);
  --ink-3:rgba(242,232,214,.50);
  --gold:#F7A945;                         /* the logo's gold */
  --gold-hi:#FFC766;
  --gold-lo:#D98A2B;
  --pole-red:#D9402C;
  --pole-blue:#5374AA;
  --hair:rgba(255,236,210,.10);
  --hair-2:rgba(255,236,210,.16);
  --glass:rgba(255,244,228,.035);
  --serif:"Playfair Display",Georgia,"Times New Roman",serif;
  --sans:Manrope,"Segoe UI",system-ui,-apple-system,sans-serif;
}

/* Website-only tokens. A storefront reads from further away than an iPad in
   the hand, so the type scale runs higher and the spacing is far looser. */
:root{
  color-scheme:dark;
  --on-gold:#1B1309;
  --brass:linear-gradient(180deg,var(--gold-hi),var(--gold) 58%,var(--gold-lo));
  --gold-line:rgba(247,169,69,.45);
  --gold-tint:rgba(247,169,69,.08);
  --hair-row:rgba(255,236,210,.08);

  /* type: 390-wide phone at the low end, 1920 desktop at the top */
  /* The hero headline shares the frame with the photograph and the two
     buttons; it is not the frame. It ran to 118px across a laptop, which read
     as a type specimen with a shop behind it rather than the other way round.
     45px on a phone (still one line), 84px at the top. */
  --fs-hero:clamp(44px,calc(26px + 4.8vw),84px);
  --fs-h2:clamp(32px,calc(19px + 3.5vw),62px);
  --fs-h3:clamp(20px,calc(15.6px + 1.15vw),29px);
  --fs-lede:clamp(17px,calc(14.4px + .68vw),23px);
  --fs-body:clamp(15.5px,calc(14.1px + .37vw),19px);
  --fs-small:clamp(13.5px,calc(12.6px + .23vw),16px);
  --fs-eyebrow:clamp(10.5px,calc(9.7px + .2vw),13px);
  --fs-price:clamp(19px,calc(15px + 1.05vw),27px);
  --fs-rating:clamp(58px,calc(34px + 6.3vw),118px);

  /* space + shape */
  --gutter:clamp(20px,5vw,56px);
  /* the air above and below a section. Generous, but not so generous that a
     laptop scrolls through a screen of nothing between two ideas. */
  --band:clamp(58px,calc(26px + 6.6vw),134px);
  --gap:clamp(16px,calc(10px + 1.6vw),32px);
  --tap:52px;
  --r-panel:clamp(16px,calc(11px + 1.2vw),24px);
  --r-tile:clamp(12px,calc(9px + .8vw),18px);
  --shadow:0 24px 64px rgba(0,0,0,.5),inset 0 1px 0 rgba(255,244,228,.07);
  --ease:cubic-bezier(.2,.7,.2,1);
  --max:1200px;
}


/* ---------- 2. the ground ------------------------------------------------ */
*,*::before,*::after{box-sizing:border-box}
[hidden]{display:none!important}

html{
  /* No background on <html>: it would cover the glows on <body>. */
  scroll-behavior:smooth;
  /* the hero is full height, so anchors need to clear nothing, but the headings
     below want a little air when you land on them */
  scroll-padding-top:clamp(12px,3vw,32px);
}

body.dream{
  margin:0;min-height:100svh;
  color:var(--ink);font:500 var(--fs-body)/1.6 var(--sans);
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
  text-rendering:optimizeLegibility;-webkit-tap-highlight-color:transparent;
  -webkit-text-size-adjust:100%;text-size-adjust:100%;
  background:var(--ground);
  scrollbar-color:rgba(242,232,214,.18) transparent;
}
/* The three glows sit on a fixed layer rather than background-attachment,
   which iOS ignores — on a page this long the light would stretch. */
body.dream::before{
  content:"";position:fixed;inset:0;z-index:-2;pointer-events:none;
  background:
    radial-gradient(60% 55% at 10% -6%, rgba(247,169,69,.17), transparent 62%),
    radial-gradient(46% 52% at 104% 104%, rgba(83,116,170,.17), transparent 64%),
    radial-gradient(34% 38% at 92% -4%, rgba(217,64,44,.11), transparent 62%);
}
/* the logo again, huge and faint, behind everything */
/* Quieter than the app's, because a website is read at leisure and the eye
   has time to notice it. It is a texture, not a logo. */
.mark{
  position:fixed;z-index:-1;left:0;bottom:0;width:clamp(460px,62vw,1180px);height:auto;
  transform:translate(-28%,38%);opacity:.022;filter:grayscale(1) blur(1.6px);
  pointer-events:none;user-select:none;-webkit-user-drag:none}

::selection{background:rgba(247,169,69,.34);color:var(--ink)}
:where(h1,h2,h3,p,figure,ul,ol){margin:0}
:where(h1,h2,h3){font-weight:inherit;text-wrap:balance}
:where(ul,ol){padding:0;list-style:none}
:where(button,input,select,textarea){font:inherit;color:inherit}
:where(button,a,label,summary){touch-action:manipulation}
:where(a){color:inherit}
img{max-width:100%}

/* one focus ring everywhere: gold, offset, following the corner radius */
:focus-visible{outline:2px solid var(--gold-hi);outline-offset:3px;border-radius:4px}
:where(.btn,.slides,.dot,a.card):focus-visible{border-radius:inherit}
:focus:not(:focus-visible){outline:none}

.skip{
  position:absolute;left:50%;top:8px;z-index:60;transform:translate(-50%,-160%);
  display:inline-flex;align-items:center;min-height:44px;padding:0 22px;border-radius:999px;
  background:var(--brass);color:var(--on-gold);font:800 14px/1 var(--sans);
  text-decoration:none;transition:transform .18s var(--ease)}
.skip:focus{transform:translate(-50%,0)}

.sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}


/* ---------- 3. type + layout -------------------------------------------- */
.h2,.hero-title{font-family:var(--serif);font-weight:600;color:var(--ink);letter-spacing:-.012em}
.h2{font-size:var(--fs-h2);line-height:1.04}
:is(.h2,.hero-title) em{font-style:italic;font-weight:600;color:var(--gold)}

.eyebrow{
  display:block;margin-bottom:clamp(10px,1.4vw,18px);
  font:700 var(--fs-eyebrow)/1.2 var(--sans);letter-spacing:.24em;
  text-transform:uppercase;color:var(--gold)}
.lede{font:500 var(--fs-lede)/1.5 var(--sans);color:var(--ink-2);text-wrap:pretty}
.small{font:500 var(--fs-small)/1.45 var(--sans);color:var(--ink-3)}
.tnum{font-variant-numeric:tabular-nums}

.wrap{width:100%;max-width:var(--max);margin-inline:auto;
  padding-inline:max(var(--gutter),env(safe-area-inset-left),env(safe-area-inset-right))}
.wrap--narrow{--max:780px}

.band{position:relative;padding-block:var(--band)}
.band-head{margin-bottom:clamp(28px,4.2vw,58px);max-width:46ch}
.band-head .lede{margin-top:clamp(12px,1.6vw,20px)}
.band-head--row{display:flex;align-items:flex-end;justify-content:space-between;
  gap:var(--gap);max-width:none;flex-wrap:wrap}

/* a hairline that fades out at both ends, the way the TV's footer rules do */
.rule{height:1px;border:0;background:linear-gradient(90deg,transparent,var(--hair-2) 18%,var(--hair-2) 82%,transparent)}


/* ---------- 4. glass, tiles, buttons ------------------------------------- */
.panel{
  position:relative;
  padding:clamp(22px,calc(12px + 2.2vw),44px);border-radius:var(--r-panel);
  background:
    radial-gradient(36% 36% at 18% 98%, rgba(247,169,69,.09), transparent),
    linear-gradient(180deg,rgba(255,244,228,.06),rgba(255,244,228,.018));
  border:1px solid var(--hair);box-shadow:var(--shadow);
  -webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}

.tile{position:relative;border-radius:var(--r-tile);
  background:linear-gradient(180deg,rgba(255,244,228,.05),rgba(255,244,228,.014));
  border:1px solid var(--hair-row)}

/* the hole-in-one: exactly one gold-lit thing per screen */
.lead{
  position:relative;overflow:hidden;isolation:isolate;
  border:1px solid rgba(247,169,69,.5);
  background:
    radial-gradient(90% 80% at 0% 0%,rgba(255,199,102,.22),transparent 62%),
    linear-gradient(155deg,rgba(247,169,69,.25),rgba(247,169,69,.06) 58%,rgba(247,169,69,.11));
  box-shadow:0 26px 56px -24px rgba(247,169,69,.34),0 18px 48px rgba(0,0,0,.45),
             inset 0 1px 0 rgba(255,220,160,.22)}
.lead::after{
  content:"";position:absolute;inset:0;z-index:1;pointer-events:none;border-radius:inherit;
  background:linear-gradient(112deg,transparent 40%,rgba(255,232,190,.12) 50%,transparent 60%);
  transform:translateX(-110%);animation:sheen 8s ease-in-out infinite}
@keyframes sheen{0%,72%{transform:translateX(-110%)}100%{transform:translateX(110%)}}

.btn{
  --bh:var(--tap);
  position:relative;display:inline-flex;align-items:center;justify-content:center;gap:10px;
  min-height:var(--bh);min-width:var(--bh);padding:0 clamp(20px,2.2vw,32px);
  border-radius:999px;border:1px solid var(--hair-2);
  background:linear-gradient(180deg,rgba(255,244,228,.085),rgba(255,244,228,.03));
  color:var(--ink);font:700 clamp(15px,calc(13.4px + .42vw),18px)/1.15 var(--sans);
  letter-spacing:.01em;text-align:center;text-decoration:none;white-space:nowrap;
  cursor:pointer;user-select:none;-webkit-appearance:none;appearance:none;
  box-shadow:inset 0 1px 0 rgba(255,244,228,.09),0 6px 18px rgba(0,0,0,.26);
  transition:background-color .18s,border-color .18s,box-shadow .18s,color .18s,filter .18s,transform .1s}
.btn svg{flex:none;width:1.2em;height:1.2em}
@media (hover:hover){
  .btn:hover{border-color:rgba(255,236,210,.26);background-color:rgba(255,244,228,.05)}
}
.btn:active{transform:translateY(1px);background-color:rgba(0,0,0,.14);
  box-shadow:inset 0 2px 7px rgba(0,0,0,.4)}

/* the brass key */
.btn--primary{
  color:var(--on-gold);font-weight:800;border-color:rgba(255,214,140,.55);
  background:var(--brass);text-shadow:0 1px 0 rgba(255,232,180,.35);
  box-shadow:inset 0 1px 0 rgba(255,246,222,.7),inset 0 -2px 0 rgba(140,80,10,.28),
             0 12px 30px -10px rgba(247,169,69,.6),0 2px 6px rgba(0,0,0,.35)}
@media (hover:hover){
  .btn--primary:hover{filter:brightness(1.06) saturate(1.05);border-color:rgba(255,224,160,.7);
    background:var(--brass)}
}
.btn--primary:active{transform:translateY(2px);filter:brightness(.95);background:var(--brass);
  box-shadow:inset 0 3px 8px rgba(110,60,0,.4),0 4px 12px -6px rgba(247,169,69,.45)}

.btn--lg{--bh:clamp(56px,calc(40px + 2.6vw),68px);
  padding:0 clamp(26px,3vw,44px);font-size:clamp(16px,calc(13.6px + .62vw),20px)}
.btn--icon{width:var(--bh);padding:0;border-radius:50%}
.btn--icon svg{width:22px;height:22px}

.link{color:var(--gold);font-weight:700;text-decoration:underline;
  text-decoration-color:rgba(247,169,69,.4);text-underline-offset:.22em;
  transition:color .18s,text-decoration-color .18s}
@media (hover:hover){.link:hover{color:var(--gold-hi);text-decoration-color:var(--gold)}}

/* pills: outlined, tiny, uppercase; gold is good news */
.pill{
  display:inline-flex;align-items:center;gap:9px;
  min-height:clamp(30px,calc(26px + .6vw),36px);padding:0 clamp(13px,1.3vw,18px);
  border-radius:999px;border:1px solid var(--hair-2);background:rgba(11,9,8,.5);
  font:700 var(--fs-eyebrow)/1 var(--sans);letter-spacing:.18em;text-transform:uppercase;
  color:var(--ink-3);white-space:nowrap;
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}
.pill > i{flex:none;width:7px;height:7px;border-radius:50%;background:currentColor}
.pill.is-open{color:var(--gold);border-color:var(--gold-line);background:rgba(247,169,69,.1)}
.pill.is-open > i{background:var(--gold);box-shadow:0 0 10px rgba(247,169,69,.7);
  animation:breathe 2.6s ease-in-out infinite}
.pill.is-closed{color:var(--ink-3)}
@keyframes breathe{50%{opacity:.35;transform:scale(.72)}}


/* ---------- 5. photographs, and honest stand-ins for them ---------------- */
/* Every picture on this site keeps its shape whether or not the photograph
   exists yet: the frame sets aspect-ratio, so nothing jumps when a real file
   drops in. A missing photo is NOT an empty box — it's a lit panel with the
   logo pressed into it and a caption saying what will hang there. */
.frame{position:relative;display:block;overflow:hidden;border-radius:var(--r-tile);
  background:#0E0B09;border:1px solid var(--hair)}
.frame--wide{aspect-ratio:4/3}
.frame--tall{aspect-ratio:4/5}
.frame--hero{aspect-ratio:3/2}
/* A real photograph brings its own shape: --ar is its pixels, straight out of
   content.js, so a 4:3 room and a 3:4 row of chairs are each printed as they
   were taken instead of being cropped to one house shape. */
.frame--free{aspect-ratio:var(--ar,4/3)}
.frame > img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}

.ph{
  position:absolute;inset:0;display:grid;place-items:center;overflow:hidden;
  background:
    radial-gradient(120% 90% at 22% 8%, rgba(247,169,69,.13), transparent 58%),
    radial-gradient(90% 80% at 96% 100%, rgba(83,116,170,.10), transparent 62%),
    linear-gradient(162deg,#17120D 0%,#0C0A08 58%,#100C09 100%)}
/* the logo pressed into the panel */
.ph::before{
  content:"";position:absolute;inset:0;
  background:url("img/brand/dream-logo-light.webp") no-repeat 50% 44%/auto 52%;
  opacity:.045;filter:grayscale(1)}
/* a fine warm weave, so the panel has a surface instead of being flat black */
.ph::after{
  content:"";position:absolute;inset:0;opacity:.5;
  background:repeating-linear-gradient(118deg,rgba(255,236,210,.022) 0 1px,transparent 1px 7px)}
/* Six identical tiles in a row would read as a broken page, so the light falls
   differently in each one — they look like a set of photographs, not one tile
   repeated. Delete nothing here when the real photos arrive; these rules only
   ever touch the stand-ins. */
.slide:nth-child(3n+2) .ph,.shop-photos figure:nth-child(2) .ph{
  background:
    radial-gradient(110% 95% at 88% 12%, rgba(247,169,69,.11), transparent 58%),
    radial-gradient(90% 80% at 4% 96%, rgba(83,116,170,.12), transparent 62%),
    linear-gradient(196deg,#150F0B 0%,#0B0908 62%,#120D09 100%)}
.slide:nth-child(3n+3) .ph,.shop-photos figure:nth-child(3) .ph{
  background:
    radial-gradient(120% 100% at 50% 108%, rgba(247,169,69,.1), transparent 56%),
    radial-gradient(80% 70% at 10% 0%, rgba(217,64,44,.07), transparent 60%),
    linear-gradient(142deg,#120E0A 0%,#0C0A08 54%,#16100B 100%)}
.slide:nth-child(3n+2) .ph::before{background-position:50% 40%;background-size:auto 46%;opacity:.038}
.slide:nth-child(3n+3) .ph::before{background-position:50% 48%;background-size:auto 58%;opacity:.05}
.slide:nth-child(even) .ph::after{background:repeating-linear-gradient(62deg,rgba(255,236,210,.02) 0 1px,transparent 1px 8px)}
.ph-label{
  position:relative;z-index:1;align-self:end;justify-self:start;
  margin:0 0 clamp(12px,1.6vw,20px) clamp(12px,1.6vw,20px);
  padding:7px 13px;border-radius:999px;
  border:1px solid var(--hair);background:rgba(11,9,8,.52);
  font:700 clamp(9.5px,calc(9px + .18vw),11.5px)/1 var(--sans);letter-spacing:.2em;
  text-transform:uppercase;color:var(--ink-3);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}

.caption{margin-top:10px;font:500 var(--fs-small)/1.4 var(--sans);color:var(--ink-3)}


/* ---------- 6. the hero -------------------------------------------------- */
.hero{
  position:relative;isolation:isolate;overflow:hidden;
  min-height:100svh;display:grid;grid-template-rows:1fr auto;
  padding:calc(clamp(28px,6vh,64px) + env(safe-area-inset-top))
          max(var(--gutter),env(safe-area-inset-right))
          clamp(16px,3vh,28px)
          max(var(--gutter),env(safe-area-inset-left))}
.hero-art{position:absolute;inset:0;z-index:-2;border-radius:0;border:0;background:#0E0B09}
.hero-art .ph{border-radius:0;
  background:
    radial-gradient(90% 70% at 18% 4%, rgba(247,169,69,.14), transparent 60%),
    radial-gradient(70% 66% at 96% 100%, rgba(83,116,170,.12), transparent 62%),
    radial-gradient(50% 44% at 86% 2%, rgba(217,64,44,.08), transparent 60%),
    linear-gradient(168deg,#17120D 0%,#0B0908 62%,#100C09 100%)}
/* The real logo is right there at full strength on the hero, so the stand-in
   panel behind it does not get a ghost of the same art — it would read as a
   double exposure behind the headline. */
.hero-art .ph::before{display:none}
.hero-art .ph-label{display:none}
/* THE PHOTOGRAPH IS ONLY SO BIG. The owner's pictures came through a messaging
   app — shop-1 is 1269 px across — and a full-bleed hero on a 1920 screen would
   blow it up half again, which reads as blur. So the photograph is never
   stretched past --hero-cap (site.js sets that from the file's own pixels, a
   shade over its native width); past that the dark ground carries the edges and
   the frame goes cinematic instead of soft. Drop in a bigger original one day
   and the cap rises with it, on its own. The 4% fade hides the seam. */
.hero-art > img,.hero-art > video{
  position:absolute;top:0;bottom:0;left:50%;transform:translateX(-50%);
  width:min(100%,var(--hero-cap,100%));height:100%;object-fit:cover;display:block}
/* The seam where a capped photograph meets the ground, feathered. It is
   PAINTED over the picture rather than masked out of it, which keeps the
   photograph a plain image layer — and covers the video in the same breath,
   since both sit in this same box. */
.hero-art::after{
  content:"";position:absolute;top:0;bottom:0;left:50%;transform:translateX(-50%);
  width:min(100%,var(--hero-cap,100%));pointer-events:none;
  background:linear-gradient(90deg,var(--ground),rgba(11,9,8,0) 5%,rgba(11,9,8,0) 95%,var(--ground))}
/* The shop moving, behind the headline. Exactly the same box as the
   photograph, on top of it, so there is nothing to shift when it starts and
   nothing to see if it never does — and it fades up rather than cutting in.
   site.js leaves it out altogether on a screen the clip doesn't suit, when the
   visitor has asked for less motion, or when the phone is saving data. */
/* box, crop and edge-fade come from the .hero-art > img,video rule above, so
   the video sits in exactly the photograph's frame */
.hero-video{opacity:0;transition:opacity .9s var(--ease);pointer-events:none}
.hero-video.is-on{opacity:1}
/* A darker veil while the video is up: moving footage has bright frames the
   photograph doesn't, and the headline has to stay readable over all of them. */
.hero:has(.hero-video.is-on) .hero-veil{
  background:
    radial-gradient(80% 54% at 50% 54%,rgba(11,9,8,.62),rgba(11,9,8,.2) 72%,transparent 88%),
    linear-gradient(180deg,rgba(11,9,8,.82) 0%,rgba(11,9,8,.52) 30%,rgba(11,9,8,.58) 62%,rgba(11,9,8,.88) 88%,var(--ground) 100%)}
/* The photograph is never allowed to fight the type. The real photograph of
   the shop is a BRIGHT one — a dozen white capes and a lit ceiling — so the
   veil carries a soft pool of dark under the headline as well as the top-to-
   bottom wash: ivory type over a white cape at .36 was down to about 2.3:1,
   and over this it holds about 7:1 at the worst pixel in the frame. The foot
   of it walks out into the ground colour so the hero ends rather than stops. */
.hero-veil{position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:
    radial-gradient(80% 54% at 50% 54%,rgba(11,9,8,.52),rgba(11,9,8,.14) 72%,transparent 88%),
    linear-gradient(180deg,rgba(11,9,8,.78) 0%,rgba(11,9,8,.44) 30%,rgba(11,9,8,.5) 62%,rgba(11,9,8,.86) 88%,var(--ground) 100%)}

.hero-inner{
  position:relative;align-self:center;justify-self:center;width:100%;max-width:min(100%,880px);
  display:flex;flex-direction:column;align-items:center;text-align:center;
  gap:clamp(14px,2vh,22px);padding-block:clamp(12px,3vh,40px)}
.hero-logo{
  width:auto;height:clamp(104px,calc(52px + 15vw),208px);
  filter:drop-shadow(0 10px 28px rgba(0,0,0,.65))}
.hero-pill{margin-top:clamp(2px,1vh,10px)}

.hero-title{
  font-size:var(--fs-hero);line-height:.96;letter-spacing:-.022em;
  text-wrap:balance;text-shadow:0 6px 28px rgba(0,0,0,.6)}
.hero-line{
  max-width:30ch;font:500 var(--fs-lede)/1.5 var(--sans);color:var(--ink-2);
  text-wrap:pretty;text-shadow:0 2px 14px rgba(0,0,0,.6)}

.hero-actions{display:flex;flex-wrap:wrap;justify-content:center;gap:clamp(12px,1.6vw,18px);
  width:100%;margin-top:clamp(4px,1.2vh,12px)}
.hero-actions .btn{flex:1 1 190px;max-width:290px}

.hero-where{font:500 var(--fs-small)/1.5 var(--sans);color:var(--ink-3);text-wrap:balance}
.hero-where b{font-weight:700;color:var(--ink-2)}

.hero-scroll{
  position:relative;justify-self:center;align-self:end;display:inline-flex;align-items:center;gap:10px;
  min-height:44px;padding:0 14px;text-decoration:none;
  font:700 var(--fs-eyebrow)/1 var(--sans);letter-spacing:.24em;text-transform:uppercase;
  color:var(--ink-3);transition:color .2s}
.hero-scroll svg{width:16px;height:16px;animation:nudge 3.4s ease-in-out infinite}
@media (hover:hover){.hero-scroll:hover{color:var(--gold)}}
@keyframes nudge{0%,62%,100%{transform:translateY(0)}78%{transform:translateY(4px)}}

/* A phone held in landscape has no height to give: drop the full-height hero
   so the headline and the two buttons are all still on one screen. */
@media (max-height:520px){
  .hero{min-height:auto;padding-block:clamp(24px,7vh,44px)}
  .hero-logo{height:clamp(72px,14vh,110px)}
  .hero-scroll{display:none}
}


/* ---------- 7. the three facts ------------------------------------------- */
.facts{position:relative;padding-block:clamp(30px,4.6vw,58px);
  border-top:1px solid var(--hair);border-bottom:1px solid var(--hair);
  background:linear-gradient(180deg,rgba(255,244,228,.03),transparent 70%)}
.facts-list{
  width:100%;max-width:var(--max);margin-inline:auto;
  padding-inline:max(var(--gutter),env(safe-area-inset-left));
  display:grid;gap:clamp(22px,3vw,40px)}
.facts-list > li{position:relative}
.facts-list .eyebrow{margin-bottom:8px}
.facts-list p{font:500 var(--fs-body)/1.55 var(--sans);color:var(--ink-2);text-wrap:pretty}
@media (min-width:760px){
  .facts-list{grid-template-columns:repeat(3,1fr);gap:clamp(26px,3.4vw,52px)}
  /* a gold hairline between the facts, fading top and bottom */
  .facts-list > li + li::before{
    content:"";position:absolute;left:calc(clamp(26px,3.4vw,52px) / -2);top:-2px;bottom:-2px;width:1px;
    background:linear-gradient(180deg,transparent,rgba(247,169,69,.34),transparent)}
}
@media (max-width:759px){
  .facts-list > li + li{padding-top:clamp(20px,3vw,28px);border-top:1px solid var(--hair-row)}
}


/* ---------- 8. the shop -------------------------------------------------- */
.shop-grid{display:grid;gap:clamp(30px,4.6vw,66px);align-items:start}
@media (min-width:900px){
  .shop-grid{grid-template-columns:minmax(0,1.02fr) minmax(0,1fr);
    gap:clamp(40px,5vw,84px);align-items:center}
}
.shop-words .prose{margin-top:clamp(14px,2vw,24px);display:grid;gap:1em}
.shop-words .prose p{font:500 var(--fs-lede)/1.55 var(--sans);color:var(--ink-2);text-wrap:pretty}
.shop-words .prose p:first-child{color:var(--ink)}

.ticks{margin-top:clamp(20px,2.6vw,32px);display:grid;gap:11px}
.ticks li{position:relative;padding-left:30px;font:600 var(--fs-body)/1.45 var(--sans);color:var(--ink-2)}
.ticks li::before{
  content:"";position:absolute;left:2px;top:.44em;width:13px;height:7px;
  border-left:2px solid var(--gold);border-bottom:2px solid var(--gold);
  transform:rotate(-45deg);border-radius:1px}

.shop-photos{display:grid;grid-template-columns:1fr 1fr;gap:clamp(10px,1.4vw,18px)}
.shop-photos > figure:first-child{grid-column:1 / -1}
.shop-photos figure{margin:0;min-width:0}
/* On a phone a pair of tall photographs side by side comes out about 170px
   wide, which is too small to see a room in. One to a row instead: the page is
   a scroll, and this is the section where a man actually wants to look. */
@media (max-width:560px){
  .shop-photos{grid-template-columns:1fr}
  .shop-photos > figure:first-child{grid-column:auto}
}


/* ---------- 9. the barbers ----------------------------------------------- */
.barber-grid{display:grid;gap:clamp(14px,1.8vw,26px);grid-template-columns:repeat(2,minmax(0,1fr))}
@media (min-width:560px){.barber-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (min-width:1000px){.barber-grid{grid-template-columns:repeat(6,minmax(0,1fr))}}
/* A full floor — a dozen or fifteen men — is a lot of colour to meet at once.
   The rings come down a size, the cards tighten, and a phone takes three
   across instead of two, so fifteen reads as a team and not a paint chart.
   site.js adds .is-many past eight; six or eight keep the bigger badge.

   BUT NOT ON A NARROW PHONE. Three cards across 390px leave a name about 94px
   of card, which is under a long one's own width at any size worth reading —
   and a name that doesn't fit is a name that breaks. So below 430px a floor of
   fifteen lays out exactly like a floor of six: two across, full-size rings,
   full-size names. The section is longer and every man is legible, which is
   the right way round. */
@media (min-width:430px){
  .barber-grid.is-many{gap:clamp(10px,1.3vw,20px);grid-template-columns:repeat(3,minmax(0,1fr))}
  .barber-grid.is-many .badge{--bs:clamp(46px,calc(20px + 6.2vw),76px)}
  .barber-grid.is-many .barber{padding:clamp(13px,1.5vw,20px) clamp(8px,1vw,14px) clamp(11px,1.3vw,16px)}
  .barber-grid.is-many .barber-name{--name-max:clamp(17px,calc(13.4px + .95vw),24px)}
}
@media (min-width:1000px){.barber-grid.is-many{grid-template-columns:repeat(6,minmax(0,1fr))}}

.barber{
  position:relative;min-width:0;padding:clamp(16px,1.8vw,24px) clamp(12px,1.4vw,18px) clamp(14px,1.6vw,20px);
  border-radius:var(--r-tile);text-align:center;
  background:linear-gradient(180deg,rgba(255,244,228,.05),rgba(255,244,228,.014));
  border:1px solid var(--hair-row);
  /* the card measures itself for the name below: 100cqi is its own inside
     width, whatever the screen is doing */
  container-type:inline-size}
.barber .frame{margin-bottom:clamp(12px,1.4vw,16px)}

/* A MAN'S NAME NEVER BREAKS IN THE MIDDLE OF ITSELF.
   Six cards across a laptop leave a name about 110px of card to live in, and
   "Sebastian" at the full heading size wants a shade more than that — which
   used to come out as "Sebastia / n", and reads as a fault rather than a
   design. So the size is worked out from the card instead of guessed:

     100cqi          the card's own inner width
     --name-w        how many ems wide the longest name on this floor is, in
                     this very typeface — site.js measures it in the real
                     Playfair rather than counting letters, because an "i" and
                     a "w" are not the same width
     --name-max      the size it has today, which it is never allowed to exceed

   so every name is set at the biggest size that keeps it whole, every card on
   the floor gets the SAME size (a roster reads as a set), and a shop of short
   names looks exactly as it does now. 14px is the last stop, and the two rules
   after it are only ever reached by a name longer than any of these cards can
   hold at a readable size — hyphens:auto divides it at a syllable with a
   hyphen where the browser has the dictionary for it, and break-word behind
   that is the guarantee that nothing can spill out of a card and give the page
   a sideways scroll.                                                         */
.barber-name{
  --name-max:var(--fs-h3);
  font:600 var(--name-max)/1.15 var(--serif);color:var(--ink);
  font-size:clamp(14px,calc(100cqi / var(--name-w,4.4)),var(--name-max));
  text-wrap:balance;hyphens:auto;overflow-wrap:break-word}
.barber-shop{margin-top:5px;font:700 var(--fs-eyebrow)/1.2 var(--sans);letter-spacing:.2em;
  text-transform:uppercase;color:var(--ink-3)}

/* A ring in his colour around a dark disc with his letters in ivory — the same
   badge the lobby screen and the owner's report use, so a barber is recognisable
   from the website to the wall. Never a solid block of his colour. */
.badge{
  --bs:clamp(64px,calc(30px + 8.4vw),104px);
  position:relative;display:inline-grid;place-items:center;margin-bottom:clamp(12px,1.4vw,16px);
  width:var(--bs);height:var(--bs);border-radius:50%;
  background:var(--cr,var(--c,#8E8275));
  /* a ring that glows a little, never a neon one: six of these sit in a row */
  box-shadow:0 0 calc(var(--bs) * .2) color-mix(in oklab,var(--c,#8E8275) 20%,transparent)}
.badge::before{content:"";position:absolute;inset:max(3px,calc(var(--bs) * .07));border-radius:50%;
  background:radial-gradient(circle at 34% 28%,#2B241D,#110E0B 72%)}
.badge > span{position:relative;font:700 calc(var(--bs) * .33)/1 var(--sans);
  letter-spacing:.01em;color:var(--ink)}


/* ---------- 10. the price board ------------------------------------------ */
/* It should read like the board on the wall: the service, a hairline running
   across, the price in figures that line up. */
.board-panel{padding-block:clamp(18px,2.4vw,34px)}
.board-list{display:grid}
/* His board keeps the men's and the kids' cuts together, then the beard work,
   then the small stuff. Each group gets a quiet label and its own hairline, so
   eleven services can be read down a phone without becoming a wall. */
.board-group + .board-group{margin-top:clamp(18px,2.4vw,32px);
  padding-top:clamp(16px,2vw,26px);border-top:1px solid var(--hair)}
.board-group-name{
  margin-bottom:clamp(2px,.6vw,6px);
  font:700 var(--fs-eyebrow)/1.2 var(--sans);letter-spacing:.24em;
  text-transform:uppercase;color:var(--ink-3)}
.board-rows{display:grid}
.board-rows > li{
  display:flex;align-items:baseline;gap:clamp(10px,1.4vw,18px);
  padding-block:clamp(13px,1.5vw,20px)}
.board-rows > li + li{border-top:1px solid var(--hair-row)}
.board-name{font:600 var(--fs-price)/1.25 var(--serif);color:var(--ink);min-width:0}
.board-detail{display:block;margin-top:3px;font:500 var(--fs-small)/1.35 var(--sans);color:var(--ink-3)}
.board-leader{
  flex:1 1 auto;min-width:18px;height:1px;transform:translateY(-.34em);
  background:linear-gradient(90deg,rgba(247,169,69,.34),rgba(247,169,69,.1) 62%,transparent)}
.board-price{
  flex:none;display:inline-grid;justify-items:end;text-align:right;
  font:600 var(--fs-price)/1.25 var(--serif);color:var(--gold);
  font-variant-numeric:tabular-nums;letter-spacing:.01em}
.board-price.is-blank{color:var(--ink-3)}
/* "and up" belongs to the price, but under it — beside it, it would push the
   figure out of the column the other prices line up in. */
.board-from{
  font:500 var(--fs-small)/1.15 var(--sans);color:var(--ink-3);
  font-variant-numeric:normal;letter-spacing:.04em;white-space:nowrap}
.board-note{margin-top:clamp(16px,2vw,24px);padding-top:clamp(14px,1.8vw,20px);
  border-top:1px solid var(--hair);
  font:500 var(--fs-small)/1.5 var(--sans);color:var(--ink-3);text-wrap:pretty}


/* ---------- 11. the gallery slideshow ------------------------------------ */
.slide-nav{display:flex;gap:10px;flex:none}
.slides{
  position:relative;
  /* One height for every photograph, and each one takes the width its own
     shape asks for — a filmstrip, the way photographs of different
     orientations actually get shown. --slide-h is set so a LANDSCAPE frame
     still fits between the gutters on a phone; --ar per slide comes from the
     photo's own pixels in content.js. */
  --slide-h:clamp(250px,78vw,330px);
  /* the track bleeds to the edge of the screen on a phone, which is what makes
     a swipe feel native instead of boxed in */
  margin-inline:calc(max(var(--gutter),env(safe-area-inset-left)) * -1);
  padding-inline:max(var(--gutter),env(safe-area-inset-left));
  overflow-x:auto;overflow-y:hidden;
  /* PROXIMITY, not mandatory. In a strip where several photographs are on
     screen at once, the last two can never bring their left edge to the start
     of the strip — there is no scroll left to give — so a mandatory snap has
     nowhere legal to rest at the end and jumps back to a photo you didn't ask
     for. Proximity snaps a swipe that lands near a photo and leaves the end of
     the strip alone. */
  scroll-snap-type:x proximity;scroll-behavior:smooth;
  /* The strip bleeds out to the edge of the screen, but a photo SNAPS to the
     text column above it, not to the bleed — without this the first tile is
     pulled a gutter's width left of its own heading. */
  scroll-padding-inline:max(var(--gutter),env(safe-area-inset-left));
  -webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;
  scrollbar-width:none}
.slides::-webkit-scrollbar{display:none}
.slide-track{display:flex;gap:clamp(12px,1.6vw,22px);width:max-content;padding-block:2px}
.slide{
  flex:none;margin:0;scroll-snap-align:start;
  width:calc(var(--slide-h) * var(--ar,4/5));
  /* never wider than the screen: a landscape photograph on a narrow phone
     takes a small honest crop off its sides rather than running off the edge */
  max-width:calc(100vw - 2 * max(var(--gutter),env(safe-area-inset-left)))}
.slide .frame{height:var(--slide-h);aspect-ratio:auto;
  transition:border-color .3s,transform .5s var(--ease)}
@media (min-width:760px){
  .slides{--slide-h:clamp(330px,33vw,470px)}
}
/* the slide in the middle of the frame is the one being looked at */
.slide.is-current .frame{border-color:rgba(247,169,69,.42);
  box-shadow:0 22px 50px -26px rgba(247,169,69,.4),0 14px 36px rgba(0,0,0,.45)}

.slide-dots{display:flex;justify-content:center;gap:2px;margin-top:clamp(12px,1.8vw,22px);flex-wrap:wrap}
/* the dot is 7px; the button around it is a 44px thumb-sized target */
.dot{
  width:44px;height:44px;padding:0;border:0;background:none;cursor:pointer;
  display:grid;place-items:center;border-radius:50%}
.dot::before{content:"";width:7px;height:7px;border-radius:50%;
  background:rgba(242,232,214,.26);transition:background-color .25s,transform .25s,box-shadow .25s}
@media (hover:hover){.dot:hover::before{background:rgba(242,232,214,.5)}}
.dot[aria-current="true"]::before{background:var(--gold);transform:scale(1.5);
  box-shadow:0 0 10px rgba(247,169,69,.65)}


/* ---------- 12. reviews -------------------------------------------------- */
.reviews-grid{display:grid;gap:clamp(20px,2.6vw,36px);align-items:start}
@media (min-width:880px){
  .reviews-grid{grid-template-columns:minmax(0,320px) minmax(0,1fr);
    gap:clamp(28px,3.4vw,52px)}
}
/* With no individual reviews the quiet panel squares up to the rating card;
   with reviews in it, the cards keep their own heights. */
.reviews-grid:has(.reviews-calm){align-items:stretch}
/* the rating is the one gold-lit thing in this section */
.rating-card{
  border-radius:var(--r-panel);padding:clamp(24px,3vw,40px);text-align:center;
  display:grid;justify-items:center;gap:clamp(10px,1.2vw,14px)}
.rating-num{font:600 var(--fs-rating)/.9 var(--serif);color:var(--ink);
  font-variant-numeric:tabular-nums;letter-spacing:-.02em;
  text-shadow:0 8px 30px rgba(0,0,0,.4)}
.rating-num small{font-size:.34em;font-weight:600;color:var(--ink-2);letter-spacing:0}
.stars{display:flex;gap:5px}
.stars svg{width:clamp(20px,2.4vw,28px);height:clamp(20px,2.4vw,28px);flex:none}
.stars .on{fill:var(--gold)}
.stars .off{fill:rgba(242,232,214,.2)}
.rating-count{font:600 var(--fs-body)/1.4 var(--sans);color:var(--ink-2)}
.rating-card .btn{margin-top:6px;position:relative;z-index:2}
.rating-src{font:600 var(--fs-eyebrow)/1.3 var(--sans);letter-spacing:.14em;
  text-transform:uppercase;color:rgba(242,232,214,.62)}

/* no individual reviews to print yet: a calm line, the way the TV says a quiet
   shop — italic Playfair and one quiet sentence, never an empty box */
.reviews-calm{
  display:grid;align-content:center;justify-items:center;text-align:center;
  gap:clamp(12px,1.4vw,18px);
  min-height:clamp(180px,24vw,300px);padding:clamp(28px,3.4vw,52px);
  border-radius:var(--r-panel);border:1px solid var(--hair);
  background:
    radial-gradient(60% 70% at 50% 0%, rgba(247,169,69,.05), transparent 70%),
    linear-gradient(180deg,rgba(255,244,228,.04),rgba(255,244,228,.012))}
.reviews-calm .big{font:italic 600 clamp(25px,calc(16px + 2.3vw),44px)/1.15 var(--serif);
  color:var(--ink);max-width:24ch;text-wrap:balance}
.reviews-calm .sm{font:500 var(--fs-lede)/1.5 var(--sans);color:var(--ink-3);max-width:34ch}
/* the gold hairline that separates a heading from its quiet line, as on the TV */
.reviews-calm .rule{width:clamp(90px,14vw,170px);
  background:linear-gradient(90deg,transparent,rgba(247,169,69,.6) 50%,transparent)}

/* the live feed, once Google is wired up */
.quote-grid{display:grid;gap:clamp(14px,1.8vw,22px)}
@media (min-width:620px){.quote-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
.quote{padding:clamp(18px,2.2vw,28px);border-radius:var(--r-tile);display:grid;gap:12px;align-content:start}
.quote-head{display:flex;align-items:center;gap:12px;min-width:0}
.quote-avatar{flex:none;width:38px;height:38px;border-radius:50%;object-fit:cover;
  background:rgba(255,244,228,.06);border:1px solid var(--hair)}
.quote-who{min-width:0}
/* The review's own words. Given its own class rather than styling ".quote p",
   which would also catch the name and the date — and `text-wrap: pretty` there
   quietly switched their `white-space: nowrap` back on, so a long name wrapped
   under its own stars. */
.quote-text{font:500 var(--fs-body)/1.6 var(--sans);color:var(--ink-2);text-wrap:pretty}
.quote-name{font:600 var(--fs-body)/1.25 var(--serif);color:var(--ink);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.quote-when{font:500 var(--fs-small)/1.3 var(--sans);color:var(--ink-3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.quote-stars{margin-left:auto;flex:none}
.quote-stars svg{width:14px;height:14px}


/* ---------- 13. where we are --------------------------------------------- */
/* One card per open shop, in a grid that takes a second card the day Palmetto
   opens without a line of layout changing. */
.where-grid{display:grid;gap:clamp(18px,2.4vw,32px)}
.where-cards{display:grid;gap:clamp(18px,2.4vw,32px)}
@media (min-width:820px){
  .where-cards{grid-template-columns:repeat(auto-fit,minmax(min(100%,330px),1fr))}
}
/* The card asks its OWN width, not the window's: one shop on a desktop gets
   the address and the hours side by side, and the day Palmetto opens the two
   narrower cards each fall back to a single column on their own. */
.where-card{container-type:inline-size;display:grid;gap:clamp(16px,2vw,24px);align-content:start}
.where-body{display:grid;gap:clamp(18px,2.2vw,26px);align-items:start}
.where-main{display:grid;gap:clamp(16px,2vw,24px);align-content:start;min-width:0}
@container (min-width:620px){
  .where-body{grid-template-columns:minmax(0,1fr) minmax(0,300px);
    column-gap:clamp(28px,4cqw,56px)}
  .where-body .hours{border-top:0;padding-top:0;
    border-left:1px solid var(--hair);padding-left:clamp(20px,3cqw,36px)}
}
.where-name{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.where-name h3{font:600 var(--fs-h3)/1.1 var(--serif);color:var(--ink)}
.where-addr{font:500 var(--fs-lede)/1.5 var(--sans);color:var(--ink-2);font-style:normal}
.where-addr a{color:var(--ink);font-weight:700;text-decoration:none;
  border-bottom:1px solid rgba(247,169,69,.4);padding-bottom:1px}
@media (hover:hover){.where-addr a:hover{color:var(--gold-hi);border-bottom-color:var(--gold)}}
.where-actions{display:flex;flex-wrap:wrap;gap:12px}
.where-actions .btn{flex:1 1 150px}

.hours{display:grid;gap:2px;border-top:1px solid var(--hair);padding-top:clamp(14px,1.8vw,20px)}
.hours > div{display:flex;align-items:baseline;justify-content:space-between;gap:16px;
  padding-block:5px;font:500 var(--fs-body)/1.4 var(--sans);color:var(--ink-2)}
.hours dt{color:var(--ink-3)}
.hours dd{margin:0;font-variant-numeric:tabular-nums;white-space:nowrap}
.hours .is-today{color:var(--ink)}
.hours .is-today dt{color:var(--gold);font-weight:700}
.hours .is-today dd{font-weight:700}
.hours .is-shut dd{color:var(--ink-3)}

/* Palmetto, while it's still being built: a quiet line, not a card. When
   comingSoon turns false it becomes a full card in the grid above instead. */
/* A solid hairline with a gold rule down its leading edge, not a dashed box:
   this is a shop on the way, not an unfinished part of the page. */
.soon{
  position:relative;overflow:hidden;
  display:flex;align-items:center;gap:clamp(14px,2vw,24px);flex-wrap:wrap;
  padding:clamp(18px,2.2vw,28px) clamp(18px,2.4vw,32px);border-radius:var(--r-tile);
  border:1px solid var(--hair);background:
    linear-gradient(90deg,rgba(247,169,69,.05),transparent 42%),
    linear-gradient(180deg,rgba(255,244,228,.03),rgba(255,244,228,.008))}
.soon::before{content:"";position:absolute;left:0;top:0;bottom:0;width:2px;
  background:linear-gradient(180deg,transparent,var(--gold) 28%,var(--gold-lo) 72%,transparent)}
.soon-mark{
  flex:none;display:inline-flex;align-items:center;justify-content:center;
  min-height:30px;padding:0 14px;border-radius:999px;
  border:1px solid var(--gold-line);background:var(--gold-tint);
  font:700 var(--fs-eyebrow)/1 var(--sans);letter-spacing:.2em;text-transform:uppercase;color:var(--gold)}
.soon-text{min-width:0;flex:1 1 260px}
.soon-text b{display:block;font:600 var(--fs-h3)/1.2 var(--serif);font-weight:600;color:var(--ink)}
.soon-text span{display:block;margin-top:4px;font:500 var(--fs-small)/1.45 var(--sans);color:var(--ink-3)}


/* ---------- 14. the footer ----------------------------------------------- */
.foot{position:relative;padding-block:clamp(44px,6vw,86px) calc(clamp(28px,4vw,48px) + env(safe-area-inset-bottom));
  border-top:1px solid var(--hair);background:linear-gradient(180deg,transparent,rgba(0,0,0,.34))}
/* the tagline, in gold caps between two gold hairlines */
.foot-tag{
  display:flex;align-items:center;justify-content:center;gap:clamp(12px,2vw,22px);
  font:700 clamp(10px,calc(9px + .3vw),13px)/1.4 var(--sans);letter-spacing:.3em;
  text-transform:uppercase;color:var(--gold);text-align:center}
.foot-tag::before,.foot-tag::after{content:"";flex:1 1 0;min-width:0;max-width:150px;height:1px;
  background:linear-gradient(90deg,transparent,rgba(247,169,69,.65))}
.foot-tag::after{transform:scaleX(-1)}

.foot-cols{
  margin-top:clamp(34px,4.4vw,60px);display:grid;gap:clamp(26px,3.4vw,44px);
  grid-template-columns:1fr}
@media (min-width:620px){.foot-cols{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (min-width:980px){.foot-cols{grid-template-columns:auto repeat(3,minmax(0,1fr));align-items:start}}
.foot-col{min-width:0}
.foot-logo{width:auto;height:clamp(72px,8vw,104px);opacity:.92;
  filter:drop-shadow(0 8px 20px rgba(0,0,0,.6))}
.foot-col h2{font:700 var(--fs-eyebrow)/1.2 var(--sans);letter-spacing:.24em;
  text-transform:uppercase;color:var(--ink-3);margin-bottom:14px}
.foot-col p,.foot-col li{font:500 var(--fs-small)/1.6 var(--sans);color:var(--ink-2)}
.foot-col a{display:inline-block;padding-block:3px;color:var(--ink-2);text-decoration:none;
  border-bottom:1px solid transparent;transition:color .18s,border-color .18s}
@media (hover:hover){.foot-col a:hover{color:var(--gold);border-bottom-color:var(--gold-line)}}
.foot-col ul{display:grid;gap:9px}
.foot-col .row{display:flex;justify-content:space-between;gap:14px;
  font-variant-numeric:tabular-nums}
.foot-col .row span:first-child{color:var(--ink-3)}
.foot-legal{margin-top:clamp(30px,4vw,52px);padding-top:clamp(18px,2.2vw,26px);
  border-top:1px solid var(--hair);
  font:500 clamp(12px,calc(11.4px + .16vw),14px)/1.5 var(--sans);color:var(--ink-3);text-align:center}


/* ---------- 15. the slow reveal ------------------------------------------ */
/* Scoped under .js so that if the script never runs — a bad connection, an old
   phone — every word is still on the page at full opacity. */
.js .reveal{opacity:0;transform:translateY(22px);
  transition:opacity .85s var(--ease),transform .85s var(--ease)}
.js .reveal.is-in{opacity:1;transform:none}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .slides{scroll-behavior:auto}
  .js .reveal{opacity:1;transform:none;transition:none}
  .lead::after,.pill.is-open > i,.hero-scroll svg{animation:none}
  .lead::after{opacity:0}
}
