/**
 * What a shop's own page looks like, per theme.
 *
 * The layout and the booking wizard live in book.html and are the same for
 * every barbershop - there is one wizard and there will go on being one,
 * because it is the part that takes money and four copies of it would drift.
 * What changes here is the shopfront: the sign, the tagline and the price
 * list, which is what a stranger reads before deciding to trust the place.
 *
 * Two rules hold this together.
 *
 * Everything is written against tokens. Not one hex code below, which is why
 * a shop setting its own three colours restyles all four of these for free
 * rather than needing a fifth block written for it.
 *
 * The staff screens are left alone. A theme reaches them as colour only: a
 * diary in Chrome's yellow is fine, a diary set in Anton with a stripe
 * running across it is not somewhere anybody can work a Saturday.
 */

/* Every treatment needs these hooks; each theme turns on the ones it uses. */
.stripes, .ticker, .dock, .open-sign, .menu .dots { display: none; }

@media (prefers-reduced-motion: reduce) {
  .shopfront *, .shopfront *::before, .shopfront *::after {
    animation: none !important; transition: none !important;
  }
}

/* ==================================================================== */
/* WHAT THE SHOP SELLS — named one way, wherever it is offered.         */
/* ==================================================================== */

/*
 * A haircut used to arrive in two voices on one page. The price card set it
 * in the shop's own face and the booking step a screen below set it in the
 * reading face, so the same word, from the same row of the same table, was
 * typeset twice and differently. Nothing was wrong with either treatment;
 * what was missing was anything saying how a service is named, so each list
 * had quietly grown its own answer.
 *
 * Each theme now answers that once, here, and the three lists that offer a
 * service read it: the price card, the offers above it, and the first step of
 * the wizard. Size is not part of the answer - a price card is read across a
 * room and a chip is tapped with a thumb - so that stays with each list.
 *
 * It stops at the lists, deliberately. Where a service is named inside a
 * sentence or a labelled row - the line above the confirm button, the booking
 * itself, somebody's own appointments - it is a word in running prose and
 * keeps the reading face, because a sentence set in two faces is a worse
 * fault than the one this fixes.
 */
.shopfront {
  --font-service: var(--font-body);
  --service-weight: 600;
  --service-case: none;
  --service-track: normal;

  --font-price: var(--font-body);
  --price-weight: 650;
}

.shopfront :is(.menu, .offers, .opt) b {
  font-family: var(--font-service);
  font-weight: var(--service-weight);
  text-transform: var(--service-case);
  letter-spacing: var(--service-track);
}

.shopfront :is(.menu, .offers) em {
  font-family: var(--font-price);
  font-weight: var(--price-weight);
}

/* ==================================================================== */
/* BUZZ — a sign in capitals, white cards on paper, a pole that runs.   */
/* ==================================================================== */

/* Prices are lettered like the sign, which is how Issam's home page sets
   every number it wants read; names stay in the reading face. */
[data-theme="buzz"] .shopfront {
  --font-price: var(--font-sign);
  --price-weight: 800;
}

[data-theme="buzz"] .intro h1 {
  font-family: var(--font-sign); font-weight: 800; text-transform: uppercase;
  font-size: clamp(52px, 11vw, 116px); line-height: .9; letter-spacing: .005em;
  animation: sf-slam .7s cubic-bezier(.2, 1.25, .4, 1) backwards;
}
/* The last word on its own line in red: "Fade / Factory", the way the home
   page says "You cut. / We pick up." */
[data-theme="buzz"] .intro h1 .last { color: var(--accent); }
[data-theme="buzz"] .intro .tagline {
  margin-top: 14px; font-size: clamp(18px, 2.4vw, 22px); font-weight: 600;
  line-height: 1.35; color: var(--ink);
  animation: sf-rise .7s .12s backwards;
}
[data-theme="buzz"] .facts { animation: sf-rise .7s .22s backwards; }

[data-theme="buzz"] h2 { color: var(--accent); }

