/* ============================================================
   Brook Philemon Nails
   Palette lifted straight off the logo: warm sand, cream, ink.
   Mobile first. Base 375px. Breakpoints 640 / 1024.
   Quiet by design: few shapes, one accent, a lot of air.
   ============================================================ */

:root {
  --sand:    #e7dfd4;   /* the logo background */
  --sand-2:  #ded4c7;   /* deeper band */
  --cream:   #f3eee6;   /* cards */
  --ivory:   #faf7f2;   /* the lightest surface */
  --mono:    #f6f1e8;   /* the BP watermark. Lighter than the sand, as in the logo */
  --word:    #f7f3ec;   /* the pale word under the signature */

  /* Everything that carries words is near black. Warm grey on warm
     sand tested as unreadable outdoors and on a dim phone, so the
     old three-step grey ramp is now three steps of almost-black. */
  --ink:     #17140f;
  --ink-2:   #241f18;
  --ink-3:   #2f2820;
  --line:    #cdc0ae;
  --line-2:  #b8a893;

  --accent:      #6b563c;   /* mocha, darkened to read as text */
  --accent-deep: #4b3c28;
  --towson:      #2d4a50;   /* the Towson marker */
  --live:        #22c55e;   /* open right now. Bright, it has to read at a glance */
  --off:         #9a3b2c;

  /* Pill everywhere. Small radii are only for things that would
     look wrong as a capsule, like time inputs in a row. */
  --r-sm: 14px;
  --r-md: 22px;
  --r-lg: 32px;
  --r-full: 999px;
  --shell: 1080px;

  --shadow: 0 18px 40px -24px rgba(35, 26, 14, .5);
  --lift:   0 30px 60px -30px rgba(35, 26, 14, .62);

  /* one easing for the whole site, so nothing feels out of step */
  --ease: cubic-bezier(.22, .61, .36, 1);
  --ease-soft: cubic-bezier(.4, 0, .2, 1);

  --dock-h: 76px;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

/* Any display rule below would otherwise beat the hidden attribute,
   which is how a "hidden" grid stays on screen. This wins. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--sand);
  color: var(--ink);
  font-family: Jost, "Helvetica Neue", system-ui, -apple-system, sans-serif;
  font-size: 15px;
  font-weight: 400;
  line-height: 1.65;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  padding-bottom: var(--dock-h);
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; margin: 0; padding: 0; }
button { font: inherit; color: inherit; }

h1, h2, h3, h4, .serif {
  font-family: "Cormorant Garamond", Georgia, serif;
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.005em;
  margin: 0;
}

.shell   { width: 100%; max-width: var(--shell); margin: 0 auto; padding: 0 20px; }
.shell-n { max-width: 760px; }
.section { padding: 54px 0; }
.band    { background: var(--sand-2); }
.center  { text-align: center; }
.accent  { color: var(--accent); }

.eyebrow {
  font-size: 10.5px; font-weight: 500; letter-spacing: .26em;
  text-transform: uppercase; color: var(--accent); margin: 0 0 12px;
}
.h1   { font-size: 40px; }
.h2   { font-size: 32px; margin-bottom: 12px; }
.h3   { font-size: 22px; }
.lede { color: var(--ink-2); font-size: 15px; max-width: 58ch; margin: 0; }
.small-note { font-size: 12.5px; color: var(--ink-3); margin: 12px 0 0; }
.rule { height: 1px; background: var(--line); border: 0; margin: 0; }

/* ============================================================
   THE LOGO LOCKUP
   Three layers, same as the printed logo: the BP monogram sits
   behind, the signature crosses it, the word sits under.
   ============================================================ */
.lockup {
  position: relative;
  display: inline-block;
  padding: 40px 0 8px;
  line-height: 1;
  max-width: 100%;
}
/* the monogram sits behind. Absolute, so it never sets the width. */
.lockup-mono {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -56%);
  font-family: "Cormorant Garamond", Georgia, serif;
  font-weight: 600;
  /* Sized off the same vw as the signature so the monogram keeps
     the proportion it has in the printed logo, roughly half the
     width of the handwriting, at every screen size. */
  font-size: clamp(138px, 50vw, 195px);
  line-height: 1;
  letter-spacing: -0.06em;
  color: var(--mono);
  z-index: 0;
  user-select: none;
  pointer-events: none;
}
/* the signature sets the width of the whole lockup */
.lockup-script {
  position: relative;
  z-index: 1;
  display: block;
  text-align: center;
  /* Herr Von Muellerhoff. Hairline and small on the body, so it is
     set much larger than a normal script would be, and sized in vw
     so the nowrap signature can never outgrow a narrow phone. */
  font-family: "Herr Von Muellerhoff", Allura, "Brush Script MT", cursive;
  font-weight: 400;
  font-size: clamp(58px, 21vw, 82px);
  line-height: .96;
  color: var(--ink);
  white-space: nowrap;
  margin: 0;
  letter-spacing: .005em;
}
.lockup-word {
  position: relative;
  z-index: 1;
  display: block;
  text-align: center;
  font-size: 18px;
  font-weight: 300;
  letter-spacing: .42em;
  text-indent: .42em;
  text-transform: uppercase;
  color: var(--word);
  margin-top: 2px;
}

/* small version, for the header */
.lockup-sm                { padding: 20px 0 3px; }
.lockup-sm .lockup-mono   { font-size: 74px; }
/* A hairline script goes to nothing at nav size, so the small
   lockup runs proportionally larger than the maths would suggest. */
.lockup-sm .lockup-script { font-size: 34px; }
.lockup-sm .lockup-word   { font-size: 7.5px; letter-spacing: .34em; text-indent: .34em;
                            margin-top: 0; color: var(--ink-3); }

@media (min-width: 640px) {
  .lockup        { padding: 56px 0 12px; }
  .lockup-mono   { font-size: clamp(197px, 26.4vw, 278px); }
  .lockup-script { font-size: clamp(82px, 11vw, 116px); }
  .lockup-word   { font-size: 23px; }
}

/* ============================================================
   HEADER
   ============================================================ */
/* A floating capsule rather than a full-width bar. It shrinks and
   gains a shadow once you scroll, so it stays out of the way. */
.site-header {
  position: sticky; top: 0; z-index: 60;
  padding: 10px 14px 0;
  transition: padding .35s var(--ease);
}
/* No logo in here, so the bar is just navigation. It sits centred
   and only as wide as its contents rather than stretching the full
   page, which is what made it look empty once the mark came out. */
.nav {
  width: max-content; max-width: calc(100% - 8px); margin: 0 auto;
  padding: 5px 6px 5px 6px;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  background: rgba(243, 238, 230, .82);
  backdrop-filter: blur(16px) saturate(1.3);
  -webkit-backdrop-filter: blur(16px) saturate(1.3);
  border: 1px solid transparent;
  border-radius: var(--r-full);
  transition: border-color .35s var(--ease-soft), box-shadow .35s var(--ease),
              background .35s var(--ease-soft), transform .35s var(--ease);
}
.site-header.scrolled { padding-top: 6px; }
.site-header.scrolled .nav {
  border-color: var(--line);
  box-shadow: 0 14px 34px -22px rgba(35, 26, 14, .75);
  background: rgba(243, 238, 230, .94);
}
.nav-links { display: none; gap: 22px; font-size: 13px; letter-spacing: .02em; padding: 0 10px; }
.nav-links a { color: var(--ink-2); padding: 6px 0; position: relative; transition: color .22s var(--ease-soft); }
.nav-links a::after {
  content: ""; position: absolute; left: 0; right: 100%; bottom: 2px;
  height: 1px; background: var(--accent); transition: right .34s var(--ease);
}
.nav-links a:hover { color: var(--ink); }
.nav-links a:hover::after, .nav-links a[aria-current="page"]::after { right: 0; }
.nav-links a[aria-current="page"] { color: var(--ink); }

.nav-right { display: flex; align-items: center; gap: 10px; }
.ig-btn {
  width: 36px; height: 36px; display: grid; place-items: center; flex: none;
  border: 1px solid var(--line-2); border-radius: var(--r-full); color: var(--ink-2);
  transition: background .24s var(--ease-soft), color .24s var(--ease-soft),
              border-color .24s var(--ease-soft), transform .24s var(--ease);
}
.ig-btn svg { width: 17px; height: 17px; }
.ig-btn:hover { background: var(--ink); color: var(--ivory); border-color: var(--ink); transform: translateY(-1px); }

.burger {
  width: 36px; height: 36px; border: 1px solid var(--line-2); background: none;
  border-radius: var(--r-full); cursor: pointer; display: grid; place-items: center;
  padding: 0; flex: none;
  transition: border-color .24s var(--ease-soft);
}
.burger:hover { border-color: var(--ink); }
.burger span, .burger span::before, .burger span::after {
  content: ""; display: block; width: 15px; height: 1px; background: var(--ink);
  transition: transform .3s var(--ease);
}
.burger span { position: relative; }
.burger span::before { position: absolute; top: -5px; }
.burger span::after  { position: absolute; top: 5px; }

.mobile-menu {
  position: fixed; inset: 0; z-index: 90; background: var(--sand);
  display: flex; flex-direction: column; justify-content: center; gap: 2px;
  padding: 32px 28px;
  opacity: 0; visibility: hidden;
  transform: translateY(-14px);
  transition: opacity .32s var(--ease-soft), transform .38s var(--ease), visibility .38s;
}
.mobile-menu.open { opacity: 1; visibility: visible; transform: none; }
.menu-link {
  font-family: "Cormorant Garamond", Georgia, serif; font-size: 30px;
  padding: 11px 0; border-bottom: 1px solid var(--line);
  opacity: 0; transform: translateY(10px);
}
.mobile-menu.open .menu-link { animation: menuIn .44s var(--ease) forwards; }
.mobile-menu.open .menu-link:nth-child(2) { animation-delay: .04s; }
.mobile-menu.open .menu-link:nth-child(3) { animation-delay: .08s; }
.mobile-menu.open .menu-link:nth-child(4) { animation-delay: .12s; }
.mobile-menu.open .menu-link:nth-child(5) { animation-delay: .16s; }
.mobile-menu.open .menu-link:nth-child(6) { animation-delay: .20s; }
@keyframes menuIn { to { opacity: 1; transform: none; } }
.menu-close {
  position: absolute; top: 18px; right: 22px; background: none; border: 0;
  font-size: 34px; line-height: 1; cursor: pointer; color: var(--ink-2);
}
.menu-foot { margin-top: 26px; display: grid; gap: 10px; }

@media (min-width: 900px) {
  .nav-links { display: flex; }
  .burger { display: none; }
}

/* ============================================================
   BUTTONS
   ============================================================ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 13px 26px; border-radius: var(--r-full); border: 1px solid transparent;
  font-size: 12px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase;
  cursor: pointer; text-align: center;
  transition: transform .22s var(--ease), background .24s var(--ease-soft),
              color .24s var(--ease-soft), border-color .24s var(--ease-soft),
              box-shadow .24s var(--ease-soft), opacity .2s;
}
.btn:hover  { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }
/* Every button is black with white letters. The secondary one is
   the same capsule a shade lighter, so the hierarchy survives
   without dropping any of them to low-contrast outline text. */
.btn-primary { background: var(--ink); color: #fff; }
.btn-primary:hover { background: var(--accent-deep); box-shadow: var(--lift); }
.btn-ghost { background: #3b342b; color: #fff; border-color: #3b342b; }
.btn-ghost:hover { background: var(--ink); border-color: var(--ink); box-shadow: var(--shadow); }
.btn-sm { padding: 9px 17px; font-size: 10.5px; }
.btn:disabled { opacity: .34; cursor: not-allowed; transform: none; box-shadow: none; }
.btn-row { display: flex; flex-wrap: wrap; gap: 12px; }

/* ============================================================
   THE DOCK
   The booking call to action, pinned to the bottom of every page.
   On the booking page the running total takes the same slot.
   ============================================================ */
/* A floating capsule, not a bar welded to the bottom edge. */
.dock {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 70;
  padding: 0 12px 12px;
  padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  pointer-events: none;
  animation: dockIn .6s var(--ease) .35s both;
}
@keyframes dockIn { from { opacity: 0; transform: translateY(120%); } to { opacity: 1; transform: none; } }
.dock-in {
  pointer-events: auto;
  max-width: 560px; margin: 0 auto;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 9px 9px 9px 20px;
  background: rgba(243, 238, 230, .9);
  backdrop-filter: blur(18px) saturate(1.3);
  -webkit-backdrop-filter: blur(18px) saturate(1.3);
  border: 1px solid var(--line);
  border-radius: var(--r-full);
  box-shadow: 0 20px 44px -24px rgba(35, 26, 14, .8);
}
.dock-text { min-width: 0; }
.dock-text small {
  display: block; font-size: 9.5px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--ink-3);
}
.dock-text b {
  display: block; font-family: "Cormorant Garamond", Georgia, serif;
  font-size: 19px; font-weight: 600; line-height: 1.2;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dock .btn { flex: none; }

/* dark variant, used for the running total on the booking page */
.dock-dark .dock-in { background: rgba(23, 20, 15, .95); border-color: rgba(255,255,255,.14); }
.dock-dark .dock-text small { color: rgba(250, 247, 242, .72); }
.dock-dark .dock-text b { color: var(--ivory); }
.dock-dark .btn-primary { background: var(--ivory); color: var(--ink); }
.dock-dark .btn-primary:hover { background: #fff; }

/* ============================================================
   HERO
   ============================================================ */
.hero { padding: 26px 0 46px; text-align: center; }
.hero-live { margin-top: 20px; }
.hero-locations {
  display: flex; flex-wrap: wrap; justify-content: center; align-items: center;
  gap: 8px 18px; margin: 22px 0 0;
}
.hero-tag {
  font-family: "Cormorant Garamond", Georgia, serif;
  font-size: 21px; font-style: italic; color: var(--ink-2);
  margin: 16px auto 0; max-width: 34ch;
}
.hero .btn-row { justify-content: center; margin-top: 26px; }
.hero-fine { font-size: 12px; color: var(--ink-3); margin-top: 16px; }
@media (min-width: 640px) { .hero-tag { font-size: 24px; max-width: 42ch; } }

/* ============================================================
   LIVE STATUS
   The first thing on the page: where Brook is right now, so a
   client does not have to read a schedule to find out.
   ============================================================ */
/* Two rows, always both, so the badge never changes shape between
   open and closed. Fixed label column keeps the values aligned. */
.live {
  display: inline-block; text-align: left;
  background: var(--cream); border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 4px 20px 4px 16px;
  max-width: 100%;
  animation: liveIn .6s var(--ease) both;
}
@keyframes liveIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }

.live-row {
  display: grid;
  grid-template-columns: 14px 88px minmax(0, 1fr);
  align-items: baseline; gap: 0 10px;
  padding: 11px 0;
}
.live-row + .live-row { border-top: 1px solid var(--line); }
.live-mark { position: relative; top: 1px; width: 10px; height: 10px; }
.live-k {
  font-size: 10px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink-3); white-space: nowrap;
}
.live-v { font-size: 14.5px; font-weight: 500; color: var(--ink); line-height: 1.3; }
.live-v small {
  display: block; font-size: 11.5px; font-weight: 400; color: var(--ink-3);
  letter-spacing: 0; text-transform: none; margin-top: 1px;
}
/* Closed reads as a state, not as a place. */
.live.off .is-now .live-v { color: var(--ink-3); font-weight: 400; }

/* The blip. A steady core with a ring pulsing out of it, the way a
   live indicator reads in an admin dashboard. Only the state where
   Brook is actually in a chair gets the pulse: a dot that always
   blinks stops meaning anything. */
.blip { position: relative; display: block; width: 10px; height: 10px; flex: none; }
.blip i, .blip u {
  position: absolute; inset: 0; border-radius: 50%; display: block;
  background: var(--ink-3);
}
.blip u { opacity: 0; }
.blip i { transform: scale(.72); }

/* Bright green, and it only runs when she is genuinely open. */
.live.on .blip i, .live.on .blip u { background: var(--live); }
.live.on .blip i { box-shadow: 0 0 0 2px rgba(34, 197, 94, .22); }
.live.on .blip u { opacity: .55; animation: blipRing 1.6s var(--ease-soft) infinite; }
.live.on .blip i { animation: blipCore 1.6s var(--ease-soft) infinite; }

@keyframes blipRing {
  0%   { transform: scale(.72); opacity: .5; }
  70%  { transform: scale(2.2);  opacity: 0; }
  100% { transform: scale(2.2);  opacity: 0; }
}
@keyframes blipCore {
  0%, 100% { transform: scale(.72); }
  50%      { transform: scale(.86); }
}
@media (prefers-reduced-motion: reduce) {
  .live.on .blip u { animation: none; opacity: .3; transform: scale(1.5); }
  .live.on .blip i { animation: none; }
}

/* ---------- location marker, used everywhere a place is named ---------- */
.loc-chip {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 10.5px; letter-spacing: .18em; text-transform: uppercase;
  color: var(--ink-2); white-space: nowrap;
}
.loc-chip i { width: 7px; height: 7px; border-radius: 50%; flex: none; background: var(--ink); }
.loc-chip em { font-style: normal; color: var(--ink-3); }

/* ============================================================
   THE WORK: spotlight carousel
   One set in focus, its neighbours peeking, and the name below
   changing with it.
   ============================================================ */
/* full bleed, and clipped there, so the peeking cards stop at the
   screen edge instead of widening the page */
.deck {
  margin: 26px -20px 0;
  padding: 14px 20px 26px;
  overflow: hidden;
  user-select: none;
}
.deck-stage {
  position: relative;
  height: 420px;
  touch-action: pan-y;
  cursor: grab;
}
.deck-stage:active { cursor: grabbing; }

.deck-card {
  position: absolute; top: 0; left: 50%;
  width: 72%; max-width: 340px; height: 100%;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--cream) center / cover no-repeat;
  border: 1px solid var(--line);
  transform: translateX(-50%) scale(.72);
  opacity: 0;
  pointer-events: none;
  transition: transform .62s var(--ease), opacity .5s var(--ease-soft),
              box-shadow .62s var(--ease);
  display: grid; place-items: center;
}
.deck-card.is-prev,
.deck-card.is-next { opacity: .42; z-index: 2; }
.deck-card.is-prev { transform: translateX(-100%) scale(.8); }
.deck-card.is-next { transform: translateX(0%)    scale(.8); }
.deck-card.is-active {
  opacity: 1; z-index: 3; pointer-events: auto;
  transform: translateX(-50%) scale(1);
  box-shadow: var(--lift);
}