/* The price list as white cards on paper. */
[data-theme="buzz"] .menu > button {
  background: var(--surface); border-radius: 16px; padding: 15px 18px;
  transition: transform .18s, box-shadow .18s, border-color .18s;
}
[data-theme="buzz"] .menu > button:hover {
  background: var(--surface); border-color: var(--ink);
  transform: translateY(-3px); box-shadow: 0 14px 26px -18px var(--shadow);
}
[data-theme="buzz"] .menu b { font-size: 15.5px; }
[data-theme="buzz"] .menu em { font-size: 30px; line-height: 1; color: var(--accent); }
[data-theme="buzz"] .offers > li > button { border-width: 2px; border-radius: 16px; }
[data-theme="buzz"] .offers em { font-size: 24px; }

/* Rounder, and the chosen thing in ink, the way the home page's buttons are. */
[data-theme="buzz"] .card { border-radius: 24px; backdrop-filter: none; }
[data-theme="buzz"] .btn { border-radius: 999px; }
[data-theme="buzz"] .btn.primary { background: var(--accent); padding: 10px 20px; }
[data-theme="buzz"] :is(.opt, .day, .time) { border-radius: 14px; }
[data-theme="buzz"] :is(.opt, .day, .time)[aria-pressed="true"] {
  background: var(--ink); border-color: var(--ink); color: var(--bg);
}
[data-theme="buzz"] :is(.opt, .day, .time)[aria-pressed="true"] :is(b, span) { color: var(--bg); }
[data-theme="buzz"] .whos button { border-radius: 999px; }
[data-theme="buzz"] .team li, [data-theme="buzz"] .gallery img { border-radius: 16px; }

/* ==================================================================== */
/* PARLOUR — a printed price card, and a pole that turns.               */
/* ==================================================================== */

/* Playfair for both. A name takes the lighter of the two weights this theme
   loads, because a printed card lists its services and shouts its prices. */
[data-theme="parlour"] .shopfront {
  --font-service: var(--font-sign);
  --service-weight: 500;
  --font-price: var(--font-sign);
}

[data-theme="parlour"] .intro h1 {
  font-family: var(--font-sign);
  font-size: clamp(46px, 10vw, 104px);
  line-height: .95;
  letter-spacing: -.03em;
  animation: sf-rise .9s cubic-bezier(.2,.7,.3,1) backwards;
}
[data-theme="parlour"] .intro .tagline {
  font-family: var(--font-quote); font-style: italic;
  font-size: clamp(18px, 2.4vw, 25px);
  animation: sf-rise .9s .12s backwards;
}

/* A brass hairline that draws itself under the name. */
[data-theme="parlour"] .intro::after {
  content: ''; display: block; height: 1px; margin: 22px 0 18px;
  background: linear-gradient(90deg, var(--accent), transparent);
  transform-origin: left;
  animation: sf-draw 1.3s .25s cubic-bezier(.2,.8,.2,1) backwards;
}
[data-theme="parlour"] .facts { animation: sf-rise .9s .35s backwards; }

/* The mark's square becomes a barber's pole, in motion.css, which turns the
   same pole on the shop's sign-in and appointment pages too. */

/* Rows with leader dots rather than a grid of cards. */
[data-theme="parlour"] .menu { display: block; }
[data-theme="parlour"] .menu > button {
  display: grid; grid-template-columns: auto 1fr auto; align-items: baseline; gap: 12px;
  background: none; border: 0; border-bottom: 1px solid var(--line);
  border-radius: 0; padding: 15px 4px;
}
[data-theme="parlour"] .menu > button:hover { background: var(--surface); padding-left: 14px; }
[data-theme="parlour"] .menu .dots {
  display: block; align-self: center;
  border-bottom: 1.5px dotted color-mix(in srgb, var(--ink) 26%, transparent);
}
/* Name and duration on one line, or the leader dots have nothing to lead
   along and the price floats away from a two-line block. */
[data-theme="parlour"] .menu .what { display: block; }
[data-theme="parlour"] .menu b { display: inline; font-size: 21px; }
[data-theme="parlour"] .menu i { display: inline; margin-left: 10px; }
[data-theme="parlour"] .menu em { font-size: 22px; color: var(--accent); }

/* ==================================================================== */
/* LINEN — daylight, enormous type, and a dock that follows you down.   */
/* ==================================================================== */

/* The sign is plain here and the character is carried by the serif, so a
   service is named in daylight and priced in the serif. */
[data-theme="linen"] .shopfront {
  --font-service: var(--font-sign);
  --service-weight: 500;
  --font-price: var(--font-quote);
}

[data-theme="linen"] .intro h1 {
  font-family: var(--font-sign); font-weight: 700;
  font-size: clamp(50px, 12vw, 140px); line-height: .88; letter-spacing: -.055em;
  /* Wiped up from behind its own edge: things arrive, nothing bounces. */
  overflow: hidden;
}
[data-theme="linen"] .intro h1 > span,
[data-theme="linen"] .intro h1 { display: block; }
[data-theme="linen"] .intro h1 { animation: sf-wipe 1.05s cubic-bezier(.16,1,.3,1) backwards; }

[data-theme="linen"] .intro .tagline {
  font-family: var(--font-quote); font-style: italic;
  font-size: clamp(20px, 2.8vw, 31px); line-height: 1.25; max-width: 22ch;
}
[data-theme="linen"] .facts {
  gap: 10px 44px; padding-top: 22px; border-top: 1px solid var(--line); margin-top: 34px;
}

/* A list, not cards. The price is the loud part. */
[data-theme="linen"] .menu { display: block; }
[data-theme="linen"] .menu > button {
  display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 20px;
  background: none; border: 0; border-bottom: 1px solid var(--line); border-radius: 0;
  padding: 24px 8px;
}
[data-theme="linen"] .menu > button:hover { background: var(--surface-hover); padding-left: 20px; }
[data-theme="linen"] .menu .what { display: block; }
/* The negative tracking is for this size and stays here rather than going
   into the theme's answer above: it closes up 36px type and would strangle
   the same words at the size a chip sets them. */
[data-theme="linen"] .menu b { display: inline; font-size: clamp(22px, 3.2vw, 36px); letter-spacing: -.03em; }
[data-theme="linen"] .menu i { display: inline; margin-left: 14px; vertical-align: middle; }
[data-theme="linen"] .menu em { font-size: clamp(24px, 3.6vw, 38px); color: var(--accent); }

[data-theme="linen"] .dock {
  display: flex; position: sticky; bottom: 20px; z-index: 5;
  margin: 40px auto 0; width: fit-content; align-items: center; gap: 16px;
  background: var(--ink); color: var(--bg); border-radius: 999px;
  padding: 10px 12px 10px 22px; box-shadow: 0 14px 40px var(--shadow);
  /* Held back until the hero is behind you. Offering a time before anybody
     has seen a price is nagging, and over the address it looks like a bug. */
  opacity: 0; transform: translateY(14px); pointer-events: none; transition: .45s ease;
}
[data-theme="linen"] .dock[data-up] { opacity: 1; transform: none; pointer-events: auto; }
[data-theme="linen"] .dock button {
  font: inherit; font-size: 13.5px; font-weight: 650; cursor: pointer; border: 0;
  border-radius: 999px; padding: 9px 19px; background: var(--bg); color: var(--ink);
}

/* ==================================================================== */
/* MIDNIGHT — a neon sign in a dark window.                             */
/* ==================================================================== */

/* The tube-bent face is for the sign over the door and nothing else; the
   condensed one under it is what this theme writes in. Its tracking is a
   property of the face rather than of any one size, so it travels. */
[data-theme="midnight"] .shopfront {
  position: relative;
  --font-service: var(--font-label);
  --service-track: .04em;
}
[data-theme="midnight"] .intro h1 {
  font-family: var(--font-sign); font-weight: 400;
  font-size: clamp(34px, 8vw, 88px); line-height: 1.1; color: var(--ink);
  /* The glow is the theme's own accent, so a shop that picks red gets red
     neon rather than the cyan this was drawn in. */
  text-shadow:
    0 0 6px color-mix(in srgb, var(--ink) 80%, transparent),
    0 0 16px var(--accent),
    0 0 38px var(--accent),
    0 0 74px color-mix(in srgb, var(--accent-2) 60%, transparent);
  animation: sf-strike 2.2s steps(1) 1 both;
}
[data-theme="midnight"] .intro .tagline { font-family: var(--font-quote); max-width: 46ch; }
[data-theme="midnight"] .facts dt { font-family: var(--font-label); letter-spacing: .14em; color: var(--accent); }