.deck-cap { margin-top: 4px; text-align: center; min-height: 58px; }
.deck-name {
  font-family: "Cormorant Garamond", Georgia, serif;
  font-size: 26px; font-weight: 600; line-height: 1.15;
}
.deck-meta {
  font-size: 10.5px; letter-spacing: .18em; text-transform: uppercase;
  color: var(--ink-3); margin-top: 5px;
}
.deck-cap.swap .deck-name, .deck-cap.swap .deck-meta { animation: capIn .46s var(--ease) both; }
@keyframes capIn { from { opacity: 0; transform: translateY(7px); } to { opacity: 1; transform: none; } }

.deck-nav { display: flex; align-items: center; justify-content: center; gap: 16px; margin-top: 18px; }
.deck-arrow {
  width: 40px; height: 40px; border-radius: 50%; flex: none;
  border: 1px solid var(--line-2); background: none; cursor: pointer;
  display: grid; place-items: center; font-size: 17px; line-height: 1;
  transition: background .24s var(--ease-soft), color .24s var(--ease-soft),
              border-color .24s var(--ease-soft), transform .24s var(--ease);
}
.deck-arrow:hover { background: var(--ink); color: var(--ivory); border-color: var(--ink); transform: translateY(-2px); }
.deck-ticks { display: flex; gap: 7px; }
.deck-ticks button {
  width: 24px; height: 2px; border: 0; padding: 0; cursor: pointer;
  background: var(--line-2); border-radius: 2px;
  transition: background .3s var(--ease-soft), width .4s var(--ease);
}
.deck-ticks button.on { background: var(--ink); width: 40px; }

@media (min-width: 640px) {
  .deck-stage { height: 520px; }
  .deck-card  { width: 42%; max-width: 380px; }
  .deck-card.is-prev { transform: translateX(-118%) scale(.82); }
  .deck-card.is-next { transform: translateX(18%)   scale(.82); }
  .deck-name { font-size: 32px; }
}

/* ---------- the drop-in photo slot, used by the deck and the portrait ---------- */
.slot-drop {
  display: block; text-align: center; padding: 18px;
  font-size: 10.5px; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-3);
}
.slot-drop b {
  display: block; font-weight: 500; letter-spacing: .03em; text-transform: none;
  font-size: 13px; color: var(--accent); margin-bottom: 6px; word-break: break-all;
}

/* lightbox */
.lightbox {
  position: fixed; inset: 0; z-index: 120; background: rgba(23,20,15,.92);
  display: none; place-items: center; padding: 22px; cursor: zoom-out;
  animation: fade .3s var(--ease-soft);
}
.lightbox.open { display: grid; }
.lightbox img { max-width: 100%; max-height: 84vh; border-radius: var(--r-md); }
.lightbox-cap {
  color: var(--word); text-align: center; margin-top: 14px;
  font-size: 10.5px; letter-spacing: .18em; text-transform: uppercase;
}
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

/* ============================================================
   THE MENU
   ============================================================ */
.menu-list { margin-top: 24px; border-top: 1px solid var(--line); }
.menu-item {
  display: grid; grid-template-columns: 1fr auto; gap: 4px 18px;
  padding: 18px 0; border-bottom: 1px solid var(--line); align-items: baseline;
}
.menu-item h3 { font-size: 21px; }
.menu-price { font-family: "Cormorant Garamond", Georgia, serif; font-size: 21px; font-weight: 600; white-space: nowrap; }
.menu-price small { font-size: 11px; font-family: Jost, sans-serif; font-weight: 400; color: var(--ink-3); }
.menu-blurb { grid-column: 1 / -1; color: var(--ink-2); font-size: 14px; max-width: 62ch; margin: 0; }
.menu-time {
  grid-column: 1 / -1; font-size: 10.5px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-3); margin-top: 4px;
}

/* ============================================================
   CARDS, LISTS, EMPTY STATES
   ============================================================ */
.cards { display: grid; gap: 16px; margin-top: 24px; }
@media (min-width: 760px) { .cards-2 { grid-template-columns: 1fr 1fr; } }

.card {
  background: var(--cream); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 24px 22px;
  transition: transform .4s var(--ease), box-shadow .4s var(--ease);
}
.card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.card h3 { font-size: 25px; }
.pill {
  font-size: 9.5px; letter-spacing: .18em; text-transform: uppercase;
  border: 1px solid var(--line-2); border-radius: var(--r-full);
  padding: 4px 11px; color: var(--ink-3); white-space: nowrap;
}
.pill-solid { background: var(--ink); border-color: var(--ink); color: var(--ivory); }
.card-season {
  font-size: 10.5px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--accent); margin: 10px 0 2px;
}
.card-days { font-size: 13px; color: var(--ink-3); margin: 4px 0 16px; font-style: italic; }

.ticks { display: grid; gap: 11px; }
.ticks li { display: grid; grid-template-columns: 18px 1fr; gap: 10px; font-size: 14px; color: var(--ink-2); line-height: 1.5; }
.ticks li::before {
  content: ""; width: 7px; height: 12px; margin-top: 5px;
  border-right: 1.5px solid var(--accent); border-bottom: 1.5px solid var(--accent);
  transform: rotate(42deg);
}

/* what shows where Brook's words are not in yet */
.pending {
  border: 1px dashed var(--line-2); border-radius: var(--r-md);
  padding: 16px 18px; text-align: center;
  font-size: 12.5px; color: var(--ink-3); line-height: 1.5;
}
.pending b {
  display: block; font-weight: 500; font-size: 13px; color: var(--accent);
  letter-spacing: .04em; margin-bottom: 3px;
}

.fees { margin-top: 22px; border-top: 1px solid var(--line); }
.fee-row {
  display: grid; grid-template-columns: 1fr auto; gap: 2px 14px;
  padding: 15px 0; border-bottom: 1px solid var(--line); align-items: baseline;
}
.fee-row b { font-size: 15px; font-weight: 500; }
.fee-amt { font-family: "Cormorant Garamond", Georgia, serif; font-size: 20px; font-weight: 600; white-space: nowrap; }
.fee-amt.warn { color: #96442f; }
.fee-row p { grid-column: 1 / -1; margin: 2px 0 0; font-size: 13px; color: var(--ink-3); }

/* ============================================================
   STYLIST
   ============================================================ */
.stylist { display: grid; gap: 24px; align-items: center; }
@media (min-width: 760px) { .stylist { grid-template-columns: .85fr 1.15fr; gap: 40px; } }
/* 4:5 rather than square, and the crop is biased upwards. Phone
   portraits are tall with the face in the top third, so a square
   centre crop takes the chin and leaves the torso. */
.portrait {
  aspect-ratio: 4 / 5; border-radius: var(--r-lg);
  background: var(--cream) center 28% / cover no-repeat;
  border: 1px solid var(--line); display: grid; place-items: center;
  box-shadow: var(--shadow);
}
.stylist p + p { margin-top: 12px; }
.stylist .sig {
  font-family: "Herr Von Muellerhoff", Allura, cursive; font-size: 60px;
  color: var(--ink); margin-top: 12px; line-height: 1;
}

/* ============================================================
   FORMS
   ============================================================ */
.form { display: grid; gap: 16px; margin-top: 24px; }
@media (min-width: 640px) { .form-2 { grid-template-columns: 1fr 1fr; } }
.field { display: grid; gap: 6px; }
.field.wide { grid-column: 1 / -1; }
.field label { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-2); }
.req { color: var(--accent); }
.field input, .field textarea, .field select {
  width: 100%; padding: 12px 18px; font: inherit; font-size: 15px; color: var(--ink);
  background: var(--ivory); border: 1px solid var(--line-2); border-radius: var(--r-full);
  transition: border-color .22s var(--ease-soft), box-shadow .22s var(--ease-soft),
              background .22s var(--ease-soft);
}
/* a capsule with three lines of text in it looks wrong */
.field textarea { min-height: 110px; resize: vertical; border-radius: var(--r-md); }
.field select { appearance: none; cursor: pointer; }
.field input:focus, .field textarea:focus, .field select:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(138,116,88,.16);
}
.field small { font-size: 12px; color: var(--ink-3); }
.form-note { grid-column: 1 / -1; font-size: 12.5px; color: var(--ink-3); margin: 0; }
.form-note a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
.form-actions { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 12px; margin-top: 4px; }