[data-theme="midnight"] .open-sign {
  display: inline-flex; align-items: center;
  font-family: var(--font-label); font-size: 14px; letter-spacing: .2em;
  color: var(--accent); border: 1.5px solid var(--accent); border-radius: 6px; padding: 4px 12px;
  text-shadow: 0 0 8px var(--accent);
  box-shadow: 0 0 14px color-mix(in srgb, var(--accent) 35%, transparent),
              inset 0 0 10px color-mix(in srgb, var(--accent) 18%, transparent);
  animation: sf-buzz 3.4s infinite;
}

[data-theme="midnight"] h2 { font-family: var(--font-label); font-size: 22px; letter-spacing: .14em; color: var(--ink); }
[data-theme="midnight"] .menu > button { overflow: hidden; position: relative; }
/* A light that sweeps the glass when you point at it. */
[data-theme="midnight"] .menu > button::after {
  content: ''; position: absolute; inset: 0; transform: translateX(-100%);
  background: linear-gradient(105deg, transparent 30%,
    color-mix(in srgb, var(--ink) 12%, transparent) 50%, transparent 70%);
  transition: transform .7s;
}
[data-theme="midnight"] .menu > button:hover {
  border-color: var(--accent);
  box-shadow: 0 0 22px color-mix(in srgb, var(--accent) 28%, transparent);
  transform: translateY(-3px);
}
[data-theme="midnight"] .menu > button:hover::after { transform: translateX(100%); }
[data-theme="midnight"] .menu b { font-size: 21px; }
[data-theme="midnight"] .menu em {
  font-size: 25px; color: var(--accent);
  text-shadow: 0 0 12px color-mix(in srgb, var(--accent) 50%, transparent);
}

/* ==================================================================== */
/* CHROME — stripes, a ticker, and cards that snap.                     */
/* ==================================================================== */

/* Everything here is set in capitals, which is as much a part of how this
   theme says a word as the face it says it in, so the case travels with the
   face instead of being reapplied list by list. */
[data-theme="chrome"] .shopfront {
  --font-service: var(--font-label);
  --service-case: uppercase;
  --service-track: .02em;
  --font-price: var(--font-label);
}

[data-theme="chrome"] .stripes {
  display: block; height: 15px; margin: 18px 0 0;
  background: repeating-linear-gradient(115deg,
    var(--accent) 0 20px, var(--bg) 20px 40px, var(--ink) 40px 60px, var(--bg) 60px 80px);
  background-size: 160px 100%;
  animation: sf-run 2.4s linear infinite;
}

/* This face overshoots its own line box badly at these sizes, so the top
   margin is clearing the stripe band above rather than being decorative. */
[data-theme="chrome"] .intro { margin-top: 34px; }
[data-theme="chrome"] .intro h1 {
  font-family: var(--font-sign); text-transform: uppercase;
  font-size: clamp(52px, 13vw, 152px); line-height: .9; letter-spacing: -.01em;
}
/* The second word is cut out of the page rather than printed on it. */
[data-theme="chrome"] .intro h1 .cut {
  -webkit-text-stroke: 2px var(--accent); color: transparent;
}
[data-theme="chrome"] .intro .tagline { max-width: 42ch; }
[data-theme="chrome"] .facts dt { font-family: var(--font-label); color: var(--accent); letter-spacing: .06em; }

[data-theme="chrome"] .ticker {
  display: block; margin: 34px 0 0; overflow: hidden;
  border-top: 2px solid var(--ink); border-bottom: 2px solid var(--ink); padding: 11px 0;
}
[data-theme="chrome"] .ticker > div { display: flex; gap: 38px; width: max-content; animation: sf-slide 22s linear infinite; }
[data-theme="chrome"] .ticker:hover > div { animation-play-state: paused; }
/* The price list again, read out along a rail, so it is set as the price
   list is. */
[data-theme="chrome"] .ticker b {
  font-family: var(--font-service); font-size: 23px;
  text-transform: var(--service-case); letter-spacing: .03em; white-space: nowrap;
}
[data-theme="chrome"] .ticker b span { color: var(--accent); }

[data-theme="chrome"] h2 { font-family: var(--font-label); font-size: 30px; text-transform: uppercase; letter-spacing: .02em; color: var(--ink); }