.alert {
  border-radius: var(--r-md); padding: 13px 16px; font-size: 13.5px; line-height: 1.5;
  border: 1px solid var(--line-2); background: var(--cream); color: var(--ink-2);
  animation: capIn .34s var(--ease) both;
}
.alert-bad  { border-color: #d3a494; background: #f7e9e3; color: #7d3421; }
.alert-good { border-color: #a9bda0; background: #eaf1e5; color: #3d5730; }

/* ============================================================
   BOOKING FLOW
   ============================================================ */

/* the two ways in: book a set, or ask about something custom */
.modes {
  display: grid; grid-template-columns: 1fr 1fr; gap: 4px;
  background: var(--sand-2); border-radius: var(--r-full); padding: 4px; margin-top: 20px;
}
.modes button {
  border: 0; background: none; cursor: pointer; border-radius: var(--r-full);
  padding: 10px 12px; font-size: 11px; letter-spacing: .13em; text-transform: uppercase;
  color: var(--ink-2);
  transition: background .3s var(--ease), color .3s var(--ease-soft), box-shadow .3s var(--ease);
}
.modes button.on { background: var(--ivory); color: var(--ink); box-shadow: var(--shadow); }

.steps {
  display: flex; align-items: center; gap: 8px; margin: 22px 0 6px;
  font-size: 10px; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-3);
}
.steps span { display: flex; align-items: center; gap: 7px; white-space: nowrap; }
.steps b {
  width: 20px; height: 20px; border-radius: 50%; display: grid; place-items: center;
  border: 1px solid var(--line-2); font-size: 10px; font-weight: 500; letter-spacing: 0;
  transition: background .3s var(--ease-soft), color .3s var(--ease-soft), border-color .3s var(--ease-soft);
}
.steps .on { color: var(--ink); }
.steps .on b { background: var(--ink); border-color: var(--ink); color: var(--ivory); }
.steps i { flex: 1; height: 1px; background: var(--line); }
@media (max-width: 460px) { .steps span:not(.on) em { display: none; } .steps em { font-style: normal; } }

.panel { display: none; }
.panel.on { display: block; animation: rise .42s var(--ease) both; }
@keyframes rise { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }

/* pick tiles */
.picks { display: grid; gap: 10px; margin-top: 14px; }
@media (min-width: 640px) { .picks-2 { grid-template-columns: 1fr 1fr; } }

.pick {
  text-align: left; background: var(--cream); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 15px 17px; cursor: pointer; width: 100%;
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  transition: border-color .26s var(--ease-soft), background .26s var(--ease-soft),
              transform .26s var(--ease), box-shadow .26s var(--ease);
}
.pick:hover { border-color: var(--line-2); transform: translateY(-2px); }
.pick.on {
  border-color: var(--ink); background: var(--ivory); box-shadow: var(--shadow);
}
.pick-main b { display: block; font-size: 15.5px; font-weight: 500; }
.pick-main small { display: block; font-size: 12.5px; color: var(--ink-3); line-height: 1.45; margin-top: 2px; }
.pick-side { text-align: right; white-space: nowrap; }
.pick-side b { font-family: "Cormorant Garamond", Georgia, serif; font-size: 19px; font-weight: 600; }
.pick-side small { display: block; font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); }

/* the summary strip at the top of steps 2 and 3 */
.chosen {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  background: var(--cream); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 14px 17px; margin-top: 18px;
}
.chosen b { display: block; font-size: 15px; font-weight: 500; }
.chosen small { display: block; font-size: 12px; color: var(--ink-3); }

/* calendar */
.cal { margin-top: 20px; background: var(--cream); border: 1px solid var(--line); border-radius: var(--r-lg); padding: 16px; }
.cal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.cal-head b { font-family: "Cormorant Garamond", Georgia, serif; font-size: 21px; font-weight: 600; }
.cal-head button {
  width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--line-2);
  background: none; cursor: pointer; font-size: 17px; line-height: 1;
  transition: background .24s var(--ease-soft), color .24s var(--ease-soft), border-color .24s var(--ease-soft);
}
.cal-head button:hover:not(:disabled) { background: var(--ink); color: var(--ivory); border-color: var(--ink); }
.cal-head button:disabled { opacity: .28; cursor: not-allowed; }
.cal-dow { display: grid; grid-template-columns: repeat(7,1fr); gap: 4px; margin-bottom: 6px; }
.cal-dow span { text-align: center; font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); }
.cal-grid { display: grid; grid-template-columns: repeat(7,1fr); gap: 4px; }
.cal-grid button {
  aspect-ratio: 1; border: 1px solid transparent; background: none; border-radius: 50%;
  cursor: pointer; font-size: 13.5px; display: grid; place-items: center; position: relative;
  transition: background .22s var(--ease-soft), color .22s var(--ease-soft),
              border-color .22s var(--ease-soft), transform .22s var(--ease);
}
.cal-grid button.free:hover { border-color: var(--line-2); transform: scale(1.06); }
/* Both markers are black. The two locations are told apart by
   filled against hollow rather than by colour, so the calendar
   still works for a colour blind client and in a screenshot. */
.cal-grid button.free::after {
  content: ""; position: absolute; bottom: 5px; width: 5px; height: 5px;
  border-radius: 50%; background: var(--ink); box-sizing: border-box;
}
.cal-grid button.free.towson::after {
  background: transparent; border: 1.5px solid var(--ink);
}
.cal-grid button.off { color: var(--line-2); cursor: not-allowed; }
.cal-grid button.on { background: var(--ink); color: var(--ivory); border-color: var(--ink); }
.cal-grid button.on::after { background: var(--ivory); }
.cal-grid .blank { visibility: hidden; }
.cal-key { display: flex; gap: 18px; flex-wrap: wrap; margin-top: 14px; }
/* The legend has to use the same filled-or-hollow marker as the
   days above it, or it is explaining the wrong thing. */
.cal-key .loc-chip.towson i {
  background: transparent; border: 1.5px solid var(--ink); box-sizing: border-box;
}

/* The banner naming where the chosen day happens. Deliberately the
   loudest thing on the step: turning up at the wrong city is the
   one mistake this page has to make impossible. */
.where {
  display: flex; align-items: center; gap: 14px; margin-top: 18px;
  background: var(--ink); color: var(--ivory);
  border: 1px solid var(--ink);
  border-radius: var(--r-lg); padding: 16px 20px;
  animation: capIn .4s var(--ease) both;
}
.where .blip i, .where .blip u { background: var(--ivory); }
.where-label {
  display: block; font-size: 10px; letter-spacing: .2em; text-transform: uppercase;
  color: rgba(250, 247, 242, .72);
}
.where b { display: block; font-size: 18px; font-weight: 600; line-height: 1.25;
           font-family: "Cormorant Garamond", Georgia, serif; }
.where small { display: block; font-size: 12.5px; color: rgba(250, 247, 242, .78); }

.slots { margin-top: 20px; }
.slot-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(94px, 1fr)); gap: 8px; margin-top: 12px; }
.slot-grid button {
  padding: 11px 6px; border: 1px solid var(--line-2); background: var(--ivory);
  border-radius: var(--r-full); cursor: pointer; font-size: 13.5px;
  transition: background .22s var(--ease-soft), color .22s var(--ease-soft),
              border-color .22s var(--ease-soft), transform .22s var(--ease);
}
.slot-grid button:hover { border-color: var(--ink); transform: translateY(-2px); }
.slot-grid button.on { background: var(--ink); border-color: var(--ink); color: var(--ivory); }

/* deposit + confirm */
.breakdown { margin-top: 18px; border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; }
.breakdown div { display: flex; justify-content: space-between; gap: 14px; padding: 13px 17px; font-size: 14px; }
.breakdown div + div { border-top: 1px solid var(--line); }
.breakdown .now { background: var(--ink); color: var(--ivory); }
.breakdown .now b { font-family: "Cormorant Garamond", Georgia, serif; font-size: 20px; }
.breakdown .later, .breakdown .total { background: var(--cream); color: var(--ink-2); }
.breakdown .total { font-weight: 500; color: var(--ink); }

.pay { margin-top: 18px; background: var(--cream); border: 1px solid var(--line); border-radius: var(--r-lg); padding: 20px; }
.pay h4 { font-size: 19px; margin-bottom: 12px; }

/* the deposit amount leads the whole panel: biggest thing in it,
   nothing competes with it for attention */
.pay-hero { text-align: center; padding-bottom: 18px; border-bottom: 1px solid var(--line); }
.pay-amount {
  display: block; font-family: "Cormorant Garamond", Georgia, serif;
  font-size: 42px; font-weight: 600; line-height: 1.05; color: var(--ink);
}
.pay-sub { margin: 8px 0 0; font-size: 12.5px; color: var(--ink-3); }