[data-theme="chrome"] .menu > button {
  border: 2px solid var(--ink); border-radius: 0; align-items: flex-end;
  background: var(--surface); transition: .14s;
}
[data-theme="chrome"] .menu > button:hover {
  background: var(--accent); color: var(--on-accent);
  transform: translate(-3px, -3px); box-shadow: 6px 6px 0 var(--ink);
}
[data-theme="chrome"] .menu > button:hover b,
[data-theme="chrome"] .menu > button:hover i,
[data-theme="chrome"] .menu > button:hover em { color: var(--on-accent); }
[data-theme="chrome"] .menu b { font-size: 21px; }
[data-theme="chrome"] .menu em { font-size: 28px; }

[data-theme="chrome"] .who .btn, [data-theme="chrome"] .btn.primary {
  border-radius: 0; box-shadow: 4px 4px 0 var(--ink); text-transform: uppercase;
  font-family: var(--font-label); letter-spacing: .07em;
}
[data-theme="chrome"] .btn.primary:hover { transform: translate(2px, 2px); box-shadow: 2px 2px 0 var(--ink); }

/* ==================================================================== */

/* ==================================================================== */
/* SAGE - daylight, generous spacing, nothing shouting.                 */
/* ==================================================================== */

/* The serif is kept for the sign alone. Everything a customer reads below it
   is one face at one weight, which is the whole of this theme's argument. */
[data-theme="sage"] .shopfront {
  --service-weight: 550;
  --price-weight: 550;
}

[data-theme="sage"] .intro { margin-top: 26px; }
[data-theme="sage"] .intro h1 {
  font-family: var(--font-sign); font-weight: 400;
  font-size: clamp(42px, 8vw, 86px); line-height: 1.02; letter-spacing: -.02em;
  animation: sf-rise .6s ease both;
}
[data-theme="sage"] .intro .tagline {
  max-width: 46ch; font-size: 17px; color: var(--ink-dim); margin-top: 12px;
}
[data-theme="sage"] .facts dt { letter-spacing: .1em; }

[data-theme="sage"] h2 {
  font-family: var(--font-label); font-size: 12px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .13em; color: var(--ink-faint);
}

/* A list with the price at the end of the line, the way a menu on a wall
   reads, rather than a grid of boxes competing for attention. */
[data-theme="sage"] .menu { display: block; }
[data-theme="sage"] .menu > button {
  border: 0; border-bottom: 1px solid var(--line-soft); border-radius: 0;
  background: none; padding: 15px 2px;
}
[data-theme="sage"] .menu > button:hover { background: var(--surface-2); }
[data-theme="sage"] .menu b { font-size: 16px; }
[data-theme="sage"] .menu em { font-size: 16px; color: var(--accent); }

/* The work, bigger here than anywhere else: a calm page can afford it. */
[data-theme="sage"] .gallery { grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 11px; }
[data-theme="sage"] .team li { background: none; border-color: var(--line-soft); }

/* ==================================================================== */
/* POMADE - cream, a deep red, and a sign over the door.                */
/* ==================================================================== */

/* The slab is a signwriter's face, so it paints the numbers and the headings
   and the names are left in the grotesque beside them - which is how a card in
   a window of this vintage was actually lettered. One weight only: the face is
   drawn at a single thickness and asking a browser to embolden something this
   heavy just smears it. */
[data-theme="pomade"] .shopfront {
  --font-price: var(--font-sign);
  --price-weight: 400;
}

[data-theme="pomade"] .stripes {
  display: block; height: 11px; margin: 16px 0 0; border-radius: 6px;
  background: repeating-linear-gradient(115deg,
    var(--accent) 0 14px, var(--surface) 14px 28px, var(--accent-2) 28px 42px, var(--surface) 42px 56px);
  background-size: 112px 100%;
  animation: sf-run 3.6s linear infinite;
}