.pay-methods { display: grid; gap: 10px; margin-top: 18px; }
.pay-method {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 10px 14px;
  background: var(--ivory); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 13px 16px;
  transition: border-color .24s var(--ease-soft), box-shadow .24s var(--ease-soft),
              transform .22s var(--ease);
}
.pay-method:hover  { border-color: var(--line-2); box-shadow: var(--shadow); transform: translateY(-1px); }
.pay-method:active { transform: translateY(0); box-shadow: none; }
.pay-method-info  { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pay-method-label {
  font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-3);
}
.pay-method-value { font-size: 16px; font-weight: 500; color: var(--ink); word-break: break-word; }
.pay-method-actions { display: flex; gap: 8px; flex-wrap: wrap; }

/* cash pays the balance only, never the deposit, so it is kept
   visually apart from the three rows above rather than styled as
   a fourth interchangeable method */
.pay-cash {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 6px 14px; margin-top: 12px; padding: 12px 16px;
  border: 1px dashed var(--line-2); border-radius: var(--r-md);
}
.pay-cash-label { font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); }
.pay-cash-note  { font-size: 12.5px; color: var(--ink-3); text-align: right; }

/* the copy-state kick: btn's own transitions (background, border,
   shadow, transform) carry this, no extra timing needed here */
.btn.is-copied {
  background: var(--accent-deep); border-color: var(--accent-deep);
  box-shadow: var(--shadow); transform: scale(1.04);
}

.paste { margin-top: 14px; background: var(--ivory); border: 1px dashed var(--line-2); border-radius: var(--r-sm); padding: 13px; }
.paste small { display: block; font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 7px; }
.paste code {
  display: block; font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 12.5px;
  line-height: 1.5; color: var(--ink); word-break: break-word; white-space: pre-wrap; margin-bottom: 11px;
}

.done-mark {
  width: 54px; height: 54px; margin: 0 auto 16px; border-radius: 50%;
  background: var(--ink); color: var(--ivory); display: grid; place-items: center; font-size: 22px;
  animation: pop .5s var(--ease) both;
}
@keyframes pop { from { opacity: 0; transform: scale(.7); } to { opacity: 1; transform: none; } }
.recap { margin-top: 18px; border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; text-align: left; }
.recap div { display: flex; justify-content: space-between; gap: 14px; padding: 12px 17px; font-size: 14px; background: var(--cream); }
.recap div + div { border-top: 1px solid var(--line); }
.recap dt { color: var(--ink-3); margin: 0; }
.recap dd { margin: 0; font-weight: 500; text-align: right; }

/* ============================================================
   CTA BLOCK
   ============================================================ */
.cta { text-align: center; padding: 56px 0; }
.cta .h2 { font-size: 34px; }

/* ============================================================
   ADMIN
   ============================================================ */
#gateError { margin-top: 14px; }
.admin-row {
  display: grid; grid-template-columns: 84px minmax(0, 1fr); gap: 10px 14px;
  align-items: center; padding: 14px 0; border-bottom: 1px solid var(--line);
}
.admin-row > b { font-size: 14px; font-weight: 500; }
.admin-where { display: flex; gap: 8px; flex-wrap: wrap; }
/* min-height 44px everywhere in this section: this page is run
   one-handed on a phone, often between clients. */
.admin-where button {
  border: 1px solid var(--line-2); background: var(--ivory); cursor: pointer;
  border-radius: var(--r-full); padding: 11px 16px; min-height: 44px; font-size: 12px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink);
  transition: background .24s var(--ease-soft), color .24s var(--ease-soft),
              border-color .24s var(--ease-soft), transform .2s var(--ease);
}
.admin-where button:hover { transform: translateY(-1px); border-color: var(--ink); }
.admin-where button.on { background: var(--ink); border-color: var(--ink); color: var(--ivory); }
.admin-times { grid-column: 2; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.admin-times input {
  padding: 11px 12px; font: inherit; font-size: 15px; border-radius: var(--r-sm);
  border: 1px solid var(--line-2); background: var(--ivory); color: var(--ink);
  min-width: 0; min-height: 44px; flex: 1 1 108px;
}
.admin-times span { font-size: 12px; color: var(--ink-3); flex: none; }

/* one hand, on a phone, between clients */
@media (max-width: 430px) {
  .admin-row   { grid-template-columns: 1fr; gap: 8px; }
  .admin-times { grid-column: 1; }
}

/* ---------- "Where I am right now": a manual override on top
   of everything else, so it gets its own bigger, plainer buttons
   rather than reusing the day-toggle look. ---------- */
.now-picker { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.now-picker button {
  flex: 1 1 150px; min-height: 48px; padding: 12px 16px;
  border: 1px solid var(--line-2); border-radius: var(--r-full);
  background: var(--ivory); color: var(--ink); cursor: pointer;
  font-size: 13px; font-weight: 500; text-align: center;
  transition: background .22s var(--ease-soft), color .22s var(--ease-soft),
              border-color .22s var(--ease-soft), transform .2s var(--ease);
}
.now-picker button:hover { transform: translateY(-1px); border-color: var(--ink); }
.now-picker button.on { background: var(--ink); border-color: var(--ink); color: var(--ivory); }

/* ---------- the live status banner: whether her changes have
   actually reached her clients, in words that can't be misread.
   Colour comes from the existing .alert-good / .alert-bad
   classes so it stays in step with the rest of the site. ---------- */
.live-banner b { font-size: 16px; }

/* ---------- seasons: the date ranges a location actually runs ---------- */
.season-row {
  display: grid; gap: 10px; padding: 14px; margin-top: 10px;
  background: var(--cream); border: 1px solid var(--line); border-radius: var(--r-md);
  transition: border-color .2s var(--ease-soft), background .2s var(--ease-soft);
}
.season-row.bad { border-color: #d3a494; background: #f7e9e3; }
.season-fields { display: grid; gap: 10px; grid-template-columns: 1fr 1fr; }
.season-fields label {
  display: grid; gap: 5px; font-size: 11px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-3);
}
.season-fields label.season-label-field { grid-column: 1 / -1; }
.season-fields input {
  width: 100%; padding: 11px 12px; font: inherit; font-size: 15px; min-height: 44px;
  border-radius: var(--r-sm); border: 1px solid var(--line-2);
  background: var(--ivory); color: var(--ink);
}
.season-warn { font-size: 12.5px; color: #7d3421; margin: 0; }
.season-row .btn { justify-self: start; }
@media (min-width: 520px) {
  .season-fields { grid-template-columns: 1fr 1fr 1.4fr; }
}

/* ============================================================
   MOTION
   ============================================================ */
.reveal { opacity: 0; transform: translateY(18px); }
.reveal.seen {
  opacity: 1; transform: none;
  transition: opacity .7s var(--ease-soft), transform .7s var(--ease);
}

/* ---------- the page arriving ----------
   One short sequence on load rather than effects scattered around.
   The lockup settles, then the status, then the buttons. */
.hero .lockup   { animation: heroRise .9s var(--ease) both; }
.hero-live      { animation: heroRise .9s var(--ease) .12s both; }
.hero-locations { animation: heroRise .9s var(--ease) .2s both; }
.hero .btn-row  { animation: heroRise .9s var(--ease) .28s both; }
.hero-fine      { animation: heroRise .9s var(--ease) .36s both; }
@keyframes heroRise { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }

/* the monogram fades up behind the signature a beat later */
.hero .lockup-mono { animation: monoIn 1.5s var(--ease-soft) .3s both; }
@keyframes monoIn { from { opacity: 0; transform: translate(-50%, -50%) scale(.94); }
                    to   { opacity: 1; transform: translate(-50%, -56%) scale(1); } }

/* ---------- rows that arrive one after another ----------
   .stagger-item is added by app.js, never written in the markup, so
   a row it never reaches stays visible rather than stuck hidden. */
.stagger-item { opacity: 0; transform: translateY(14px); }
.stagger-item.seen {
  opacity: 1; transform: none;
  transition: opacity .6s var(--ease-soft), transform .6s var(--ease);
}
li.stagger-item { transform: translateX(-8px); }

/* ---------- press feedback on anything tappable ---------- */
.pick:active, .slot-grid button:active, .cal-grid button:active,
.modes button:active, .deck-arrow:active { transform: scale(.97); }

/* the chosen tile gives a single confirming nudge */
.pick.on, .slot-grid button.on { animation: chosen .34s var(--ease); }
@keyframes chosen { 40% { transform: scale(1.025); } 100% { transform: none; } }

/* underline that draws itself under a section heading as it lands */
.section > .shell > .h2 { position: relative; display: inline-block; }
.section > .shell > .h2::after {
  content: ""; position: absolute; left: 0; bottom: -6px; height: 1px;
  width: 0; background: var(--accent); transition: width .8s var(--ease) .2s;
}
.section > .shell > .h2.seen::after { width: 100%; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-delay: 0ms !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
  .reveal, .menu-link, .stagger-item { opacity: 1; transform: none; }
  .section > .shell > .h2::after { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-delay: 0ms !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
  .reveal, .menu-link { opacity: 1; transform: none; }
}

@media (min-width: 640px) {
  .section { padding: 74px 0; }
  body { font-size: 15.5px; }
  .h1 { font-size: 52px; }
  .h2 { font-size: 38px; }
}

/* ============================================================
   THE FONT HOLD
   Herr Von Muellerhoff has no lookalike fallback, so swapping into
   it mid-load reads as a glitch on the one element people look at
   first. The inline script in each page's head adds .fonts-loading
   to <html> and removes it once the real face is decoded, or after
   1.5s if the request hangs. Only the logo waits: holding body
   copy back would be a worse trade than a subtle reflow.
   ============================================================ */
.lockup-script, .lockup-word, .lockup-mono {
  transition: opacity .4s var(--ease-soft);
}
.fonts-loading .lockup-script,
.fonts-loading .lockup-word,
.fonts-loading .lockup-mono { opacity: 0; }

/* ============================================================
   ADMIN: TABS AND BOOKINGS
   ============================================================ */

/* The tab bar reuses .modes, so it inherits the pill treatment.
   These only add what a three-way bar needs on a narrow phone. */
.admin-tabs { grid-template-columns: repeat(3, 1fr); }
.sub-tabs   { grid-template-columns: repeat(2, 1fr); }

.tab-count {
  display: inline-grid; place-items: center;
  min-width: 18px; height: 18px; padding: 0 5px; margin-left: 6px;
  border-radius: var(--r-full);
  background: var(--live); color: #06331a;
  font-size: 10px; font-weight: 600; letter-spacing: 0;
  vertical-align: middle;
  animation: countIn .38s var(--ease) both;
}
.tab-count:empty { display: none; }
@keyframes countIn {
  from { opacity: 0; transform: scale(.5); }
  to   { opacity: 1; transform: scale(1); }
}

/* A tab swap should feel like a change of view, not a repaint. */
.tabpanel { animation: tabIn .34s var(--ease) both; }
@keyframes tabIn {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

/* ---------- one request ---------- */
.req-card {
  background: var(--cream);
  border: 1px solid var(--line);
  border-left: 4px solid var(--line-2);
  border-radius: var(--r-lg);
  padding: 18px 20px;
  margin-top: 12px;
  animation: tabIn .4s var(--ease) both;
  transition: border-color .3s var(--ease-soft), box-shadow .3s var(--ease),
              transform .3s var(--ease);
}
.req-card:hover { box-shadow: var(--shadow); transform: translateY(-2px); }

/* The left edge carries the status, so a screenful of requests can
   be triaged without reading a word of any of them. */
.req-card.is-new       { border-left-color: var(--live); }
.req-card.is-confirmed { border-left-color: var(--towson); }
.req-card.is-done      { border-left-color: var(--line-2); opacity: .78; }
.req-card.is-declined  { border-left-color: var(--off); opacity: .68; }

.req-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
}
.req-head b {
  font-family: "Cormorant Garamond", Georgia, serif;
  font-size: 22px; font-weight: 600;
}
.req-head small { font-size: 11.5px; color: var(--ink-3); white-space: nowrap; }

.req-body { margin-top: 12px; }
.req-row {
  display: grid; grid-template-columns: 104px 1fr; gap: 4px 14px;
  padding: 7px 0; border-top: 1px solid var(--line);
  font-size: 14px; align-items: baseline;
}
.req-row:first-child { border-top: 0; }
.req-row span { font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-3); }
.req-row b { font-weight: 500; overflow-wrap: anywhere; }

.req-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }

.req-status {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line);
}
.status-pill {
  border: 1px solid var(--line-2); background: var(--ivory); cursor: pointer;
  border-radius: var(--r-full); padding: 7px 14px;
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-2);
  transition: background .24s var(--ease-soft), color .24s var(--ease-soft),
              border-color .24s var(--ease-soft), transform .18s var(--ease);
}
.status-pill:hover:not(:disabled) { border-color: var(--ink); transform: translateY(-2px); }
.status-pill:active:not(:disabled) { transform: translateY(0) scale(.97); }
.status-pill:disabled { opacity: .5; cursor: wait; }
.status-pill.on { background: var(--ink); border-color: var(--ink); color: var(--ivory); }

@media (min-width: 640px) {
  .req-row { grid-template-columns: 130px 1fr; }
}

/* ============================================================
   THE BUTTON PASS
   Nothing that can be pressed should sit still when you touch it.
   These rules are deliberately last so they win over anything
   above that forgot a state.
   ============================================================ */

/* One visible focus ring for keyboard users, on every control. */
.btn:focus-visible,
.pick:focus-visible,
.status-pill:focus-visible,
.modes button:focus-visible,
.deck-arrow:focus-visible,
.cal-grid button:focus-visible,
.slot-grid button:focus-visible,
.admin-where button:focus-visible,
.burger:focus-visible,
.ig-btn:focus-visible,
.deck-ticks button:focus-visible,
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* Every pressable thing acknowledges the press. Phones have no
   hover, so without this half the site feels dead to the touch. */
.btn:active:not(:disabled),
.pick:active,
.modes button:active,
.deck-arrow:active,
.slot-grid button:active,
.cal-grid button.free:active,
.admin-where button:active,
.ig-btn:active {
  transform: scale(.97);
}

/* A light sweeps across a primary button on hover. It is the one
   flourish on the site, so it is reserved for the button that
   actually matters: the one that books. */
.btn-primary {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}
.btn-primary::after {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(115deg, transparent 30%,
              rgba(255, 255, 255, .22) 50%, transparent 70%);
  transform: translateX(-120%);
  transition: transform .7s var(--ease);
}
.btn-primary:hover:not(:disabled)::after { transform: translateX(120%); }

@media (prefers-reduced-motion: reduce) {
  .tabpanel, .req-card, .tab-count { animation: none; }
  .btn-primary::after { display: none; }
}

/* ============================================================
   THEMES

   Six curated palettes. Brook picks one in the dashboard and
   app.js sets data-theme on <html>.

   Every preset redefines the WHOLE token set rather than
   inheriting some of it, because a half-applied palette is worse
   than the wrong one: light lines on a dark ground disappear.
   --veil is the frosted surface behind the nav and the dock,
   which is why those two are not allowed a hardcoded rgba.
   ============================================================ */

:root,
:root[data-theme="sand"] {
  --sand: #e7dfd4; --sand-2: #ded4c7; --cream: #f3eee6; --ivory: #faf7f2;
  --mono: #f6f1e8; --word: #f7f3ec;
  --ink: #17140f; --ink-2: #241f18; --ink-3: #2f2820;
  --line: #cdc0ae; --line-2: #b8a893;
  --accent: #6b563c; --accent-deep: #4b3c28;
  --towson: #2d4a50; --live: #22c55e; --off: #9a3b2c;
  --veil: rgba(243, 238, 230, .82); --veil-strong: rgba(243, 238, 230, .94);
}

:root[data-theme="blush"] {
  --sand: #f7eeea; --sand-2: #efe0da; --cream: #fbf4f1; --ivory: #fffbf9;
  --mono: #fbf0eb; --word: #fdf7f4;
  --ink: #241a17; --ink-2: #33251f; --ink-3: #43312a;
  --line: #e0cec6; --line-2: #cbb2a8;
  --accent: #a8574a; --accent-deep: #7d3d33;
  --towson: #5a6b74; --live: #1faa55; --off: #a33b28;
  --veil: rgba(251, 244, 241, .84); --veil-strong: rgba(251, 244, 241, .95);
}

:root[data-theme="powder"] {
  --sand: #f3eef2; --sand-2: #e8dfe8; --cream: #faf6f9; --ivory: #fffdfe;
  --mono: #f7f0f6; --word: #fbf6fa;
  --ink: #2c2230; --ink-2: #3b2f40; --ink-3: #4b3d50;
  --line: #ddcfdb; --line-2: #c5b0c4;
  --accent: #8e6494; --accent-deep: #6a4570;
  --towson: #4a6470; --live: #1faa55; --off: #a33b28;
  --veil: rgba(250, 246, 249, .84); --veil-strong: rgba(250, 246, 249, .95);
}

:root[data-theme="sage"] {
  --sand: #f1f4ef; --sand-2: #e2e8de; --cream: #f8faf6; --ivory: #fdfefc;
  --mono: #f4f7f2; --word: #f9fbf8;
  --ink: #1e2620; --ink-2: #2b352c; --ink-3: #3a4539;
  --line: #d2dccd; --line-2: #b6c4b1;
  --accent: #4d6a4f; --accent-deep: #35492f;
  --towson: #4a6470; --live: #1faa55; --off: #a33b28;
  --veil: rgba(248, 250, 246, .84); --veil-strong: rgba(248, 250, 246, .95);
}

:root[data-theme="mocha"] {
  --sand: #efe6da; --sand-2: #e3d6c5; --cream: #f7f1e8; --ivory: #fdfaf5;
  --mono: #f3ebe0; --word: #f8f3ea;
  --ink: #2a1c14; --ink-2: #3a2820; --ink-3: #4a362c;
  --line: #d8c6b0; --line-2: #c0a888;
  --accent: #6b4226; --accent-deep: #4a2c18;
  --towson: #3f5d63; --live: #1faa55; --off: #a33b28;
  --veil: rgba(247, 241, 232, .84); --veil-strong: rgba(247, 241, 232, .95);
}