[data-theme="pomade"] .intro { margin-top: 28px; text-align: center; }
[data-theme="pomade"] .intro h1 {
  font-family: var(--font-sign); font-size: clamp(40px, 9vw, 96px);
  line-height: .98; color: var(--accent); letter-spacing: -.01em;
  animation: sf-rise .55s ease both;
}
[data-theme="pomade"] .intro .tagline {
  margin: 10px auto 0; max-width: 44ch; font-style: italic;
}
[data-theme="pomade"] .facts { justify-content: center; }
[data-theme="pomade"] .socials { justify-content: center; }
[data-theme="pomade"] .hours { text-align: center; }
[data-theme="pomade"] .hours-week { margin-left: auto; margin-right: auto; text-align: left; }

[data-theme="pomade"] h2 {
  font-family: var(--font-sign); font-size: 22px; letter-spacing: 0;
  color: var(--accent); text-transform: none;
}

/* The price card a barbershop actually has on the wall: ruled lines, the
   price at the end, leader dots carrying the eye across. */
[data-theme="pomade"] .menu { display: block; }
[data-theme="pomade"] .menu > button {
  background: none; border: 0; border-bottom: 1px dashed var(--line);
  border-radius: 0; padding: 13px 4px;
}
[data-theme="pomade"] .menu .dots {
  display: block; flex: 1; height: 1px; align-self: flex-end; margin-bottom: 6px;
  background: repeating-linear-gradient(90deg, var(--line-strong) 0 2px, transparent 2px 7px);
}
[data-theme="pomade"] .menu b { font-size: 16px; }
[data-theme="pomade"] .menu em { font-size: 18px; color: var(--accent); }

/* ==================================================================== */
/* NOIR - a magazine page, so the photographs win.                      */
/* ==================================================================== */

/* The garamond throughout, light, because a magazine sets its captions in the
   same face as its headlines and that is the look being borrowed. */
[data-theme="noir"] .shopfront {
  --font-service: var(--font-sign);
  --service-weight: 400;
  --font-price: var(--font-sign);
  --price-weight: 400;
}

[data-theme="noir"] .intro { margin-top: 30px; }
[data-theme="noir"] .intro h1 {
  font-family: var(--font-sign); font-weight: 300;
  font-size: clamp(46px, 11vw, 120px); line-height: .95; letter-spacing: -.015em;
  animation: sf-rise .6s ease both;
}
[data-theme="noir"] .intro .tagline {
  font-family: var(--font-quote); font-style: italic;
  font-size: 21px; max-width: 40ch; color: var(--ink-dim);
}
[data-theme="noir"] .facts dt { letter-spacing: .14em; font-size: 10.5px; }

[data-theme="noir"] h2 {
  font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .18em; color: var(--ink-faint);
}

[data-theme="noir"] .menu { display: block; }
[data-theme="noir"] .menu > button {
  background: none; border: 0; border-bottom: 1px solid var(--line-soft);
  border-radius: 0; padding: 16px 2px;
}
[data-theme="noir"] .menu b { font-size: 21px; }
[data-theme="noir"] .menu em { font-size: 21px; color: var(--accent); }

/* Edge to edge and square, with no gaps: the whole point of this theme is
   that the work is the page. */
[data-theme="noir"] .gallery { gap: 3px; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
[data-theme="noir"] .gallery img { border-radius: 0; border: 0; }
[data-theme="noir"] .team li { background: none; border: 0; padding: 0 0 8px; }
[data-theme="noir"] .team img, [data-theme="noir"] .team .noface {
  width: 100%; height: auto; aspect-ratio: 1; border-radius: 0; border: 0;
}

@keyframes sf-rise { from { opacity: 0; transform: translateY(22px); } }
@keyframes sf-slam { from { opacity: 0; transform: scale(1.08) translateY(6px); } }
@keyframes sf-wipe { from { transform: translateY(105%); } }
@keyframes sf-draw { from { transform: scaleX(0); } }
@keyframes sf-run  { to { background-position: -160px 0; } }
@keyframes sf-slide { to { transform: translateX(-50%); } }
@keyframes sf-buzz { 0%, 96%, 100% { opacity: 1; } 97% { opacity: .35; } 98.5% { opacity: 1; } }
@keyframes sf-strike {
  0%, 8%   { opacity: .25; text-shadow: none; }
  9%, 11%  { opacity: 1; }
  12%, 14% { opacity: .3; text-shadow: none; }
  15%, 19% { opacity: 1; }
  20%, 21% { opacity: .5; }
  22%, 100% { opacity: 1; }
}