/* The one dark preset. --ink and --ivory swap roles, which is why
   every component reads from tokens instead of naming a colour:
   .btn-primary becomes light-on-dark here for free. */
:root[data-theme="ink"] {
  --sand: #141210; --sand-2: #1e1a17; --cream: #221e1a; --ivory: #2b2622;
  --mono: #241f18; --word: #4a3f2c;
  --ink: #f5f0e6; --ink-2: #e6dfd2; --ink-3: #cfc6b6;
  --line: #3a332b; --line-2: #52483c;
  --accent: #c9a24b; --accent-deep: #e2bb64;
  --towson: #7fa8b0; --live: #34d399; --off: #e0745c;
  --veil: rgba(30, 26, 23, .82); --veil-strong: rgba(30, 26, 23, .94);
}

/* the frosted surfaces follow the theme */
.nav { background: var(--veil); }
.site-header.scrolled .nav { background: var(--veil-strong); }
.dock { background: var(--veil-strong); }

/* ============================================================
   HEADER MARK
   The full signature is hairline and pale, which is exactly why
   it never read at nav size. Just the monogram, in ink, so it is
   actually legible. It arrives once the hero logo has scrolled
   away, so the two are never on screen competing.
   ============================================================ */
.nav-mark {
  display: grid; place-items: center;
  flex: none; padding: 0 4px;
  opacity: 0; transform: translateY(-6px) scale(.86);
  pointer-events: none;
  transition: opacity .45s var(--ease-soft), transform .55s var(--ease);
}
.site-header.scrolled .nav-mark {
  opacity: 1; transform: none; pointer-events: auto;
}
.nav-mark-bp {
  font-family: "Cormorant Garamond", Georgia, serif;
  font-weight: 600; font-size: 26px; line-height: 1;
  letter-spacing: -0.07em; color: var(--ink);
  transition: color .24s var(--ease-soft), transform .3s var(--ease);
}
.nav-mark:hover .nav-mark-bp { color: var(--accent); transform: scale(1.06); }
.nav-mark:active .nav-mark-bp { transform: scale(.96); }

/* Mobile: the mark sits between Instagram and the menu button, so
   those two have to become siblings of it rather than a group. */
@media (max-width: 899px) {
  .nav-right { display: contents; }
  .ig-btn   { order: 1; }
  .nav-mark { order: 2; }
  .burger   { order: 3; }
  /* Instagram is the one outbound link on the page, so it earns
     a bigger tap target than an icon button normally would. */
  .ig-btn { width: 42px; height: 42px; }
  .ig-btn svg { width: 20px; height: 20px; }
}
@media (min-width: 900px) {
  .nav-mark { order: 0; margin-right: 4px; }
}

/* ============================================================
   LIVE STATUS
   Two rows on one card: where she is now, and where she is next.
   The pulse is reserved for genuinely being in a chair - a dot
   that always blinks stops meaning anything.
   ============================================================ */
.status {
  display: inline-grid; gap: 2px;
  text-align: left; margin: 22px auto 0;
  padding: 12px 20px 12px 16px;
  background: var(--cream);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
  animation: statusIn .6s var(--ease) both;
}
@keyframes statusIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

.status-row {
  display: grid;
  grid-template-columns: 14px auto 1fr;
  align-items: baseline; gap: 4px 9px;
}
.status-row + .status-row { margin-top: 7px; padding-top: 7px; border-top: 1px solid var(--line); }

.status-label {
  font-size: 9.5px; letter-spacing: .2em; text-transform: uppercase;
  color: var(--ink-3); white-space: nowrap;
}
.status-place {
  font-family: "Cormorant Garamond", Georgia, serif;
  font-size: 19px; font-weight: 600; line-height: 1.1; white-space: nowrap;
}
.status-meta {
  grid-column: 2 / -1;
  font-size: 12px; color: var(--ink-3); line-height: 1.3;
}
.status-row.is-next .status-place { font-size: 16px; }

/* The blip and its quiet twin. Scoped to .status so these cannot
   reach the older markup elsewhere, where an always-green pulse
   would claim she is working when she is not. */
.status .blip, .status .status-dot { grid-row: span 2; align-self: center; }
.status .blip { position: relative; width: 10px; height: 10px; }
.status .blip i, .status .blip u {
  position: absolute; inset: 0; border-radius: 50%; display: block;
  background: var(--live);
}
.status .blip u { opacity: .5; animation: blipRing 1.8s var(--ease-soft) infinite; }
.status .blip i { transform: scale(.72); animation: blipCore 1.8s var(--ease-soft) infinite; }
@keyframes blipRing {
  0%   { transform: scale(.72); opacity: .5; }
  70%  { transform: scale(2.3); opacity: 0; }
  100% { transform: scale(2.3); opacity: 0; }
}
@keyframes blipCore { 0%, 100% { transform: scale(.72); } 50% { transform: scale(.9); } }

.status-dot {
  width: 10px; height: 10px; border-radius: 50%;
  border: 1.5px solid var(--line-2); background: none;
}

@media (prefers-reduced-motion: reduce) {
  .status .blip u { animation: none; opacity: .3; transform: scale(1.6); }
  .status .blip i { animation: none; }
  .status { animation: none; }
}

/* ============================================================
   TIME PILL
   ============================================================ */
.pill-time {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 11px 4px 9px;
  border-radius: var(--r-full);
  background: var(--sand-2);
  font-size: 11.5px; font-weight: 500; letter-spacing: .01em;
  color: var(--ink-2); white-space: nowrap; vertical-align: middle;
}
.pill-time .ico {
  width: 13px; height: 13px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 1.9;
  stroke-linecap: round; stroke-linejoin: round;
  opacity: .75;
}
.pick.on .pill-time { background: var(--ivory); }

/* ============================================================
   PAYMENT METHODS
   Brand-coloured tiles rather than the official marks: a coloured
   capsule reads instantly and does not reproduce a trademark.
   ============================================================ */
.pay-method {
  display: grid;
  grid-template-columns: 40px 1fr;
  gap: 4px 13px; align-items: center;
  padding: 14px 16px;
  background: var(--ivory);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  transition: border-color .26s var(--ease-soft), transform .26s var(--ease),
              box-shadow .26s var(--ease);
}
.pay-method + .pay-method { margin-top: 10px; }
.pay-method:hover { border-color: var(--line-2); transform: translateY(-2px); box-shadow: var(--shadow); }

.pay-logo {
  width: 40px; height: 40px; border-radius: 12px;
  display: grid; place-items: center;
  font-weight: 700; font-size: 18px; line-height: 1;
  color: #fff; letter-spacing: -.02em;
}
.pay-method[data-brand="cashapp"]  .pay-logo { background: #00d54b; color: #04331a; }
.pay-method[data-brand="zelle"]    .pay-logo { background: #6d1ed4; }
.pay-method[data-brand="applepay"] .pay-logo { background: #111; font-size: 13px; letter-spacing: -.03em; }
.pay-method[data-brand="cash"]     .pay-logo { background: var(--accent); }

.pay-method-info { display: grid; gap: 1px; min-width: 0; }
.pay-method-label {
  font-size: 10px; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-3);
}
.pay-method-value {
  font-size: 16px; font-weight: 500; overflow-wrap: anywhere;
}
.pay-method-actions {
  grid-column: 2; display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px;
}
.pay-method .small-note { grid-column: 2; margin-top: 6px; }

/* the deposit headline */
.pay-hero { text-align: center; padding: 4px 0 18px; }
.pay-amount {
  display: block;
  font-family: "Cormorant Garamond", Georgia, serif;
  font-size: 44px; font-weight: 600; line-height: 1; color: var(--ink);
}
.pay-sub { margin: 8px auto 0; font-size: 13.5px; color: var(--ink-2); max-width: 34ch; }

/* cash is the balance, never the deposit, so it is set apart */
.pay-cash {
  display: grid; grid-template-columns: 40px 1fr; gap: 13px; align-items: center;
  margin-top: 14px; padding: 13px 16px;
  border: 1px dashed var(--line-2); border-radius: var(--r-md);
}
.pay-cash-label { font-size: 10px; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-3); }
.pay-cash-note  { font-size: 13.5px; color: var(--ink-2); }
.pay-cash > div { display: grid; gap: 1px; }

.btn.is-copied { background: var(--accent-deep); border-color: var(--accent-deep); color: var(--ivory); }

/* ============================================================
   READ BEFORE YOU BOOK
   Loud enough that skipping it is a choice, quiet enough that it
   is one tap out of the way.
   ============================================================ */
.readfirst {
  margin-top: 20px;
  background: var(--cream);
  border: 1px solid var(--line-2);
  border-left: 4px solid var(--accent);
  border-radius: var(--r-lg);
  padding: 16px 18px;
  animation: statusIn .5s var(--ease) both;
}
.readfirst-head { display: flex; align-items: center; gap: 13px; flex-wrap: wrap; }
.readfirst-head > div { flex: 1 1 200px; min-width: 0; }
.readfirst-head > div > b { display: block; font-size: 15.5px; font-weight: 600; }
/* Scoped to the text column. A bare "span" here also matched the
   round mark, overriding its size and turning off the grid that
   centres the glyph, which is why the mark sat high and left. */
.readfirst-head > div > span { display: block; font-size: 13px; color: var(--ink-3); }
.readfirst-mark {
  width: 28px; height: 28px; flex: none; border-radius: 50%;
  background: var(--accent); color: var(--ivory);
  display: grid; place-items: center; font-weight: 700; font-size: 15px;
}
.readfirst-body { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); }
.readfirst-body .ticks li { font-size: 13.5px; }

/* the acknowledgement, deliberately in the way of the button */
.ack {
  grid-column: 1 / -1;
  display: grid; grid-template-columns: 22px 1fr; gap: 11px; align-items: start;
  padding: 14px 16px; margin-top: 4px;
  background: var(--cream); border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  font-size: 13.5px; line-height: 1.5; cursor: pointer;
  transition: border-color .26s var(--ease-soft), background .26s var(--ease-soft);
}
.ack:hover { border-color: var(--ink-3); }
.ack input { width: 20px; height: 20px; accent-color: var(--ink); cursor: pointer; margin: 0; }
.ack a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
.ack:has(input:checked) { border-color: var(--live); background: var(--ivory); }

/* ============================================================
   CUSTOM SECTIONS
   ============================================================ */
.custom-body p { margin: 0 0 12px; color: var(--ink-2); font-size: 15px; max-width: 62ch; }
.custom-body p:last-child { margin-bottom: 0; }

/* ============================================================
   ADMIN: the availability preview, the swatches, the photo slots
   ============================================================ */
.admin-cal { margin-top: 18px; }
.admin-cal .cal-grid button { cursor: default; }
.admin-cal .cal-grid button.free:hover { transform: none; border-color: transparent; }

.where-hint {
  display: block; margin-top: 4px;
  font-size: 11.5px; line-height: 1.4; color: var(--ink-3); font-style: italic;
}

/* theme swatches */
.swatches { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-top: 16px; }
@media (min-width: 640px) { .swatches { grid-template-columns: repeat(3, 1fr); } }
.swatch {
  border: 2px solid var(--line); background: var(--ivory); cursor: pointer;
  border-radius: var(--r-md); padding: 0; overflow: hidden; text-align: left;
  transition: border-color .24s var(--ease-soft), transform .24s var(--ease),
              box-shadow .24s var(--ease);
}
.swatch:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
.swatch.on { border-color: var(--ink); box-shadow: var(--lift); }
.swatch-strip { display: flex; height: 46px; }
.swatch-strip span { flex: 1; }
.swatch-name {
  display: block; padding: 9px 12px;
  font-size: 12px; letter-spacing: .04em; color: var(--ink-2);
}
.swatch.on .swatch-name { font-weight: 600; color: var(--ink); }

/* photo slots */
.photo-slot {
  display: grid; grid-template-columns: 92px 1fr; gap: 14px;
  padding: 14px 0; border-top: 1px solid var(--line); align-items: start;
}
.photo-thumb {
  width: 92px; aspect-ratio: 4 / 5; border-radius: var(--r-sm);
  background: var(--sand-2) center / cover no-repeat;
  border: 1px solid var(--line); display: grid; place-items: center;
  font-size: 10px; color: var(--ink-3); text-align: center;
}
.photo-fields { display: grid; gap: 8px; min-width: 0; }
.photo-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.photo-actions input[type="file"] { display: none; }

/* a list row she can reorder or delete */
.edit-row {
  display: grid; grid-template-columns: 1fr auto; gap: 10px;
  padding: 12px 0; border-top: 1px solid var(--line); align-items: start;
}
.edit-row-fields { display: grid; gap: 8px; min-width: 0; }
.edit-row-tools { display: flex; gap: 6px; align-items: center; }
.icon-btn {
  width: 34px; height: 34px; border-radius: 50%; flex: none;
  border: 1px solid var(--line-2); background: var(--ivory); cursor: pointer;
  display: grid; place-items: center; font-size: 15px; line-height: 1; color: var(--ink-2);
  transition: background .22s var(--ease-soft), color .22s var(--ease-soft),
              border-color .22s var(--ease-soft), transform .2s var(--ease);
}
.icon-btn:hover:not(:disabled) { background: var(--ink); color: var(--ivory); border-color: var(--ink); transform: translateY(-2px); }
.icon-btn:active:not(:disabled) { transform: scale(.94); }
.icon-btn:disabled { opacity: .3; cursor: not-allowed; }
.icon-btn.danger:hover { background: var(--off); border-color: var(--off); color: #fff; }

/* a toggle switch for showing and hiding a section */
.switch { display: flex; align-items: center; gap: 11px; cursor: pointer; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch-track {
  width: 46px; height: 27px; border-radius: var(--r-full); flex: none;
  background: var(--line-2); position: relative;
  transition: background .26s var(--ease-soft);
}
.switch-track::after {
  content: ""; position: absolute; top: 3px; left: 3px;
  width: 21px; height: 21px; border-radius: 50%; background: var(--ivory);
  transition: transform .3s var(--ease);
}
.switch input:checked + .switch-track { background: var(--live); }
.switch input:checked + .switch-track::after { transform: translateX(19px); }
.switch input:focus-visible + .switch-track { outline: 2px solid var(--accent); outline-offset: 3px; }

@media (min-width: 640px) {
  .pay-amount { font-size: 54px; }
}

/* ============================================================
   THE FLOATING BOOK BUTTON

   Was a full width bar with a label beside the button. The label
   only ever repeated what the button said, so the bar is gone and
   what is left is the button itself, floating.
   ============================================================ */
.dock-fab {
  position: fixed; z-index: 70;
  left: 50%; transform: translateX(-50%);
  bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  display: grid; justify-items: center; gap: 1px;
  padding: 12px 30px;
  border-radius: var(--r-full);
  background: var(--ink); color: var(--ivory);
  box-shadow: 0 18px 40px -16px rgba(20, 14, 6, .65);
  text-align: center;
  transition: transform .3s var(--ease), box-shadow .3s var(--ease),
              background .24s var(--ease-soft);
  animation: fabIn .55s var(--ease) both;
}
.dock-fab:hover {
  background: var(--accent-deep);
  transform: translateX(-50%) translateY(-3px);
  box-shadow: 0 26px 52px -18px rgba(20, 14, 6, .72);
}
.dock-fab:active { transform: translateX(-50%) scale(.97); }
.dock-fab:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.dock-fab-main {
  font-size: 12px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase;
}
.dock-fab-sub { font-size: 10.5px; opacity: .68; letter-spacing: .04em; }
@keyframes fabIn {
  from { opacity: 0; transform: translateX(-50%) translateY(14px); }
  to   { opacity: 1; transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) { .dock-fab { animation: none; } }

/* The bar is gone, so the page no longer reserves a bar's height.
   Just enough room that the floating button never sits on top of
   the last line of the page. */
body { padding-bottom: 96px; }

/* ============================================================
   READ THIS FIRST, always open

   It used to fold shut behind a "Read it" button. Something a
   client must not miss should not be one tap away from never
   being seen, so it is simply always open now.
   ============================================================ */
.readfirst-body { display: block; }

/* The glyph is a single "!", whose line box carries descender
   space the character itself never uses, so centring the box left
   the mark visibly high. Setting the line height to the box and
   nudging by a hair centres the ink rather than the line box. */
.readfirst-mark {
  line-height: 1;
  font-size: 16px;
  /* "!" draws from cap height to baseline and never touches the
     descender space its line box still reserves, so a centred box
     leaves the ink sitting high. Padding at the top pushes the
     glyph down until the ink, not the box, looks centred. */
  padding-top: 3px;
}

/* ============================================================
   ATTACHMENTS
   A link box asked the client to host a photo somewhere first,
   which almost nobody can do from a phone. This is a file picker
   with the chosen photos listed under it.
   ============================================================ */
.attach { display: grid; gap: 9px; justify-items: start; }
.attach-hint { font-size: 12px; color: var(--ink-3); line-height: 1.45; }
.attach-list { display: grid; gap: 6px; width: 100%; }
.attach-list li {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px;
  background: var(--ivory); border: 1px solid var(--line);
  border-radius: var(--r-sm); font-size: 13.5px;
  animation: capIn .3s var(--ease) both;
}
.attach-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.attach-size { flex: none; font-size: 11.5px; color: var(--ink-3); }
.attach-remove {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  border: 1px solid var(--line-2); background: none; cursor: pointer;
  font-size: 16px; line-height: 1; color: var(--ink-2);
  display: grid; place-items: center; padding: 0;
  transition: background .2s var(--ease-soft), color .2s var(--ease-soft),
              border-color .2s var(--ease-soft), transform .18s var(--ease);
}
.attach-remove:hover { background: var(--off); border-color: var(--off); color: #fff; }
.attach-remove:active { transform: scale(.92); }
.attach-problem {
  border-color: var(--off); color: var(--off);
  background: var(--cream); font-size: 12.5px; display: block;
}
