/* ==========================================================================
   Handled — base, layout and components
   ========================================================================== */

/* ---- Reset ------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

body {
  background: var(--surface);
  color: var(--text-primary);
  font: var(--weight-normal) var(--text-base)/var(--leading-normal) var(--font-body);
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
}

img, svg, video { display: block; max-width: 100%; }
img { height: auto; }
input, button, textarea, select { font: inherit; color: inherit; }
button { background: none; border: 0; padding: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; padding: 0; }
[hidden] { display: none !important; }

:focus-visible {
  outline: var(--border-width-thick) solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* ---- Typography -------------------------------------------------------- */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  letter-spacing: -.01em;
  text-wrap: balance;
}
h1 { font-size: var(--text-5xl); line-height: var(--leading-tight); letter-spacing: -.02em; }
h2 { font-size: var(--text-4xl); line-height: 1.15; }
h3 { font-size: var(--text-xl);  line-height: var(--leading-snug); }
h4 { font-size: var(--text-lg);  line-height: var(--leading-snug); }
p  { text-wrap: pretty; }

.eyebrow {
  font: var(--weight-bold) var(--text-xs)/1.4 var(--font-body);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--action-on-tint);
}
.lede {
  font-size: var(--text-lg);
  line-height: var(--leading-loose);
  color: var(--text-secondary);
  max-width: var(--measure);
}
.muted { color: var(--text-tertiary); }
.small { font-size: var(--text-sm); }
.center { text-align: center; }

@media (max-width: 700px) {
  /* Large elements shrink faster than small ones. */
  h1 { font-size: var(--text-4xl); }
  h2 { font-size: var(--text-3xl); }
  h3 { font-size: var(--text-lg); }
  .lede { font-size: var(--text-base); }
}

/* ---- Layout ------------------------------------------------------------ */
.wrap { width: 100%; max-width: 1180px; margin-inline: auto; padding-inline: var(--space-5); }
.wrap-narrow { max-width: 780px; }

.section { padding-block: var(--space-9); }
.section-sm { padding-block: var(--space-8); }
.section-tint { background: var(--surface-sunken); }
.section-head { max-width: 640px; margin-bottom: var(--space-7); }
.section-head.center { margin-inline: auto; }
.section-head > * + * { margin-top: var(--space-3); }

.grid { display: grid; gap: var(--space-5); }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
.stack > * + * { margin-top: var(--space-4); }

/* ---- Nothing drags the page sideways -----------------------------------
   One element wider than the screen makes a phone zoom out to fit it, and
   every other element then looks narrow and off-centre -- which is what a
   stretched-off mobile page actually is. clip rather than hidden: hidden
   would make the body a scroll container and break position: sticky on the
   header. Rows that are meant to scroll sideways still do, because they
   carry their own overflow-x. */
html, body { max-width: 100%; overflow-x: clip; }


.stack-lg > * + * { margin-top: var(--space-6); }
.row { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; }

@media (max-width: 940px) {
  .grid-4 { grid-template-columns: repeat(2, 1fr); }
  .grid-3 { grid-template-columns: repeat(2, 1fr); }
  .section { padding-block: var(--space-8); }
}
@media (max-width: 620px) {
  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
}

.skip-link {
  position: absolute; left: var(--space-4); top: -100px; z-index: 100;
  background: var(--action); color: var(--action-text);
  padding: var(--space-3) var(--space-4); border-radius: var(--radius-sm);
  font-weight: var(--weight-bold);
}
.skip-link:focus { top: var(--space-3); }

/* ---- Buttons ----------------------------------------------------------- */
.btn {
  --btn-py: var(--space-3);
  --btn-px: var(--space-5);
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  padding: var(--btn-py) var(--btn-px);
  border-radius: var(--radius-full);
  font-weight: var(--weight-bold);
  font-size: var(--text-base);
  line-height: 1.4;
  text-align: center;
  border: var(--border-width) solid transparent;
  transition: background-color .18s var(--ease), border-color .18s var(--ease),
              color .18s var(--ease), box-shadow .18s var(--ease), transform .12s var(--ease);
  white-space: nowrap;
}
.btn:active { transform: translateY(1px); }
.btn svg { width: 18px; height: 18px; flex: none; }

.btn-primary { background: var(--action); color: var(--action-text); box-shadow: var(--shadow-1); }
.btn-primary:hover { background: var(--action-hover); box-shadow: var(--shadow-2); }
.btn-primary:active { box-shadow: none; }

.btn-secondary { background: var(--surface-raised); color: var(--text-primary); border-color: var(--border-strong); }
.btn-secondary:hover { background: var(--surface-sunken); border-color: var(--text-tertiary); }

.btn-ghost { color: var(--text-secondary); padding-inline: var(--space-3); }
.btn-ghost:hover { background: var(--surface-sunken); color: var(--text-primary); }

.btn-link { color: var(--action-on-tint); font-weight: var(--weight-bold); padding: 0; border-radius: var(--radius-sm); }
.btn-link:hover { text-decoration: underline; text-underline-offset: 3px; }

.btn-sm { --btn-py: var(--space-2); --btn-px: var(--space-4); font-size: var(--text-sm); }
.btn-lg { --btn-py: var(--space-4); --btn-px: var(--space-6); font-size: var(--text-lg); }
.btn-block { width: 100%; }
.btn[disabled] { opacity: var(--opacity-4); pointer-events: none; }

@media (max-width: 700px) {
  /* Padding tightens as the button shrinks — it does not scale with the text. */
  .btn-lg { --btn-py: var(--space-3); --btn-px: var(--space-5); font-size: var(--text-base); }
}

/* ---- Forms ------------------------------------------------------------- */
.field { display: block; }
.field > .label {
  display: block;
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--text-secondary);
  margin-bottom: var(--space-2);
}
.input, .select, .textarea {
  width: 100%;
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: var(--space-3) var(--space-4);
  color: var(--text-primary);
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.textarea { min-height: 128px; resize: vertical; line-height: var(--leading-normal); }
.input::placeholder, .textarea::placeholder { color: var(--text-tertiary); }
.input:hover, .select:hover, .textarea:hover { border-color: var(--text-tertiary); }
.input:focus, .select:focus, .textarea:focus {
  outline: none;
  border-color: var(--focus-ring);
  box-shadow: 0 0 0 3px var(--action-tint);
}
.select {
  appearance: none;
  padding-right: var(--space-8);
  background-image: var(--chevron);
  background-repeat: no-repeat;
  background-position: right var(--space-4) center;
  cursor: pointer;
}
.help { font-size: var(--text-sm); color: var(--text-tertiary); margin-top: var(--space-2); }

.check { display: flex; align-items: flex-start; gap: var(--space-3); cursor: pointer; padding: var(--space-1) 0; }
.check input {
  accent-color: var(--action);
  width: 18px; height: 18px; margin-top: 2px; flex: none; cursor: pointer;
}
.check span { font-size: var(--text-sm); color: var(--text-secondary); }
.check:hover span { color: var(--text-primary); }

.form-note { font-size: var(--text-sm); color: var(--text-tertiary); }
.form-status {
  border-radius: var(--radius-sm);
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  background: var(--accent-tint);
  color: var(--accent-on-tint);
  display: flex; align-items: flex-start; gap: var(--space-2);
}
.form-status svg { width: 18px; height: 18px; flex: none; margin-top: 1px; fill: none; stroke: currentColor; stroke-width: 2.25; stroke-linecap: round; stroke-linejoin: round; }
.form-status.is-error { background: var(--red-100); color: var(--red-800); }

/* ---- Badges & pills ---------------------------------------------------- */
.badge {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: .02em;
  background: var(--surface-sunken);
  color: var(--text-secondary);
}
.badge svg { width: 13px; height: 13px; flex: none; }
.badge-accent { background: var(--accent-tint); color: var(--accent-on-tint); }
.badge-action { background: var(--action-tint); color: var(--action-on-tint); }
.badge-gold   { background: var(--gold-100);   color: var(--gold-800); }

.pill-nav { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.pill {
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-full);
  border: var(--border-width) solid var(--border-strong);
  background: var(--surface-raised);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-secondary);
  transition: background-color .18s var(--ease), border-color .18s var(--ease), color .18s var(--ease);
}
.pill:hover { border-color: var(--text-tertiary); color: var(--text-primary); }
.pill[aria-pressed="true"], .pill.is-active {
  background: var(--action); border-color: var(--action); color: var(--action-text);
}

/* ---- Cards ------------------------------------------------------------- */
.card {
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-5);
}
.card-lg { border-radius: var(--radius-lg); padding: var(--space-6); }
@media (max-width: 620px) { .card-lg { padding: var(--space-5); } }

/* ---- Header ------------------------------------------------------------ */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: var(--surface);
  border-bottom: var(--border-width) solid var(--border);
}
@supports (backdrop-filter: blur(1px)) {
  .site-header { background: hsl(from var(--surface) h s l / .86); backdrop-filter: blur(12px); }
}

.header-inner {
  height: var(--header-height);
  display: flex; align-items: center; gap: var(--space-6);
}
.logo { display: inline-flex; align-items: center; gap: var(--space-3); flex: none; }
.logo-mark {
  width: 34px; height: 34px; border-radius: var(--radius-sm);
  background: var(--action); color: var(--action-text);
  display: grid; place-items: center; flex: none;
  box-shadow: var(--shadow-1);
}
.logo-mark svg { width: 19px; height: 19px; }
.logo-text {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  letter-spacing: -.02em;
  color: var(--text-primary);
}
.logo-text i { font-style: normal; color: var(--action-on-tint); }

.site-nav { display: flex; align-items: center; gap: var(--space-1); margin-right: auto; }
.site-nav a {
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-tertiary);
  transition: color .18s var(--ease), background-color .18s var(--ease);
}
.site-nav a:hover { color: var(--text-primary); background: var(--surface-sunken); }
.site-nav a[aria-current="page"] { color: var(--text-primary); font-weight: var(--weight-bold); }

.header-actions { display: flex; align-items: center; gap: var(--space-2); flex: none; }

.icon-btn {
  width: 40px; height: 40px; border-radius: var(--radius-full);
  display: grid; place-items: center;
  color: var(--text-tertiary);
  border: var(--border-width) solid transparent;
  transition: background-color .18s var(--ease), color .18s var(--ease);
  position: relative;
}
.icon-btn:hover { background: var(--surface-sunken); color: var(--text-primary); }
.icon-btn svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }

.fav-count {
  position: absolute; top: 1px; right: 1px;
  min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: var(--radius-full);
  background: var(--action); color: var(--action-text);
  font-size: 11px; font-weight: var(--weight-bold); line-height: 18px;
  text-align: center;
}

.nav-toggle { display: none; }
.theme-toggle .moon { display: none; }
:root[data-theme="dark"] .theme-toggle .sun { display: none; }
:root[data-theme="dark"] .theme-toggle .moon { display: block; }

@media (max-width: 980px) {
  .site-nav {
    position: fixed; inset: var(--header-height) 0 auto 0;
    flex-direction: column; align-items: stretch;
    background: var(--surface);
    border-bottom: var(--border-width) solid var(--border);
    padding: var(--space-4) var(--space-5) var(--space-6);
    gap: var(--space-1);
    box-shadow: var(--shadow-3);
    transform: translateY(-8px);
    opacity: 0; visibility: hidden;
    transition: transform .2s var(--ease), opacity .2s var(--ease), visibility .2s var(--ease);
  }
  .site-nav.is-open { transform: none; opacity: 1; visibility: visible; }
  .site-nav a { padding: var(--space-3); font-size: var(--text-base); }
  .nav-toggle { display: grid; }
  /* Only "Start planning" moves into the menu. Sign in, and the account
     button, stay in the bar — hiding every .btn here is what took sign-in
     off phones altogether. */
  .header-actions > .btn { display: none; }
  .site-nav .btn { display: inline-flex; margin-top: var(--space-3); }
}
@media (min-width: 981px) { .site-nav .btn { display: none; } }

/* ---- Hero -------------------------------------------------------------- */
.hero { position: relative; overflow: hidden; padding-block: var(--space-9) var(--space-8); }
.hero::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background:
    radial-gradient(60% 70% at 10% -8%, var(--action-tint) 0%, transparent 62%),
    radial-gradient(52% 62% at 94% 10%, var(--accent-tint) 0%, transparent 60%);
  opacity: .9;
}
.hero > * { position: relative; z-index: 1; }
.hero-grid {
  display: grid; grid-template-columns: 1.05fr .95fr;
  gap: var(--space-8); align-items: center;
}
.hero-copy > * + * { margin-top: var(--space-5); }
.hero h1 { max-width: 13ch; }
.hero .lede { max-width: 46ch; }

.hero-proof { display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap; }
.avatars { display: flex; }
.avatars span {
  width: 36px; height: 36px; border-radius: var(--radius-full);
  border: 2px solid var(--surface);
  margin-left: -10px;
  display: grid; place-items: center;
  font-size: var(--text-xs); font-weight: var(--weight-bold);
  color: var(--action-text);
}
.avatars span:first-child { margin-left: 0; }

.hero-art { position: relative; }
.hero-art .thumb { border-radius: var(--radius-lg); box-shadow: var(--shadow-4); aspect-ratio: 5 / 6; }
.hero-art .thumb::after { display: none; }
.float-card {
  position: absolute; z-index: 2;
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-3);
  padding: var(--space-3) var(--space-4);
  display: flex; align-items: center; gap: var(--space-3);
}
.float-card b { font-size: var(--text-sm); display: block; }
.float-card small { font-size: var(--text-xs); color: var(--text-tertiary); }
.float-card .cat-icon { width: 36px; height: 36px; }
.float-card .cat-icon svg { width: 17px; height: 17px; }
.float-a { left: calc(var(--space-5) * -1); bottom: var(--space-7); }
.float-b { right: calc(var(--space-4) * -1); top: var(--space-6); }

@media (max-width: 980px) {
  .hero-grid { grid-template-columns: 1fr; gap: var(--space-7); }
  .hero { padding-block: var(--space-7); }
  .hero-art { display: none; }
}

/* ---- Search bar -------------------------------------------------------- */
.searchbar {
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-3);
  box-shadow: var(--shadow-3);
  /* Flex rather than fixed columns: the browse bar carries four fields and
     the homepage three, and both should lay out without a bespoke rule. */
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: flex-end;
}
.searchbar .field { flex: 1 1 140px; }
.searchbar > .btn { flex: 0 0 auto; }
.searchbar .field { padding-inline: var(--space-2); min-width: 0; }
.searchbar .label {
  margin-bottom: 0; font-size: var(--text-xs); letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-tertiary); font-weight: var(--weight-bold);
}
.searchbar .input, .searchbar .select {
  border-color: transparent; background-color: transparent; padding: var(--space-1) 0;
  font-weight: var(--weight-medium);
}
.searchbar .select { background-position: right 0 center; padding-right: var(--space-6); }
.searchbar .input:hover, .searchbar .select:hover { border-color: transparent; }
.searchbar .input:focus, .searchbar .select:focus {
  box-shadow: none; border-color: transparent;
  outline: var(--border-width-thick) solid var(--focus-ring); outline-offset: 3px;
}
.searchbar .btn { height: 48px; }
.searchbar .field + .field { border-left: var(--border-width) solid var(--border); }

@media (max-width: 820px) {
  .searchbar > .btn { flex: 1 1 100%; }
  .searchbar .field + .field { border-left: 0; }
}
@media (max-width: 480px) { .searchbar .field { flex: 1 1 100%; } }

/* ---- Thumbnails (generated art — no external images) ------------------- */
.thumb {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--surface-sunken);
  display: grid; place-items: center;
  isolation: isolate;
}
.thumb::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to top, hsla(14, 30%, 10%, .26), transparent 55%);
  pointer-events: none;
}
.thumb svg { width: 100%; height: 100%; }
.thumb-tag {
  position: absolute; left: var(--space-3); top: var(--space-3); z-index: 2;
  background: var(--surface-raised);
  color: var(--text-secondary);
  box-shadow: var(--shadow-1);
}

.fav-btn {
  position: absolute; right: var(--space-3); top: var(--space-3); z-index: 3;
  width: 36px; height: 36px; border-radius: var(--radius-full);
  background: var(--surface-raised);
  color: var(--text-tertiary);
  display: grid; place-items: center;
  box-shadow: var(--shadow-1);
  transition: transform .16s var(--ease), color .16s var(--ease);
}
.fav-btn svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.fav-btn:hover { transform: scale(1.08); color: var(--action); }
.fav-btn[aria-pressed="true"] { color: var(--clay-500); }
.fav-btn[aria-pressed="true"] svg { fill: currentColor; }
:root[data-theme="dark"] .fav-btn[aria-pressed="true"] { color: var(--action); }

/* ---- Vendor card ------------------------------------------------------- */
.vendor-card {
  position: relative;
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  display: flex; flex-direction: column;
  transition: transform .2s var(--ease), box-shadow .2s var(--ease), border-color .2s var(--ease);
}
.vendor-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-3); border-color: var(--border-strong); }
.vendor-card:focus-within { box-shadow: var(--shadow-3); }
.vendor-body { padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-2); flex: 1; }
/* Name and badge sit on one row, and the row is always two lines tall, so
   every card's meta, blurb and price line up whatever the business is
   called. The name clamps at two lines; the badge never shrinks or wraps
   away, because it is the part that has to stay readable. */
/* Two lines of room always, so short names leave the same gap as long ones
   and the meta, blurb and price line up across the grid. A name that needs a
   third line gets it rather than being cut -- three is enough for any real
   business name at card width, and past that the ellipsis is the honest
   answer. */
.vendor-title {
  min-height: calc(var(--text-lg) * var(--leading-snug) * 2);
  font-family: var(--font-display); font-size: var(--text-lg);
  font-weight: var(--weight-bold); line-height: var(--leading-snug);
}
.vendor-title .vendor-name {
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden; overflow-wrap: anywhere;
}
/* In the flow after the name, so it never narrows the first line. */
.vendor-title .badge-verified {
  margin-left: .4em; vertical-align: middle; white-space: nowrap;
}
/* Stretched link keeps the whole card clickable without nesting interactives. */
.vendor-title a::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.vendor-meta { font-size: var(--text-sm); color: var(--text-tertiary); display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.vendor-meta svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.vendor-blurb { font-size: var(--text-sm); color: var(--text-secondary); line-height: var(--leading-normal); }
.vendor-foot {
  margin-top: auto; padding-top: var(--space-3);
  border-top: var(--border-width) solid var(--border);
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3);
}
.price { font-weight: var(--weight-bold); color: var(--text-primary); }
.price small { font-weight: var(--weight-normal); color: var(--text-tertiary); font-size: var(--text-xs); }

/* ---- Rating ------------------------------------------------------------ */
.rating { display: inline-flex; align-items: center; gap: var(--space-1); font-size: var(--text-sm); }
.rating svg { width: 15px; height: 15px; fill: var(--gold-500); flex: none; }
:root[data-theme="dark"] .rating svg { fill: var(--gold-800); }
.rating b { font-weight: var(--weight-bold); color: var(--text-primary); }
.rating span { color: var(--text-tertiary); }

/* ---- Category tiles ---------------------------------------------------- */
.cat-tile {
  display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-5);
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  transition: transform .2s var(--ease), box-shadow .2s var(--ease), border-color .2s var(--ease);
}
.cat-tile:hover { transform: translateY(-3px); box-shadow: var(--shadow-2); border-color: var(--border-strong); }
.cat-icon {
  width: 48px; height: 48px; border-radius: var(--radius-full);
  background: var(--action-tint); color: var(--action-on-tint);
  display: grid; place-items: center; flex: none;
}
.cat-icon svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.cat-tile:nth-child(3n+2) .cat-icon { background: var(--accent-tint); color: var(--accent-on-tint); }
.cat-tile:nth-child(3n+3) .cat-icon { background: var(--gold-100); color: var(--gold-800); }
.cat-name { font-family: var(--font-display); font-size: var(--text-lg); font-weight: var(--weight-bold); }
.cat-count { font-size: var(--text-sm); color: var(--text-tertiary); margin-top: auto; }

/* ---- Steps ------------------------------------------------------------- */
.steps { counter-reset: step; }
.step { position: relative; padding-left: var(--space-8); }
.step::before {
  counter-increment: step; content: counter(step);
  position: absolute; left: 0; top: 0;
  width: 40px; height: 40px; border-radius: var(--radius-full);
  background: var(--action); color: var(--action-text);
  display: grid; place-items: center;
  font-family: var(--font-display); font-weight: var(--weight-bold); font-size: var(--text-lg);
  box-shadow: var(--shadow-1);
}
.step h3 { margin-bottom: var(--space-2); padding-top: var(--space-2); }
.step p { color: var(--text-secondary); font-size: var(--text-sm); line-height: var(--leading-loose); }

/* ---- Features ---------------------------------------------------------- */
.feature { display: flex; gap: var(--space-4); }
.feature-icon {
  width: 44px; height: 44px; flex: none; border-radius: var(--radius-full);
  background: var(--accent-tint); color: var(--accent-on-tint);
  display: grid; place-items: center;
}
.feature-icon svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.feature h3 { margin-bottom: var(--space-2); }
.feature p { color: var(--text-secondary); font-size: var(--text-sm); line-height: var(--leading-loose); }

.tick-list { display: grid; gap: var(--space-3); }
.tick-list li { display: flex; gap: var(--space-3); align-items: flex-start; color: var(--text-secondary); }
.tick-list svg { width: 20px; height: 20px; flex: none; margin-top: 2px; color: var(--accent); fill: none; stroke: currentColor; stroke-width: 2.25; stroke-linecap: round; stroke-linejoin: round; }

/* ---- Testimonials ------------------------------------------------------ */
.quote {
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-6);
  display: flex; flex-direction: column; gap: var(--space-4);
}
.quote blockquote { font-family: var(--font-display); font-size: var(--text-lg); line-height: var(--leading-normal); color: var(--text-primary); }
.quote figcaption { display: flex; align-items: center; gap: var(--space-3); margin-top: auto; }
.quote-avatar {
  width: 40px; height: 40px; border-radius: var(--radius-full); flex: none;
  display: grid; place-items: center;
  font-weight: var(--weight-bold); font-size: var(--text-sm); color: var(--action-text);
}
.quote-name { font-weight: var(--weight-bold); font-size: var(--text-sm); }
.quote-role { font-size: var(--text-sm); color: var(--text-tertiary); }

/* ---- Stats ------------------------------------------------------------- */
.stat { text-align: center; }
.stat b { display: block; font-family: var(--font-display); font-size: var(--text-4xl); line-height: 1.1; color: var(--action-on-tint); }
.stat span { font-size: var(--text-sm); color: var(--text-tertiary); }

/* ---- CTA band ---------------------------------------------------------- */
.cta-band {
  background: var(--surface-inverse);
  color: var(--text-inverse);
  border-radius: var(--radius-xl);
  padding: var(--space-8);
  position: relative; overflow: hidden;
}
.cta-band::before {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(70% 130% at 88% 6%, hsla(20, 62%, 58%, .32), transparent 62%);
}
.cta-band > * { position: relative; }
.cta-band h2 { color: var(--text-inverse); }
/* Never grey text on a colored background — this is a tinted sibling of the ground. */
.cta-band p { color: hsl(30, 22%, 78%); max-width: 52ch; }
:root[data-theme="dark"] .cta-band p { color: hsl(20, 12%, 32%); }
@media (max-width: 700px) { .cta-band { padding: var(--space-6); border-radius: var(--radius-lg); } }

/* ---- FAQ / accordion --------------------------------------------------- */
.faq { border-top: var(--border-width) solid var(--border); }
.faq-item { border-bottom: var(--border-width) solid var(--border); }
.faq-q {
  width: 100%; text-align: left;
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
  padding: var(--space-5) var(--space-2);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.faq-q:hover { color: var(--action-on-tint); }
.faq-q svg { width: 20px; height: 20px; flex: none; color: var(--text-tertiary); transition: transform .2s var(--ease); fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.faq-q[aria-expanded="true"] svg { transform: rotate(45deg); }
.faq-a { padding: 0 var(--space-8) var(--space-5) var(--space-2); }
.faq-a p { color: var(--text-secondary); font-size: var(--text-sm); line-height: var(--leading-loose); max-width: var(--measure); }

/* ---- Browse page ------------------------------------------------------- */
.browse { display: grid; grid-template-columns: 264px 1fr; gap: var(--space-7); align-items: start; }
.filters {
  position: sticky; top: calc(var(--header-height) + var(--space-5));
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-5);
}
.filter-group + .filter-group { margin-top: var(--space-5); padding-top: var(--space-5); border-top: var(--border-width) solid var(--border); }
.filter-group h3 { font-family: var(--font-body); font-size: var(--text-sm); text-transform: uppercase; letter-spacing: .07em; color: var(--text-tertiary); margin-bottom: var(--space-3); }
.results-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; margin-bottom: var(--space-5); }
.results-count { font-size: var(--text-sm); color: var(--text-tertiary); }
.results-count b { color: var(--text-primary); font-weight: var(--weight-bold); }
.sort-row { display: flex; align-items: center; gap: var(--space-2); }
/* width:auto sizes a select to its longest option, and "Starting price:
   low to high" is wider than a small phone. It may grow into the room it
   has and no further. */
.sort-row .select {
  width: auto; max-width: 100%; min-width: 0;
  padding-block: var(--space-2); font-size: var(--text-sm);
}
@media (max-width: 420px) { .sort-row { flex-wrap: wrap; } }
.results-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-5); }
@media (max-width: 1120px) { .results-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 900px) {
  .browse { grid-template-columns: 1fr; }
  .filters { position: static; }
}
@media (max-width: 560px) { .results-grid { grid-template-columns: 1fr; } }

.filters-toggle { display: none; }
@media (max-width: 900px) {
  .filters-toggle { display: inline-flex; }
  .filters.is-collapsed { display: none; }
}

.empty {
  text-align: center; padding: var(--space-9) var(--space-5);
  border: var(--border-width-thick) dashed var(--border-strong);
  border-radius: var(--radius-lg);
  color: var(--text-tertiary);
}
.empty h3 { margin-bottom: var(--space-2); }
.empty p { max-width: 40ch; margin-inline: auto; font-size: var(--text-sm); }
.empty .btn { margin-top: var(--space-5); }

.active-filters { display: flex; gap: var(--space-2); flex-wrap: wrap; margin-bottom: var(--space-4); }
.chip {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: var(--space-1) var(--space-2) var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
  background: var(--action-tint); color: var(--action-on-tint);
  font-size: var(--text-sm); font-weight: var(--weight-medium);
}
.chip button { display: grid; place-items: center; width: 20px; height: 20px; border-radius: var(--radius-full); color: inherit; }
.chip button:hover { background: var(--surface-raised); }
.chip svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }

/* ---- Vendor detail ----------------------------------------------------- */
.detail { display: grid; grid-template-columns: 1fr 380px; gap: var(--space-7); align-items: start; }
@media (max-width: 1000px) { .detail { grid-template-columns: 1fr; } }

.gallery { display: grid; grid-template-columns: 2fr 1fr; gap: var(--space-2); border-radius: var(--radius-lg); overflow: hidden; }
.gallery .thumb { aspect-ratio: auto; height: 100%; min-height: 200px; }
.gallery-side { display: grid; gap: var(--space-2); }
@media (max-width: 700px) { .gallery { grid-template-columns: 1fr; } .gallery-side { grid-template-columns: 1fr 1fr; } }

.detail-title { display: flex; flex-direction: column; gap: var(--space-3); }
.detail-title h1 { font-size: var(--text-4xl); }
.detail-facts { display: flex; gap: var(--space-4); flex-wrap: wrap; color: var(--text-tertiary); font-size: var(--text-sm); align-items: center; }
.detail-facts svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.detail-facts > span { display: inline-flex; align-items: center; gap: var(--space-2); }

.detail-section + .detail-section { margin-top: var(--space-7); padding-top: var(--space-7); border-top: var(--border-width) solid var(--border); }
.detail-section h2 { font-size: var(--text-2xl); margin-bottom: var(--space-4); }
.detail-section p { color: var(--text-secondary); line-height: var(--leading-loose); max-width: var(--measure); }
.detail-section p + p { margin-top: var(--space-4); }

.package {
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-5);
  background: var(--surface-raised);
  display: flex; flex-direction: column; gap: var(--space-3);
}
.package.is-featured { border-color: var(--action); border-width: var(--border-width-thick); }
.package-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); }
.package-price { font-family: var(--font-display); font-size: var(--text-2xl); font-weight: var(--weight-bold); color: var(--action-on-tint); }
.package h3 { font-size: var(--text-lg); }
.package .tick-list li { font-size: var(--text-sm); }

.book-card {
  position: sticky; top: calc(var(--header-height) + var(--space-5));
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-3);
}
@media (max-width: 1000px) { .book-card { position: static; } }
.book-price { display: flex; align-items: baseline; gap: var(--space-2); margin-bottom: var(--space-1); }
.book-price b { font-family: var(--font-display); font-size: var(--text-3xl); }
.book-price span { color: var(--text-tertiary); font-size: var(--text-sm); }

.review { padding-block: var(--space-5); border-bottom: var(--border-width) solid var(--border); }
.review:last-child { border-bottom: 0; }
.review-head { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-3); }
.review-head .quote-avatar { width: 36px; height: 36px; }
.review p { font-size: var(--text-sm); }

.score-block { display: flex; align-items: center; gap: var(--space-5); flex-wrap: wrap; }
.score-big { font-family: var(--font-display); font-size: var(--text-5xl); line-height: 1; font-weight: var(--weight-bold); }
.bar-row { display: flex; align-items: center; gap: var(--space-3); font-size: var(--text-sm); color: var(--text-tertiary); }
.bar { flex: 1; height: 8px; border-radius: var(--radius-full); background: var(--surface-sunken); overflow: hidden; min-width: 120px; }
.bar i { display: block; height: 100%; background: var(--gold-500); border-radius: var(--radius-full); }
:root[data-theme="dark"] .bar i { background: var(--gold-800); }

/* ---- Pricing plans ----------------------------------------------------- */
.plan {
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  display: flex; flex-direction: column; gap: var(--space-4);
}
.plan.is-featured { border-color: var(--action); border-width: var(--border-width-thick); box-shadow: var(--shadow-3); }
.plan-price { font-family: var(--font-display); font-size: var(--text-4xl); font-weight: var(--weight-bold); line-height: 1; }
.plan-price small { font-family: var(--font-body); font-size: var(--text-sm); font-weight: var(--weight-normal); color: var(--text-tertiary); }
.plan .btn { margin-top: auto; }

/* ---- Page header ------------------------------------------------------- */
.page-head { padding-block: var(--space-8) var(--space-6); border-bottom: var(--border-width) solid var(--border); background: var(--surface-sunken); }
.page-head > .wrap > * + * { margin-top: var(--space-3); }
.crumbs { font-size: var(--text-sm); color: var(--text-tertiary); display: flex; gap: var(--space-2); align-items: center; flex-wrap: wrap; }
.crumbs a:hover { color: var(--action-on-tint); text-decoration: underline; text-underline-offset: 3px; }

/* ---- Footer ------------------------------------------------------------ */
.site-footer {
  background: var(--surface-sunken);
  border-top: var(--border-width) solid var(--border);
  padding-block: var(--space-8) var(--space-6);
  margin-top: var(--space-9);
}
.footer-grid { display: grid; grid-template-columns: 1.7fr 1fr 1fr 1fr; gap: var(--space-7); }
.footer-brand p { color: var(--text-tertiary); font-size: var(--text-sm); max-width: 34ch; margin-top: var(--space-3); line-height: var(--leading-loose); }
.footer-col h4 { font-family: var(--font-body); font-size: var(--text-sm); text-transform: uppercase; letter-spacing: .08em; color: var(--text-tertiary); margin-bottom: var(--space-4); }
.footer-col li + li { margin-top: var(--space-3); }
.footer-col a { font-size: var(--text-sm); color: var(--text-secondary); }
.footer-col a:hover { color: var(--action-on-tint); text-decoration: underline; text-underline-offset: 3px; }
.footer-bottom {
  margin-top: var(--space-7); padding-top: var(--space-5);
  border-top: var(--border-width) solid var(--border);
  display: flex; justify-content: space-between; align-items: center; gap: var(--space-4); flex-wrap: wrap;
  font-size: var(--text-sm); color: var(--text-tertiary);
}
.social { display: flex; gap: var(--space-2); }
.social a { width: 36px; height: 36px; border-radius: var(--radius-full); display: grid; place-items: center; color: var(--text-tertiary); border: var(--border-width) solid var(--border); }
.social a:hover { color: var(--action-on-tint); border-color: var(--border-strong); background: var(--surface-raised); }
.social svg { width: 17px; height: 17px; }
@media (max-width: 860px) { .footer-grid { grid-template-columns: 1fr 1fr; gap: var(--space-6); } }
@media (max-width: 520px) { .footer-grid { grid-template-columns: 1fr; } }

.newsletter { display: flex; gap: var(--space-2); margin-top: var(--space-4); max-width: 380px; }
.newsletter .input { border-radius: var(--radius-full); }

/* ---- Account chip in the header ---------------------------------------- */
.account-chip {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: var(--space-1) var(--space-3) var(--space-1) var(--space-1);
  border-radius: var(--radius-full);
  border: var(--border-width) solid var(--border-strong);
  background: var(--surface-raised);
  font-size: var(--text-sm); font-weight: var(--weight-bold);
  transition: border-color .18s var(--ease), background-color .18s var(--ease);
}
.account-chip:hover { border-color: var(--text-tertiary); background: var(--surface-sunken); }
.account-chip-avatar {
  width: 28px; height: 28px; border-radius: var(--radius-full); flex: none;
  display: grid; place-items: center;
  background: var(--action); color: var(--action-text);
  font-size: var(--text-xs); font-weight: var(--weight-bold);
}
@media (max-width: 620px) { .account-chip-name { display: none; } }

/* ---- Dashboards -------------------------------------------------------- */
.dash-hero { text-align: center; max-width: 640px; margin: 0 auto var(--space-6); }
.dash-hero .badge { margin-bottom: var(--space-4); }
.dash-hero h1 { font-size: var(--text-4xl); margin-bottom: var(--space-3); }
.dash-hero p { color: var(--text-secondary); max-width: 52ch; margin-inline: auto; }

/* Vendor welcome panel — the warm band across the top */
.dash-welcome {
  background: var(--action-tint);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-5) var(--space-6);
  display: flex; align-items: center; gap: var(--space-5);
  flex-wrap: wrap;
  margin-bottom: var(--space-6);
}
.dash-welcome h1 { font-size: var(--text-3xl); line-height: var(--leading-snug); }
/* Listing and the settings gear ride together at the far right of the
   banner. The pair is one flex item, so they keep their own tight gap
   rather than the banner's much wider one. */
.dash-welcome-actions { margin-left: auto; gap: var(--space-3); flex: none; }
.dash-welcome-sub { color: var(--text-secondary); font-size: var(--text-sm); margin-top: var(--space-1); }

/* Customer profile card */
.profile-card {
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-5);
  display: flex; align-items: center; gap: var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-5);
}
.profile-card .mini-stats { margin-left: auto; display: flex; gap: var(--space-6); }
.mini-stat { text-align: center; min-width: 64px; }
.mini-stat b { display: block; font-family: var(--font-display); font-size: var(--text-xl); line-height: 1.2; }
.mini-stat span { font-size: var(--text-sm); color: var(--text-tertiary); }

.avatar-lg {
  position: relative; flex: none;
  width: 56px; height: 56px; border-radius: var(--radius-full);
  background: var(--sand-200); color: var(--sand-700);
  display: grid; place-items: center;
  font-family: var(--font-display); font-weight: var(--weight-bold); font-size: var(--text-lg);
}
.avatar-lg .avatar-badge {
  position: absolute; right: -2px; bottom: -2px;
  width: 20px; height: 20px; border-radius: var(--radius-full);
  background: var(--action); color: var(--action-text);
  border: 2px solid var(--surface-raised);
  display: grid; place-items: center;
}
.avatar-lg .avatar-badge svg { width: 10px; height: 10px; fill: none; stroke: currentColor; stroke-width: 2.4; }

/* Tabs */
.dash-tabs { display: flex; gap: var(--space-2); flex-wrap: wrap; margin-bottom: var(--space-6); }
.dash-tabs .pill { padding: var(--space-3) var(--space-5); }

/* Stat cards */
.stat-cards { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-4); margin-bottom: var(--space-6); }
@media (max-width: 900px) { .stat-cards { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .stat-cards { grid-template-columns: 1fr; } }
.stat-card {
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-5);
  display: flex; align-items: center; gap: var(--space-4);
  text-align: left;
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.stat-card:hover { border-color: var(--border-strong); }
.stat-card.is-active { border-color: var(--action); border-width: var(--border-width-thick); }
.stat-card .cat-icon { width: 40px; height: 40px; background: var(--surface-sunken); color: var(--text-tertiary); }
.stat-card.is-active .cat-icon { background: var(--action-tint); color: var(--action-on-tint); }
.stat-card b { display: block; font-family: var(--font-display); font-size: var(--text-2xl); line-height: 1.1; }
.stat-card span { font-size: var(--text-sm); color: var(--text-tertiary); }

/* Toolbar above a list */
.dash-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-4); flex-wrap: wrap; margin-bottom: var(--space-4);
}
.dash-toolbar h2 { font-size: var(--text-2xl); }

/* Lead / booking rows */
.lead {
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-5);
  display: grid; gap: var(--space-3);
}
.lead + .lead { margin-top: var(--space-3); }
.lead-head { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.lead-head h3 { font-size: var(--text-lg); }
.lead-head .badge { margin-left: auto; }
/* Name over address, so the badge still sits at the far right of the row
   rather than beside the address. min-width:0 lets a long address ellipsis
   instead of pushing the badge off a phone. */
.lead-who { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 0; }
/* Wraps rather than ellipsises: a clipped address cannot be read or
   copied, and reading it off the card is half the point. */
.lead-email {
  font-size: var(--text-sm); color: var(--text-secondary);
  overflow-wrap: anywhere;
}
.lead-email:hover { color: var(--text-primary); text-decoration: underline; }
.lead-facts { display: flex; gap: var(--space-4); flex-wrap: wrap; font-size: var(--text-sm); color: var(--text-tertiary); }
.lead-facts b { color: var(--text-primary); font-weight: var(--weight-bold); }
.lead-msg { font-size: var(--text-sm); color: var(--text-secondary); line-height: var(--leading-loose); }
.lead-actions { display: flex; gap: var(--space-2); flex-wrap: wrap; padding-top: var(--space-3); border-top: var(--border-width) solid var(--border); }

.badge-pending   { background: var(--gold-100);   color: var(--gold-800); }
.badge-confirmed { background: var(--accent-tint); color: var(--accent-on-tint); }
.badge-canceled  { background: var(--surface-sunken); color: var(--text-tertiary); }

/* A tab whose feature is not built yet says so plainly. */
.not-built { text-align: center; padding: var(--space-8) var(--space-5); color: var(--text-tertiary); }
.not-built h3 { margin-bottom: var(--space-2); color: var(--text-secondary); }
.not-built p { font-size: var(--text-sm); max-width: 44ch; margin-inline: auto; }

/* A draft listing is invisible publicly — flag it where it cannot be missed. */
.draft-banner {
  display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap;
  background: var(--gold-100);
  border: var(--border-width) solid var(--border);
  border-left: 4px solid var(--gold-500);
  border-radius: var(--radius);
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-5);
}
.draft-banner .cat-icon { background: transparent; color: var(--gold-800); width: 32px; height: 32px; }
.draft-banner b { display: block; color: var(--gold-800); }
.draft-banner .btn { margin-left: auto; }

/* ---- Chat -------------------------------------------------------------- */
.chat-layout { display: grid; grid-template-columns: 280px 1fr; gap: var(--space-4); align-items: start; }
@media (max-width: 860px) { .chat-layout { grid-template-columns: 1fr; } }

.thread-list {
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-raised);
  overflow: hidden;
  max-height: 560px; overflow-y: auto;
}
.thread {
  display: block; width: 100%; text-align: left;
  padding: var(--space-4);
  border-bottom: var(--border-width) solid var(--border);
  transition: background-color .15s var(--ease);
}
.thread:last-child { border-bottom: 0; }
.thread:hover { background: var(--surface-sunken); }
.thread.is-active { background: var(--action-tint); }
.thread b { display: block; font-size: var(--text-sm); }
.thread span { font-size: var(--text-xs); color: var(--text-tertiary); }
.thread .badge { margin-top: var(--space-2); }

.chat-pane {
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-raised);
  display: flex; flex-direction: column;
  min-height: 420px; max-height: 560px;
}
.chat-head { padding: var(--space-4); border-bottom: var(--border-width) solid var(--border); }
.chat-head h3 { font-size: var(--text-lg); }
.chat-messages { flex: 1; overflow-y: auto; padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-3); }
.msg { max-width: 78%; padding: var(--space-3) var(--space-4); border-radius: var(--radius); background: var(--surface-sunken); }
.msg p { font-size: var(--text-sm); line-height: var(--leading-normal); }
.msg time { display: block; font-size: var(--text-xs); color: var(--text-tertiary); margin-top: var(--space-1); }
.msg.is-mine { align-self: flex-end; background: var(--action-tint); color: var(--action-on-tint); }
.msg.is-mine time { color: var(--action-on-tint); opacity: .75; }
.chat-composer { display: flex; gap: var(--space-2); padding: var(--space-3); border-top: var(--border-width) solid var(--border); }
.chat-composer .input { border-radius: var(--radius-full); }
.chat-closed { padding: var(--space-4); border-top: var(--border-width) solid var(--border); text-align: center; font-size: var(--text-sm); color: var(--text-tertiary); }

/* ---- Calendar ---------------------------------------------------------- */
.cal-legend { display: flex; gap: var(--space-5); flex-wrap: wrap; margin-bottom: var(--space-4); font-size: var(--text-sm); color: var(--text-tertiary); }
.cal-legend span { display: inline-flex; align-items: center; gap: var(--space-2); }
.swatch { width: 14px; height: 14px; border-radius: 4px; display: inline-block; border: var(--border-width) solid var(--border); }
.swatch-booked  { background: var(--action); border-color: var(--action); }
.swatch-blocked { background: var(--sand-300); border-color: var(--sand-400); }
.swatch-free    { background: var(--surface-raised); }

.calendar {
  display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--space-1);
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-3);
}
.cal-dow { text-align: center; font-size: var(--text-xs); font-weight: var(--weight-bold); color: var(--text-tertiary); padding: var(--space-2) 0; text-transform: uppercase; letter-spacing: .05em; }
/* A month cell holds what is on the day, not just whether anything is. The
   cell stays neutral and the events carry the colour -- a solid fill behind
   a chip would make both unreadable. */
.cal-day {
  min-height: 104px;
  border-radius: var(--radius-sm);
  border: var(--border-width) solid transparent;
  display: flex; flex-direction: column; align-items: stretch; gap: 3px;
  padding: var(--space-2);
  font-size: var(--text-sm); text-align: left;
  transition: background-color .15s var(--ease), border-color .15s var(--ease);
}
.cal-num { font-variant-numeric: tabular-nums; line-height: 1.1; }
.cal-chips { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cal-chip {
  display: block; min-width: 0;
  padding: 1px var(--space-2);
  border-radius: var(--radius-sm);
  font-size: var(--text-xs); line-height: 1.5;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cal-chip b { font-weight: var(--weight-bold); }
.cal-chip.is-booked    { background: var(--action); color: var(--action-text); }
.cal-chip.is-tentative { background: var(--action-tint); color: var(--action-on-tint); }
.cal-chip.is-busy      { background: var(--accent-tint); color: var(--accent-on-tint); }
.cal-chip.is-blocked   { background: var(--surface-sunken); color: var(--text-tertiary); }
.cal-more { font-size: var(--text-xs); color: var(--text-tertiary); padding-left: var(--space-2); }
/* The dot was how a busy day read when the cell was a square. It stays for
   the narrow layout below, where the chips are hidden. */
.cal-day .cal-dot { display: none; }
.cal-day:hover { border-color: var(--border-strong); }
.cal-day.is-out { opacity: var(--opacity-3); pointer-events: none; }
.cal-day.is-today { border-color: var(--action); font-weight: var(--weight-bold); }
/* Below this a cell is about 50px wide: a chip in it would be two letters
   and an ellipsis. The dot comes back and the day opens to the list, which
   is the readable place for detail on a phone anyway. */
@media (max-width: 760px) {
  .cal-day { min-height: 46px; align-items: center; padding: var(--space-1); }
  .cal-chips, .cal-more { display: none; }
  .cal-day .cal-dot { display: block; }
}

/* The day whose contents are listed below. A ring rather than a fill: the
   fills already mean booked, blocked and busy, and selection has to read on
   top of any of them. */
.cal-day.is-selected {
  outline: var(--border-width-thick) solid var(--action);
  outline-offset: 2px;
}
.cal-day.is-booked { font-weight: var(--weight-bold); }
.cal-day.is-blocked .cal-num { color: var(--text-tertiary); text-decoration: line-through; }
/* Busy in the vendor's own calendar — distinct from a block they set here,
   because they cannot edit it from this side. */

.swatch-busy { background: var(--accent-tint); border-color: var(--accent); }
.cal-dot { width: 5px; height: 5px; border-radius: 50%; background: currentColor; }

.month-row {
  display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap;
  padding: var(--space-4);
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
}
.month-row + .month-row { margin-top: var(--space-2); }

/* Which view the list is showing, and the way back to the month. */
.list-head {
  display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
  margin: var(--space-7) 0 var(--space-4);
}
.list-head h3 { margin: 0; margin-right: auto; }

/* The hour sits under the date, so the eye runs down one column of times
   the way it does in a calendar rather than hunting along each row. */
.month-row .row-time {
  font-size: var(--text-xs); color: var(--text-tertiary);
  white-space: nowrap; align-self: center;
}
.month-row .date-chip {
  flex: none; width: 52px; text-align: center;
  background: var(--surface-sunken); border-radius: var(--radius-sm); padding: var(--space-2);
}
.month-row .date-chip b { display: block; font-family: var(--font-display); font-size: var(--text-lg); line-height: 1; }
.month-row .date-chip span { font-size: var(--text-xs); color: var(--text-tertiary); text-transform: uppercase; }
.month-row .btn { margin-left: auto; }

/* ---- Gallery ----------------------------------------------------------- */
.gallery-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: var(--space-3); }
.gallery-item { position: relative; border-radius: var(--radius); overflow: hidden; border: var(--border-width) solid var(--border); background: var(--surface-sunken); }
.gallery-item img { width: 100%; aspect-ratio: 4/3; object-fit: cover; display: block; }
.gallery-item .cover-tag { position: absolute; left: var(--space-2); top: var(--space-2); }
.gallery-item .remove {
  position: absolute; right: var(--space-2); top: var(--space-2);
  width: 30px; height: 30px; border-radius: var(--radius-full);
  background: var(--surface-raised); color: var(--red-800);
  display: grid; place-items: center; box-shadow: var(--shadow-1);
}
.gallery-item .remove svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }
.gallery-item .move { position: absolute; left: var(--space-2); bottom: var(--space-2); display: flex; gap: 4px; }
.gallery-item .move button {
  width: 28px; height: 28px; border-radius: var(--radius-sm);
  background: var(--surface-raised); color: var(--text-secondary);
  display: grid; place-items: center; box-shadow: var(--shadow-1); font-weight: var(--weight-bold);
}
/* Pin and "make cover" sit opposite the arrows so the two kinds of change --
   nudging an order and choosing a role -- do not get muddled up. */
.gallery-item .acts { position: absolute; right: var(--space-2); bottom: var(--space-2); display: flex; gap: 4px; }
.gallery-item .acts button {
  height: 28px; padding: 0 10px; border-radius: var(--radius-sm);
  background: var(--surface-raised); color: var(--text-secondary);
  display: grid; place-items: center; box-shadow: var(--shadow-1);
  font-size: var(--text-xs); font-weight: var(--weight-medium); white-space: nowrap;
}
.gallery-item .acts button:hover { color: var(--text-primary); }
.gallery-item .acts button.is-on { background: var(--action); color: #FFFFFF; }

/* The whole tile is the way in to the viewer, so it is a button rather than
   a picture with a click handler -- the keyboard gets there the same way. */
.gallery-open {
  display: block; width: 100%; padding: 0; border: 0;
  background: none; cursor: zoom-in; position: relative;
}
.gallery-open:focus-visible { outline: 2px solid var(--action); outline-offset: -2px; }
.gallery-item video { width: 100%; aspect-ratio: 4/3; object-fit: cover; display: block; background: #000; }
/* A still frame is indistinguishable from a photo until something says so. */
.gallery-play {
  position: absolute; inset: 0; margin: auto;
  width: 44px; height: 44px; border-radius: var(--radius-full);
  background: rgba(0, 0, 0, .55); color: #FFFFFF;
  display: grid; place-items: center; font-size: 15px; padding-left: 3px;
  pointer-events: none;
}
.lightbox-stage video { max-width: 100%; max-height: 80vh; display: block; border-radius: var(--radius); background: #000; }

/* ---- Invoices ---------------------------------------------------------- */
.invoice-total { font-size: var(--text-lg); text-align: right; padding-top: var(--space-3); border-top: var(--border-width) solid var(--border); }
.invoice-total b { font-family: var(--font-display); font-size: var(--text-2xl); }
.inv-item { display: grid; grid-template-columns: 1fr 80px 110px 36px; gap: var(--space-2); margin-bottom: var(--space-2); align-items: center; }
.inv-item .remove-item { width: 32px; height: 32px; border-radius: var(--radius-sm); display: grid; place-items: center; color: var(--text-tertiary); }
.inv-item .remove-item:hover { background: var(--surface-sunken); color: var(--red-800); }
@media (max-width: 620px) { .inv-item { grid-template-columns: 1fr 1fr; } }

.badge-draft { background: var(--surface-sunken); color: var(--text-tertiary); }
.badge-sent  { background: var(--gold-100);  color: var(--gold-800); }
.badge-paid  { background: var(--accent-tint); color: var(--accent-on-tint); }
.badge-void  { background: var(--red-100);   color: var(--red-800); }
.badge-accepted { background: var(--accent-tint); color: var(--accent-on-tint); }
.badge-declined { background: var(--red-100); color: var(--red-800); }
.badge-completed { background: var(--action-tint); color: var(--action-on-tint); }

/* ---- Social links ------------------------------------------------------ */
.social-links { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.social-links a {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border: var(--border-width) solid var(--border-strong);
  border-radius: var(--radius-full);
  font-size: var(--text-sm); font-weight: var(--weight-medium);
  color: var(--text-secondary);
}
.social-links a:hover { border-color: var(--text-tertiary); color: var(--text-primary); background: var(--surface-sunken); }

/* ---- Public invoice page ------------------------------------------------ */
.invoice-sheet {
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-8);
  max-width: 760px; margin-inline: auto;
}
@media (max-width: 620px) { .invoice-sheet { padding: var(--space-5); } }
.invoice-sheet table { width: 100%; border-collapse: collapse; margin-block: var(--space-6); }
.invoice-sheet th {
  text-align: left; font-size: var(--text-xs); text-transform: uppercase; letter-spacing: .07em;
  color: var(--text-tertiary); padding-bottom: var(--space-3);
  border-bottom: var(--border-width) solid var(--border);
}
.invoice-sheet td { padding-block: var(--space-3); border-bottom: var(--border-width) solid var(--border); font-size: var(--text-sm); }
.invoice-sheet th:last-child, .invoice-sheet td:last-child { text-align: right; }
@media print {
  .site-header, .site-footer, .no-print { display: none !important; }
  .invoice-sheet { border: 0; padding: 0; }
}

/* ---- Multi-date picker -------------------------------------------------- */
.date-chips { display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-3); }
.date-chip {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-2) var(--space-2) var(--space-2) var(--space-4);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-raised);
  font-size: var(--text-sm);
}
.date-chip b { font-weight: var(--weight-medium); }
.date-chip .badge { margin-left: auto; }
.date-chip button {
  width: 26px; height: 26px; border-radius: var(--radius-sm); flex: none;
  display: grid; place-items: center; color: var(--text-tertiary);
}
.date-chip button:hover { background: var(--surface-sunken); color: var(--red-800); }
.date-chip button svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }

/* A vendor the chosen date rules out, shown while the filter is on. */
.vendor-card.is-unavailable { opacity: .55; }
.vendor-card.is-unavailable .thumb { filter: grayscale(.6); }

/* ---- Booking link ------------------------------------------------------- */
.booking-link {
  background: var(--accent-tint);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-5);
  margin-bottom: var(--space-5);
}
.booking-link h3 { color: var(--accent-on-tint); margin-bottom: var(--space-2); }
.booking-link .row { margin-top: var(--space-4); }
.booking-link .input { font-size: var(--text-sm); }
.caption-box {
  margin-top: var(--space-4);
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-sm);
  padding: var(--space-4);
  font-size: var(--text-sm);
  color: var(--text-secondary);
  white-space: pre-wrap;
}

/* ---- Account menu ------------------------------------------------------- */
.account-menu { position: relative; }
.account-dropdown {
  position: absolute; right: 0; top: calc(100% + var(--space-2)); z-index: 60;
  min-width: 208px;
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-3);
  padding: var(--space-2);
  display: flex; flex-direction: column; gap: 2px;
}
.account-dropdown-who {
  font-size: var(--text-xs);
  color: var(--text-tertiary);
  padding: var(--space-2) var(--space-3);
  border-bottom: var(--border-width) solid var(--border);
  margin-bottom: var(--space-1);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.account-dropdown a,
.account-dropdown button {
  display: block; width: 100%; text-align: left;
  padding: var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-secondary);
  transition: background-color .15s var(--ease), color .15s var(--ease);
}
.account-dropdown a:hover,
.account-dropdown button:hover { background: var(--surface-sunken); color: var(--text-primary); }
.account-dropdown button[data-signout] {
  color: var(--red-800);
  border-top: var(--border-width) solid var(--border);
  margin-top: var(--space-1);
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
}
.account-dropdown button[data-signout]:hover { background: var(--red-100); color: var(--red-800); }

/* ==========================================================================
   Mobile — the vendor dashboard is used standing up, between jobs, on a
   phone. Everything below assumes a thumb, not a mouse.
   ========================================================================== */

/* Touch targets. 44px is the smallest reliably hittable size. */
@media (pointer: coarse) {
  .icon-btn, .fav-btn { min-width: 44px; min-height: 44px; }
  .btn-sm { --btn-py: var(--space-3); }
  .thread { padding-block: var(--space-4); }
  .cal-day { min-height: 46px; }
}

@media (max-width: 760px) {
  /* iOS zooms the page whenever a focused control is under 16px. Holding
     every control at 16px is the only thing that reliably prevents it. */
  .input, .select, .textarea,
  .sort-row .select, .searchbar .input, .searchbar .select { font-size: 16px; }

  /* Tab rows scroll sideways rather than stacking seven pills down the
     screen and pushing the content out of view. */
  .dash-tabs, .dash-toolbar .pill-nav {
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    margin-inline: calc(var(--space-5) * -1);
    padding-inline: var(--space-5);
    padding-bottom: var(--space-2);
  }
  .dash-tabs::-webkit-scrollbar,
  .dash-toolbar .pill-nav::-webkit-scrollbar { display: none; }
  .dash-tabs .pill, .dash-toolbar .pill-nav .pill { flex: 0 0 auto; }

  .dash-welcome {
    flex-direction: column; align-items: flex-start;
    padding: var(--space-4);
  }
  .dash-welcome h1 { font-size: var(--text-2xl); }
  /* Stacked on a phone there is no right edge to sit against, and the
     pair reads as a row under the greeting. */
  .dash-welcome-actions { margin-left: 0; }

  /* Two up beats one: four stat cards stacked is a lot of scrolling before
     the actual list of bookings. */
  .stat-cards { grid-template-columns: 1fr 1fr; gap: var(--space-3); }
  .stat-card { flex-direction: column; align-items: flex-start; gap: var(--space-2); padding: var(--space-4); }
  .stat-card b { font-size: var(--text-xl); }

  .dash-toolbar { flex-direction: column; align-items: stretch; gap: var(--space-3); }
  .dash-toolbar h2 { font-size: var(--text-xl); }

  /* Actions on a booking go full width so they are hard to miss. */
  .lead { padding: var(--space-4); }
  .lead-actions { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); }
  .lead-actions .btn { width: 100%; }
  .lead-actions .btn:first-child:nth-last-child(odd) { grid-column: 1 / -1; }

  .profile-card { flex-direction: column; align-items: flex-start; }
  .profile-card .mini-stats { margin-left: 0; width: 100%; justify-content: space-between; }

  .booking-link .row { flex-direction: column; align-items: stretch; }
  .booking-link .btn { width: 100%; }

  .month-row { gap: var(--space-3); }
  .month-row .btn { margin-left: 0; width: 100%; }

  .cal-legend { gap: var(--space-3); font-size: var(--text-xs); }
  .calendar { padding: var(--space-2); gap: 2px; }

  .draft-banner { flex-direction: column; align-items: flex-start; }
  .draft-banner .btn { margin-left: 0; width: 100%; }

}

/* ---- Chat on a phone ----------------------------------------------------
   Two panes do not fit. Opening a thread swaps the list out for the
   conversation, with a way back — the pattern every messaging app uses. */
.chat-back { display: none; }

@media (max-width: 860px) {
  .chat-layout.thread-open .thread-list { display: none; }
  .chat-layout:not(.thread-open) .chat-pane { display: none; }
  .chat-back {
    display: inline-flex; align-items: center; gap: var(--space-2);
    font-size: var(--text-sm); font-weight: var(--weight-bold);
    color: var(--action-on-tint); margin-bottom: var(--space-2);
  }
  .chat-pane { min-height: 60vh; max-height: none; }
  .thread-list { max-height: none; }
}

/* ---- Public profile: gallery and a booking bar -------------------------- */
.photo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--space-3);
}
.photo-grid button {
  display: block; border-radius: var(--radius); overflow: hidden;
  border: var(--border-width) solid var(--border);
  background: var(--surface-sunken);
}
.photo-grid img { width: 100%; aspect-ratio: 4/3; object-fit: cover; display: block; }
.photo-grid button:hover img { opacity: .92; }

/* Lightbox */
.lightbox {
  position: fixed; inset: 0; z-index: 200;
  background: hsla(14, 30%, 6%, .92);
  display: grid; place-items: center;
  padding: var(--space-5);
}
.lightbox img { max-width: 100%; max-height: 86vh; border-radius: var(--radius); }
.lightbox-close {
  position: absolute; top: var(--space-5); right: var(--space-5);
  width: 44px; height: 44px; border-radius: var(--radius-full);
  background: var(--surface-raised); color: var(--text-primary);
  display: grid; place-items: center; box-shadow: var(--shadow-3);
}
.lightbox-close svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }
.lightbox-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 44px; height: 44px; border-radius: var(--radius-full);
  background: var(--surface-raised); color: var(--text-primary);
  display: grid; place-items: center; box-shadow: var(--shadow-3);
  font-size: var(--text-xl); font-weight: var(--weight-bold);
}
.lightbox-prev { left: var(--space-4); }
.lightbox-next { right: var(--space-4); }

/* A booking bar pinned to the bottom on phones, because the request form
   sits below a long profile and nobody scrolls that far on spec. */
.book-bar { display: none; }

@media (max-width: 1000px) {
  .book-bar {
    display: flex; align-items: center; gap: var(--space-3);
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 55;
    background: var(--surface-raised);
    border-top: var(--border-width) solid var(--border);
    box-shadow: 0 -4px 16px hsla(14, 30%, 10%, .12);
    padding: var(--space-3) var(--space-5);
    padding-bottom: calc(var(--space-3) + env(safe-area-inset-bottom, 0px));
  }
  .book-bar .price { font-size: var(--text-sm); line-height: 1.3; }
  .book-bar .btn { margin-left: auto; }
  /* Keep the sticky bar from covering the end of the page. */
  body.has-book-bar .site-footer { padding-bottom: var(--space-10); }
}

/* ---- Profile pictures ---------------------------------------------------
   The picture fills the circle that otherwise holds initials, and the camera
   badge stays on top of it. */
.avatar-lg { overflow: visible; }
.avatar-lg img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border-radius: var(--radius-full);
  object-fit: cover;
}
.avatar-lg .avatar-badge { z-index: 2; }

.account-chip-avatar { overflow: hidden; }
.account-chip-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* A picture is worth clicking even where there is no separate button. */
[data-photo] { cursor: pointer; }

/* ---- Horizontal card scroller -------------------------------------------
   Used for the featured vendors on the homepage. Snap points land each card
   against the left edge so a half-card never sits there looking broken. */
.scroller-wrap { position: relative; }

.scroller {
  display: flex;
  gap: var(--space-5);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  /* Room for the card lift on hover and its shadow, which a plain
     overflow container would otherwise clip. */
  padding-block: var(--space-2) var(--space-4);
  scrollbar-width: none;
}
.scroller::-webkit-scrollbar { display: none; }

.scroller > * {
  flex: 0 0 320px;
  scroll-snap-align: start;
}

/* A scrollable region has to be reachable by keyboard, or its content is
   simply unavailable to anyone not using a mouse or a touchscreen. */
.scroller:focus-visible {
  outline: var(--border-width-thick) solid var(--focus-ring);
  outline-offset: 4px;
  border-radius: var(--radius);
}

@media (prefers-reduced-motion: reduce) { .scroller { scroll-behavior: auto; } }

/* Arrows: horizontal scrolling is easy to miss with a mouse, and trackpad
   users get them for free anyway. Hidden on touch, which already knows. */
.scroller-btn {
  position: absolute; top: 38%; z-index: 3;
  width: 44px; height: 44px;
  border-radius: var(--radius-full);
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border-strong);
  box-shadow: var(--shadow-2);
  display: grid; place-items: center;
  font-size: var(--text-xl); line-height: 1;
  color: var(--text-secondary);
  transition: background-color .15s var(--ease), color .15s var(--ease);
}
.scroller-btn:hover { background: var(--surface-sunken); color: var(--text-primary); }
.scroller-prev { left: calc(var(--space-6) * -1); }
.scroller-next { right: calc(var(--space-6) * -1); }

@media (max-width: 1280px) {
  .scroller-prev { left: var(--space-2); }
  .scroller-next { right: var(--space-2); }
}
@media (pointer: coarse), (max-width: 760px) {
  .scroller-btn { display: none; }
}

/* Full bleed on a phone: the row should run off the edge of the screen so
   it reads as scrollable without needing an arrow to say so. */
@media (max-width: 760px) {
  .scroller {
    margin-inline: calc(var(--space-5) * -1);
    padding-inline: var(--space-5);
    scroll-padding-left: var(--space-5);
    gap: var(--space-4);
  }
  .scroller > * { flex-basis: 78%; max-width: 320px; }
}

/* ---- Pay box on the public invoice --------------------------------------- */
.pay-box {
  display: flex; align-items: center; gap: var(--space-5); flex-wrap: wrap;
  background: var(--accent-tint);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-5);
  margin-top: var(--space-7);
}
.pay-box b {
  display: block;
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  color: var(--accent-on-tint);
}
.pay-box p { max-width: 46ch; margin-top: var(--space-2); }
.pay-box .btn { margin-left: auto; }

@media (max-width: 620px) {
  .pay-box { flex-direction: column; align-items: stretch; }
  .pay-box .btn { margin-left: 0; width: 100%; }
}

/* ---- Calendar date picker ------------------------------------------------ */
.datepick {
  border: var(--border-width) solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--surface-raised);
  padding: var(--space-3);
}
.datepick-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-2); margin-bottom: var(--space-2);
}
.datepick-head strong { font-size: var(--text-sm); font-weight: var(--weight-bold); }
.datepick-nav {
  width: 32px; height: 32px; border-radius: var(--radius-sm);
  display: grid; place-items: center;
  font-size: var(--text-lg); line-height: 1; color: var(--text-secondary);
}
.datepick-nav:hover { background: var(--surface-sunken); color: var(--text-primary); }

.datepick-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.datepick-dow {
  text-align: center; font-size: var(--text-xs); font-weight: var(--weight-bold);
  color: var(--text-tertiary); padding-block: var(--space-2);
}
.datepick-pad { aspect-ratio: 1; }

.datepick-day {
  aspect-ratio: 1; min-height: 38px;
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  color: var(--text-primary);
  border: var(--border-width) solid transparent;
  transition: background-color .12s var(--ease), border-color .12s var(--ease);
}
.datepick-day:hover:not(.is-off) { background: var(--surface-sunken); border-color: var(--border-strong); }
.datepick-day.is-chosen {
  background: var(--action); color: var(--action-text);
  font-weight: var(--weight-bold); border-color: var(--action);
}
/* Struck through as well as dimmed: colour alone should never be the only
   signal that a day cannot be chosen. */
.datepick-day.is-busy { text-decoration: line-through; background: var(--surface-sunken); color: var(--text-tertiary); }
.datepick-day.is-off { opacity: var(--opacity-4); cursor: not-allowed; }
.datepick-day.is-chosen.is-off { opacity: 1; cursor: pointer; }

.datepick-key {
  display: flex; align-items: center; gap: var(--space-2);
  margin-top: var(--space-3); font-size: var(--text-xs); color: var(--text-tertiary);
}
.dp-swatch { width: 12px; height: 12px; border-radius: 3px; display: inline-block; }
.dp-swatch-busy { background: var(--surface-sunken); border: 1px solid var(--border-strong); }

@media (pointer: coarse) { .datepick-day { min-height: 44px; } }

/* ---- Gallery viewer ------------------------------------------------------ */
.gallery-cta {
  position: absolute; right: var(--space-3); bottom: var(--space-3); z-index: 3;
  background: var(--surface-raised); color: var(--text-primary);
  box-shadow: var(--shadow-2);
}

.lightbox-stage {
  position: relative;
  max-width: min(1100px, 92vw);
  width: 100%;
  display: flex; flex-direction: column; align-items: center; gap: var(--space-4);
}
.lightbox-stage img {
  max-width: 100%; max-height: 74vh;
  border-radius: var(--radius);
  object-fit: contain;
  /* Horizontal swipe on touch without hijacking vertical page scroll. */
  touch-action: pan-y;
  user-select: none;
}
.lightbox-bar {
  display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap;
  justify-content: center;
  background: var(--surface-raised);
  border-radius: var(--radius-full);
  padding: var(--space-2) var(--space-3) var(--space-2) var(--space-5);
  box-shadow: var(--shadow-3);
}
.lightbox-count { font-size: var(--text-sm); color: var(--text-tertiary); white-space: nowrap; }
.lightbox-caption {
  font-size: var(--text-sm); color: var(--text-secondary);
  max-width: 46ch; text-align: center;
}
@media (max-width: 620px) {
  .lightbox-stage img { max-height: 58vh; }
  .lightbox-bar { width: 100%; border-radius: var(--radius); justify-content: space-between; }
}

/* ---- Contracts ----------------------------------------------------------- */
.contract-body {
  margin-top: var(--space-6);
  padding-top: var(--space-6);
  border-top: var(--border-width) solid var(--border);
  white-space: pre-wrap;           /* the body is plain text; keep its line breaks */
  overflow-wrap: anywhere;
  font-size: var(--text-base);
  line-height: var(--leading-loose);
  color: var(--text-primary);
  max-width: 72ch;
}
.sign-box, .signed-block {
  margin-top: var(--space-7);
  padding: var(--space-5);
  border-radius: var(--radius);
  border: var(--border-width) solid var(--border);
}
.sign-box { background: var(--surface-sunken); }
.signed-block { background: var(--accent-tint); border-color: var(--accent); }
.signature-preview {
  min-height: 48px;
  margin-top: var(--space-4);
  padding-bottom: var(--space-2);
  border-bottom: var(--border-width-thick) solid var(--border-strong);
  font-family: 'Segoe Script', 'Brush Script MT', 'Snell Roundhand', cursive;
  font-size: var(--text-3xl);
  line-height: 1.2;
  color: var(--text-primary);
  overflow-wrap: anywhere;
}
.signature-preview.is-final { border-bottom-color: var(--accent); }
.fingerprint {
  font-family: ui-monospace, 'Cascadia Mono', Consolas, monospace;
  font-size: var(--text-xs);
  word-break: break-all;
  color: var(--text-secondary);
}
.contract-editor { min-height: 360px; font-family: ui-monospace, 'Cascadia Mono', Consolas, monospace; font-size: var(--text-sm); }

@media print {
  .sign-box { display: none !important; }
  .contract-body { max-width: none; }
}

/* ---- Team and payroll ---------------------------------------------------- */
.lead.is-inactive { opacity: .7; }
.table-scroll { overflow-x: auto; }
.pay-table { width: 100%; border-collapse: collapse; background: var(--surface-raised); border-radius: var(--radius); }
.pay-table th, .pay-table td {
  padding: var(--space-3) var(--space-4);
  border-bottom: var(--border-width) solid var(--border);
  text-align: left; font-size: var(--text-sm); white-space: nowrap;
}
.pay-table th { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: .06em; color: var(--text-tertiary); }
.pay-table td:not(:first-child), .pay-table th:not(:first-child) { text-align: right; }
.pay-table tfoot th { color: var(--text-primary); font-size: var(--text-sm); text-transform: none; letter-spacing: 0; }
.tax-note {
  display: flex; gap: var(--space-3); align-items: flex-start;
  background: var(--gold-100); color: var(--gold-800);
  border-radius: var(--radius-sm); padding: var(--space-3) var(--space-4);
  font-size: var(--text-sm); margin-bottom: var(--space-5);
}
.tax-note svg { width: 18px; height: 18px; flex: none; margin-top: 2px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }

/* ---- Vendor dashboard: section bar -------------------------------------
   One quiet row that scrolls sideways instead of wrapping. The active
   section is marked with an underline rather than a filled pill, so the
   bar stops competing with the content under it. */
.dash-nav {
  display: flex; align-items: center; gap: var(--space-3);
  border-bottom: var(--border-width) solid var(--border);
  margin-bottom: var(--space-6);
}
.dash-nav-scroll {
  flex: 1; min-width: 0;
  overflow-x: auto; overflow-y: hidden;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.dash-nav-scroll::-webkit-scrollbar { display: none; }
.dash-nav.fade-right .dash-nav-scroll {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 48px), transparent);
          mask-image: linear-gradient(to right, #000 calc(100% - 48px), transparent);
}
.dash-nav.fade-left .dash-nav-scroll {
  -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 48px), transparent);
          mask-image: linear-gradient(to left, #000 calc(100% - 48px), transparent);
}
.dash-nav.fade-left.fade-right .dash-nav-scroll {
  -webkit-mask-image: linear-gradient(to right, transparent, #000 48px, #000 calc(100% - 48px), transparent);
          mask-image: linear-gradient(to right, transparent, #000 48px, #000 calc(100% - 48px), transparent);
}
.dnav { display: flex; gap: var(--space-1, 4px); }
.dtab {
  flex: none; display: inline-flex; align-items: center; gap: var(--space-2);
  min-height: 48px; padding: 0 var(--space-3);
  font-size: var(--text-sm); font-weight: var(--weight-medium);
  color: var(--text-secondary); white-space: nowrap;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}
.dtab:hover { color: var(--text-primary); background: var(--surface-sunken); }
.dtab.is-active { color: var(--text-primary); box-shadow: inset 0 calc(-1 * var(--border-width-thick)) 0 var(--action); }
.dtab:focus-visible { outline-offset: -2px; }
.dtab-count {
  min-width: 20px; height: 20px; padding: 0 6px;
  border-radius: var(--radius-full);
  background: var(--surface-sunken); color: var(--text-secondary);
  font-size: var(--text-xs); line-height: 20px; text-align: center;
  font-variant-numeric: tabular-nums;
}
.dtab.is-active .dtab-count { background: var(--action-tint); color: var(--action-on-tint); }
.dash-customize { flex: none; }
.dash-customize svg {
  width: 18px; height: 18px; fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round;
}
@media (max-width: 640px) {
  .dash-customize-text { display: none; }
  .dash-customize { padding-inline: var(--space-3); }
}

/* ---- Customize panel ---------------------------------------------------- */
.customize-panel { max-width: 560px; margin-bottom: var(--space-6); }
.cz-list { list-style: none; margin: var(--space-5) 0; padding: 0; display: grid; gap: var(--space-2); }
.cz-row {
  display: flex; align-items: center; gap: var(--space-2);
  padding: var(--space-1, 4px) var(--space-2);
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-sm);
}
.cz-row.is-dragging {
  border-color: var(--border-strong);
  box-shadow: 0 8px 24px hsla(20, 30%, 20%, .14);
  position: relative; z-index: 1;
}
.cz-grip {
  flex: none; display: grid; place-items: center;
  width: 32px; height: 44px;
  color: var(--text-tertiary); cursor: grab;
  touch-action: none;             /* the grip drags; it must not scroll the page */
}
.cz-row.is-dragging .cz-grip { cursor: grabbing; }
.cz-grip svg { width: 16px; height: 16px; fill: currentColor; }
.cz-label { flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--space-3); min-height: 44px; cursor: pointer; }
.cz-name { font-weight: var(--weight-medium); }
.cz-row.is-off .cz-name { color: var(--text-tertiary); }
.cz-note { font-size: var(--text-xs); color: var(--text-tertiary); }
.cz-move { flex: none; display: flex; }
.cz-move button {
  width: 40px; height: 40px; display: grid; place-items: center;
  border-radius: var(--radius-sm); color: var(--text-secondary);
}
.cz-move button:hover:not(:disabled) { background: var(--surface-sunken); color: var(--text-primary); }
.cz-move button:disabled { opacity: .3; cursor: default; }
.cz-move svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }

.cz-switch {
  -webkit-appearance: none; appearance: none;
  flex: none; position: relative; margin: 0;
  width: 40px; height: 24px; border-radius: var(--radius-full);
  background: var(--border-strong); cursor: pointer;
  transition: background .15s ease;
}
.cz-switch::after {
  content: ""; position: absolute; top: 3px; left: 3px;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--surface-raised);
  box-shadow: 0 1px 2px hsla(0, 0%, 0%, .25);
  transition: transform .15s ease;
}
.cz-switch:checked { background: var(--accent); }
.cz-switch:checked::after { transform: translateX(16px); }
.cz-switch:disabled { opacity: .55; cursor: not-allowed; }
@media (prefers-reduced-motion: reduce) {
  .cz-switch, .cz-switch::after { transition: none; }
}

/* ---- Unread messages ---------------------------------------------------- */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.unread-badge {
  display: inline-grid; place-items: center;
  min-width: 20px; height: 20px; padding: 0 6px;
  border-radius: var(--radius-full);
  background: var(--action); color: var(--action-text);
  font-size: var(--text-xs); font-weight: 700; line-height: 1;
  font-variant-numeric: tabular-nums;
  vertical-align: middle;
}
.unread-badge[hidden] { display: none; }
.btn .unread-badge, .pill .unread-badge { margin-left: var(--space-2); }
.dtab-count.is-alert,
.dtab.is-active .dtab-count.is-alert { background: var(--action); color: var(--action-text); font-weight: 700; }

.thread { position: relative; }
.thread .unread-badge { position: absolute; top: var(--space-4); right: var(--space-4); }
.thread.has-unread b { padding-right: var(--space-7); }

.account-chip { position: relative; }
.account-chip .unread-badge {
  position: absolute; top: -6px; right: -6px;
  min-width: 18px; height: 18px; padding: 0 5px; font-size: 11px;
  box-shadow: 0 0 0 2px var(--surface);
}

.msg-divider {
  align-self: stretch;
  display: flex; align-items: center; gap: var(--space-3);
  margin-block: var(--space-2);
  font-size: var(--text-xs); font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--action-on-tint);
}
.msg-divider::before, .msg-divider::after { content: ""; flex: 1; border-top: var(--border-width) solid var(--action); }

/* ---- Invoice that cannot be paid online (yet) --------------------------- */
.pay-off {
  margin-top: var(--space-6);
  padding: var(--space-4) var(--space-5);
  border: var(--border-width) dashed var(--border-strong);
  border-radius: var(--radius);
  background: var(--surface-sunken);
}
.pay-off p { margin-top: var(--space-2); }

/* ---- Projects ----------------------------------------------------------- */
.seg {
  display: inline-flex; gap: 2px; padding: 3px;
  background: var(--surface-sunken); border-radius: var(--radius-full);
}
.seg-btn {
  min-height: 36px; padding: 0 var(--space-4);
  border-radius: var(--radius-full);
  font-size: var(--text-sm); font-weight: var(--weight-medium);
  color: var(--text-secondary);
}
.seg-btn:hover { color: var(--text-primary); }
.seg-btn.is-active {
  background: var(--surface-raised); color: var(--text-primary);
  box-shadow: 0 1px 2px hsla(0, 0%, 0%, .12);
}

.pj-stats {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-3); margin-bottom: var(--space-5);
}
.pj-stats:empty { display: none; }
.pj-stat {
  padding: var(--space-3) var(--space-4);
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border); border-radius: var(--radius);
}
.pj-stat b { display: block; font-family: var(--font-display); font-size: var(--text-xl); line-height: 1.2; }
.pj-stat span { font-size: var(--text-xs); color: var(--text-tertiary); }
@media (max-width: 720px) { .pj-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.pj-import {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  flex-wrap: wrap; margin-bottom: var(--space-5);
  padding: var(--space-3) var(--space-4);
  background: var(--action-tint); color: var(--action-on-tint);
  border-radius: var(--radius); font-size: var(--text-sm); font-weight: var(--weight-medium);
}
.pj-import[hidden] { display: none; }

/* Board: columns scroll sideways, and snap into place on a phone. */
.pj-board {
  display: flex; gap: var(--space-3);
  overflow-x: auto; padding-bottom: var(--space-3);
  scroll-snap-type: x proximity; -webkit-overflow-scrolling: touch;
}
.pj-col {
  flex: 0 0 272px; scroll-snap-align: start;
  display: flex; flex-direction: column;
  background: var(--surface-sunken); border-radius: var(--radius);
  min-height: 180px;
}
.pj-col-head { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-3) var(--space-4); }
.pj-col-head h3 { font-size: var(--text-sm); font-weight: 700; }
.pj-col-count {
  min-width: 22px; padding: 0 7px; line-height: 20px; text-align: center;
  font-size: var(--text-xs); color: var(--text-secondary);
  background: var(--surface-raised); border-radius: var(--radius-full);
}
.pj-col-sum { margin-left: auto; font-size: var(--text-xs); color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.pj-col-body {
  flex: 1; display: grid; align-content: start; gap: var(--space-2);
  padding: 0 var(--space-2) var(--space-2);
  border-radius: var(--radius);
  transition: background .12s ease, box-shadow .12s ease;
}
.pj-col-body.is-over { background: var(--action-tint); box-shadow: inset 0 0 0 2px var(--action); }
.pj-col-empty { padding: var(--space-5) 0; text-align: center; font-size: var(--text-xs); color: var(--text-tertiary); }

.pj-card {
  display: grid; gap: 6px; text-align: left;
  padding: var(--space-3);
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border); border-radius: var(--radius-sm);
  cursor: pointer;
}
.pj-card:hover { border-color: var(--border-strong); }
.pj-card.is-dragging { opacity: .45; }
.pj-card-title { font-size: var(--text-sm); line-height: 1.3; }
.pj-card-client { font-size: var(--text-xs); color: var(--text-secondary); }
.pj-card-meta { display: flex; justify-content: space-between; gap: var(--space-2); font-size: var(--text-xs); color: var(--text-secondary); }
.pj-card-value { font-weight: 700; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.pj-card-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.pj-card-foot:empty { display: none; }
.pj-card .unread-badge { margin-left: auto; min-width: 18px; height: 18px; font-size: 11px; }
.pj-chip {
  padding: 0 7px; line-height: 20px; white-space: nowrap;
  font-size: 11px; font-weight: var(--weight-medium);
  background: var(--surface-sunken); color: var(--text-secondary);
  border-radius: var(--radius-full);
}
.pj-chip.is-good { background: var(--accent-tint); color: var(--accent-on-tint); }
.pj-chip.is-due  { background: var(--gold-100);   color: var(--gold-800); }
.pj-chip.is-warn { background: var(--red-100);    color: var(--red-800); }

.pj-table { width: 100%; border-collapse: collapse; background: var(--surface-raised); border-radius: var(--radius); }
.pj-table th, .pj-table td {
  padding: var(--space-3) var(--space-4); text-align: left; vertical-align: top;
  border-bottom: var(--border-width) solid var(--border); font-size: var(--text-sm);
}
.pj-table th { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: .06em; color: var(--text-tertiary); }
.pj-table .btn-link { font-weight: 700; text-align: left; }

.pj-archived-toggle {
  display: inline-flex; align-items: center; gap: var(--space-2);
  margin-top: var(--space-4); min-height: 44px;
  font-size: var(--text-sm); color: var(--text-secondary); cursor: pointer;
}

/* One project */
.pj-back {
  display: inline-flex; align-items: center; gap: var(--space-2);
  min-height: 44px; margin-bottom: var(--space-2);
  font-size: var(--text-sm); color: var(--text-secondary);
}
.pj-back:hover { color: var(--text-primary); }
.pj-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--space-4); flex-wrap: wrap; margin-bottom: var(--space-5);
}
.pj-head h2 { font-size: var(--text-2xl); }
.pj-head-meta { margin-top: 4px; font-size: var(--text-sm); color: var(--text-secondary); }
.pj-stage-field { min-width: 200px; margin: 0; }
.pj-grid { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: var(--space-5); align-items: start; }
@media (max-width: 900px) { .pj-grid { grid-template-columns: 1fr; } }
.pj-main, .pj-side { display: grid; gap: var(--space-5); min-width: 0; }
.pj-section h3 {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3);
  margin-bottom: var(--space-3); font-size: var(--text-base);
}
.pj-progress { height: 6px; margin-bottom: var(--space-3); border-radius: var(--radius-full); background: var(--surface-sunken); overflow: hidden; }
.pj-progress > span { display: block; height: 100%; background: var(--accent); }

.pj-tasks { list-style: none; margin: 0; padding: 0; }
.pj-task { display: flex; align-items: center; gap: var(--space-2); border-bottom: var(--border-width) solid var(--border); }
.pj-task label { flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--space-3); min-height: 44px; cursor: pointer; }
.pj-task input[type="checkbox"] { flex: none; width: 18px; height: 18px; accent-color: var(--accent); }
.pj-task-title { overflow-wrap: anywhere; }
.pj-task.is-done .pj-task-title { text-decoration: line-through; color: var(--text-tertiary); }
.pj-task-due { font-size: var(--text-xs); color: var(--text-tertiary); white-space: nowrap; }
.pj-task.is-overdue .pj-task-due { color: var(--red-800); font-weight: 700; }
.pj-task-del {
  flex: none; width: 36px; height: 36px; display: grid; place-items: center;
  border-radius: var(--radius-sm); color: var(--text-tertiary);
}
.pj-task-del:hover { background: var(--surface-sunken); color: var(--text-primary); }
.pj-task-add { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-4); }
.pj-task-add [name="title"] { flex: 1 1 220px; }
.pj-task-add [name="due_date"] { flex: 0 0 auto; width: auto; }

.pj-money { display: grid; gap: var(--space-2); margin: 0; }
.pj-money div { display: flex; justify-content: space-between; gap: var(--space-3); font-size: var(--text-sm); }
.pj-money dt { color: var(--text-secondary); }
.pj-money dd { margin: 0; font-weight: 700; font-variant-numeric: tabular-nums; }
.pj-money .is-due dd { color: var(--gold-800); }
.pj-money .is-total { padding-top: var(--space-2); border-top: var(--border-width) solid var(--border); }

.pj-docs { list-style: none; margin: 0 0 var(--space-4); padding: 0; display: grid; gap: var(--space-3); }
.pj-doc { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); font-size: var(--text-sm); }
.pj-doc a, .pj-doc .btn-link { font-weight: var(--weight-medium); }
.pj-doc-kind { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: .06em; color: var(--text-tertiary); }
.pj-doc .badge { margin-left: auto; }

.pj-quote {
  margin-top: var(--space-3); padding-left: var(--space-3);
  border-left: 3px solid var(--border);
  font-size: var(--text-sm); color: var(--text-secondary); white-space: pre-wrap;
}

.pj-timeline { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-3); }
.pj-timeline li { display: grid; grid-template-columns: 10px 1fr; gap: var(--space-3); font-size: var(--text-sm); }
.pj-timeline li::before { content: ""; width: 10px; height: 10px; margin-top: 5px; border-radius: 50%; background: var(--border-strong); }
.pj-timeline time { display: block; font-size: var(--text-xs); color: var(--text-tertiary); }
.pj-danger { text-align: right; }

/* ---- City search -------------------------------------------------------- */
.combo { position: relative; display: block; }
.combo-list {
  position: absolute; z-index: 60; top: calc(100% + 6px); left: 0; right: 0;
  min-width: 240px; max-height: 300px; overflow-y: auto;
  display: block; padding: var(--space-1, 4px);
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow-3);
  /* Reset what a surrounding label (the search bar's is small caps) passes down. */
  text-transform: none; letter-spacing: normal; font-weight: 400;
}
.combo-list[hidden] { display: none; }
.combo-opt {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  min-height: 44px; padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm); cursor: pointer;
  font-size: var(--text-sm); color: var(--text-primary);
}
.combo-opt.is-active, .combo-opt:hover { background: var(--surface-sunken); }
.combo-opt mark { background: none; color: inherit; font-weight: 700; }
.combo-opt small { flex: none; font-size: var(--text-xs); color: var(--text-tertiary); }
.combo-add-opt {
  margin-top: 2px; border-top: var(--border-width) solid var(--border);
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  color: var(--action-on-tint); font-weight: 600;
}
.combo-empty { display: block; padding: var(--space-3); font-size: var(--text-sm); color: var(--text-tertiary); }

.combo-add {
  grid-column: 1 / -1;            /* spans the form's two columns */
  display: grid; gap: var(--space-2);
  padding: var(--space-3); background: var(--surface-sunken); border-radius: var(--radius);
}
.combo-add[hidden] { display: none; }
.combo-add-row { display: flex; flex-wrap: wrap; gap: var(--space-2); }
/* Basis kept under the country select's content width so Country, City,
   State, Add and Cancel all still fit on one line; it grows into the slack. */
.combo-add-row .input { flex: 1 1 110px; }
.combo-add-row .select { flex: 0 0 110px; width: auto; }
.combo-add-msg { margin: 0; color: var(--text-secondary); }
.combo-add-msg.is-error { color: var(--red-800); }


/* ---- Picking photos to import ------------------------------------------
   A contact sheet: the photo is the label, so the tick sits on it rather
   than beside it and the whole square is the target. */
.ig-picker { margin-top: var(--space-4); }
.ig-grid {
  display: grid; gap: var(--space-2);
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  max-height: 420px; overflow-y: auto;
}
.ig-pick { position: relative; cursor: pointer; display: block; }
.ig-pick img {
  display: block; width: 100%; aspect-ratio: 1; object-fit: cover;
  border-radius: var(--radius-sm);
  transition: opacity .15s var(--ease);
}
/* Off-screen rather than display:none, so it is still focusable and the
   keyboard can pick photos too. */
.ig-pick input {
  position: absolute; opacity: 0; width: 1px; height: 1px;
  margin: 0; pointer-events: none;
}
.ig-pick-tick {
  position: absolute; top: 8px; right: 8px;
  width: 26px; height: 26px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, .9); color: transparent;
  border: var(--border-width) solid var(--border-strong);
  font-size: var(--text-sm); font-weight: 700;
}
.ig-pick input:checked ~ .ig-pick-tick {
  background: var(--action); border-color: var(--action); color: var(--action-text);
}
.ig-pick input:checked ~ img { opacity: .72; }
.ig-pick input:focus-visible ~ .ig-pick-tick { outline: 2px solid var(--action); outline-offset: 2px; }

/* The connection line above the gallery. Quiet while everything works; gold
   when Instagram has stopped answering and the vendor has to do something. */
.ig-sync {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--space-2) var(--space-4);
  margin-top: var(--space-3); padding: var(--space-3);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius); background: var(--surface-sunken);
}
.ig-sync.is-stale { background: var(--gold-100); border-color: var(--gold-500); }
.ig-sync.is-stale .ig-sync-who { color: var(--gold-800); }
.ig-sync-who {
  margin: 0; flex: 1 1 260px;
  font-size: var(--text-sm); color: var(--text-secondary);
}
.ig-sync-acts { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.ig-sync [data-ig-sync-status] { flex-basis: 100%; margin: 0; }

/* The tray. Deliberately not shaped like the gallery grid: these photos are
   not in the gallery yet, and looking different is how you can tell. */
.ig-tray { margin-top: var(--space-4); border-color: var(--action); }
.ig-tray-grid {
  display: grid; gap: var(--space-3);
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
}
.ig-tray-item { margin: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.ig-tray-item img {
  display: block; width: 100%; aspect-ratio: 1; object-fit: cover;
  border-radius: var(--radius-sm);
}
.ig-tray-item figcaption { margin: 0; }
.ig-tray-acts { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.ig-tray-acts .btn { flex: 1 1 auto; }

/* ---- Choosing a package -------------------------------------------------
   The button sits at the foot of the card so every card ends the same way,
   whatever length its list of inclusions. */
.package { display: flex; flex-direction: column; }
.package .tick-list { flex: 1; }
.package-pick { margin-top: var(--space-4); }
/* A ring, not a fill: the featured card already has a look of its own and
   chosen has to read on top of it. */
.package.is-chosen {
  outline: var(--border-width-thick) solid var(--action);
  outline-offset: -1px;
}

/* What the form will send, shown before it sends it. */
.picked-pkg-row {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--action-tint); color: var(--action-on-tint);
  border-radius: var(--radius);
}
.picked-pkg-row b { flex: 1; min-width: 0; overflow-wrap: anywhere; font-size: var(--text-sm); }

/* ---- Signing in with a provider -----------------------------------------
   The rule runs behind the word rather than either side of it, so one
   element does the job and the two halves cannot end up different lengths. */
.oauth { margin-top: var(--space-5); }
.oauth-or {
  position: relative; text-align: center; margin: 0 0 var(--space-4);
  font-size: var(--text-sm); color: var(--text-secondary);
}
.oauth-or::before {
  content: ""; position: absolute; inset-inline: 0; top: 50%;
  border-top: var(--border-width) solid var(--border);
}
.oauth-or span { position: relative; padding: 0 var(--space-3); background: var(--surface-raised); }
.oauth-btn {
  display: flex; align-items: center; justify-content: center;
  gap: var(--space-3); margin-bottom: var(--space-2);
}
/* The Google mark is full colour and must not be recoloured by the button. */
.oauth-btn svg { flex: none; }
.oauth-note { margin-top: var(--space-3); text-align: center; }
.oauth-note a { text-decoration: underline; }

/* ---- Agreeing to the terms at signup ------------------------------------
   .check already tops-aligns the box and sizes the text; this sentence just
   wraps to two lines, and its links have to read as links. */
.check-terms span { line-height: var(--leading-snug); }
.check-terms a { text-decoration: underline; }

/* ---- First-run tour -----------------------------------------------------
   The dimming is one huge box-shadow spread from the cutout, so there is a
   single element over the page rather than four strips to keep aligned. */
.tour { position: fixed; inset: 0; z-index: 9000; }
.tour-spot {
  position: fixed; border-radius: var(--radius);
  box-shadow: 0 0 0 9999px rgba(17, 12, 9, .62);
  outline: 2px solid var(--surface-raised); outline-offset: 2px;
  transition: top .18s ease, left .18s ease, width .18s ease, height .18s ease;
  pointer-events: none;
}
.tour-bubble {
  position: fixed; width: min(340px, calc(100vw - 16px));
  background: var(--surface-raised); color: var(--text-primary);
  border-radius: var(--radius-lg); padding: var(--space-5);
  box-shadow: 0 18px 44px rgba(17, 12, 9, .28);
}
.tour-bubble h2 { font-size: var(--text-lg); margin: 0 0 var(--space-2); }
.tour-bubble p { margin: 0; }
.tour-step {
  font-size: var(--text-sm); color: var(--text-secondary);
  margin-bottom: var(--space-1) !important; letter-spacing: .02em;
}
.tour-actions {
  display: flex; align-items: center; gap: var(--space-2);
  margin-top: var(--space-4);
}
.tour-spacer { flex: 1; }
/* The page keeps its scroll position while the tour is up: scrolling it away
   would leave the spotlight pointing at nothing. */
body.tour-open { overflow: hidden; }
@media (prefers-reduced-motion: reduce) { .tour-spot { transition: none; } }

/* ---- Folded form sections ----------------------------------------------
   Tax and social links are the two blocks most vendors leave alone. They
   stay in the form but out of the way, and dashboard.js opens one that
   already holds something so nothing is ever hidden from its owner. */
.form-fold {
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius); padding: 0 var(--space-4);
}
.form-fold summary {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3); min-height: 44px; cursor: pointer;
  font-weight: 600; color: var(--text-primary);
}
.form-fold[open] summary { margin-bottom: var(--space-2); }
.form-fold-hint { font-weight: 400; font-size: var(--text-sm); color: var(--text-secondary); }
/* The last control inside needs the padding the summary does not. */
.form-fold > :last-child { margin-bottom: var(--space-4); }

/* ---- Calendar sync help ------------------------------------------------- */
.cal-help { margin-top: var(--space-3); font-size: var(--text-sm); color: var(--text-secondary); }
.cal-help summary {
  display: inline-flex; align-items: center; min-height: 44px;
  cursor: pointer; font-weight: 600; color: var(--text-primary);
}
.cal-help p { margin-top: var(--space-2); max-width: 64ch; }

/* ---- Booking page link after a request ---------------------------------- */
.form-status .form-status-link { margin-block: var(--space-3) var(--space-2); }
.form-status small { display: inline-block; font-size: var(--text-xs); line-height: 1.5; opacity: .9; }

/* ---- Availability on the shortlist -------------------------------------- */
.avail-tag {
  display: inline-block; margin-bottom: var(--space-2);
  padding: 2px 8px; border-radius: var(--radius-full);
  font-size: var(--text-xs); font-weight: 600; line-height: 1.5;
  background: var(--surface-sunken); color: var(--text-secondary);
}
.avail-tag.is-free    { background: var(--accent-tint); color: var(--accent-on-tint); }
.avail-tag.is-partial { background: var(--gold-100);    color: var(--gold-800); }
.avail-tag.is-booked  { background: var(--red-100);     color: var(--red-800); }
.brief-avail.is-warn  { color: var(--red-800); font-weight: 600; }

/* ---- Header on phones ---------------------------------------------------- */
.site-nav .nav-auth { font: inherit; text-align: left; color: var(--text-secondary); }
@media (min-width: 981px) { .site-nav .nav-auth { display: none; } }
@media (max-width: 980px) {
  .site-nav .nav-auth {
    padding: var(--space-3); border-radius: var(--radius-sm);
    font-size: var(--text-base); font-weight: var(--weight-medium); color: var(--text-primary);
  }
  .site-nav .nav-auth[hidden] { display: none; }
  [data-auth-slot] .btn { padding-inline: var(--space-3); }
}
/* The narrowest phones: make room for sign-in by dropping the theme switch,
   which follows the phone's own light/dark setting anyway. */
@media (max-width: 400px) {
  .header-actions { gap: var(--space-1); }
  .header-actions .theme-toggle { display: none; }
}

/* ---- Vendor cover ------------------------------------------------------- */
.vendor-cover.thumb {
  position: relative; aspect-ratio: 21 / 8; height: auto; min-height: 0;
  border-radius: var(--radius-lg); overflow: hidden;
}
.vendor-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cover-cta {
  position: absolute; right: var(--space-4); bottom: var(--space-4); z-index: 3;
  display: inline-flex; align-items: center; gap: var(--space-2);
  min-height: 44px; padding-inline: var(--space-4);
  background: var(--surface-raised); color: var(--text-primary);
  border: 0; box-shadow: var(--shadow-2);
  font-size: var(--text-sm); font-weight: var(--weight-medium);
}
.cover-cta:hover { background: var(--surface-raised); color: var(--text-primary); transform: translateY(-1px); }
.cover-cta svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
@media (max-width: 700px) {
  .vendor-cover.thumb { aspect-ratio: 4 / 3; border-radius: var(--radius); }
  .cover-cta { right: var(--space-3); bottom: var(--space-3); }
}

/* ---- Vendor's own questions --------------------------------------------- */
.q-list { display: grid; gap: var(--space-3); }
.q-row {
  display: flex; gap: var(--space-3); align-items: flex-start;
  padding: var(--space-4); border: var(--border-width) solid var(--border);
  border-radius: var(--radius); background: var(--surface-raised);
}
.q-main { flex: 1; min-width: 0; display: grid; gap: var(--space-3); }
.q-meta { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }
.q-meta .select { width: auto; flex: 1 1 160px; }
.q-req { display: inline-flex; align-items: center; gap: var(--space-2); min-height: 44px; font-size: var(--text-sm); cursor: pointer; }
.q-req input { width: 18px; height: 18px; accent-color: var(--accent); }
.q-tools { flex: none; display: grid; gap: 2px; }
.q-tools button {
  width: 36px; height: 36px; display: grid; place-items: center;
  border-radius: var(--radius-sm); color: var(--text-secondary); font-size: var(--text-base);
}
.q-tools button:hover:not(:disabled) { background: var(--surface-sunken); color: var(--text-primary); }
.q-tools button:disabled { opacity: .3; cursor: default; }
.q-suggest { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-3); }
.chip-btn {
  min-height: 36px; padding: 0 var(--space-3);
  border: var(--border-width) solid var(--border-strong); border-radius: var(--radius-full);
  font-size: var(--text-sm); color: var(--text-secondary); background: var(--surface-raised);
}
.chip-btn:hover:not(:disabled) { color: var(--text-primary); border-color: var(--text-tertiary); }
.chip-btn:disabled { opacity: .45; }

/* Answers on a booking and in a project */
.lead-answers { display: grid; gap: var(--space-2); margin: var(--space-3) 0 0; font-size: var(--text-sm); }
.lead-answers div { display: grid; gap: 2px; }
.lead-answers dt { color: var(--text-tertiary); font-size: var(--text-xs); }
.lead-answers dd { margin: 0; color: var(--text-primary); white-space: pre-wrap; overflow-wrap: anywhere; }

/* ---- Vendor page on phones ----------------------------------------------
   The page stretched to 394px on a 360px phone. The date picker's day cells
   were squares at least 38px wide (44px on touch), so seven of them plus
   padding made the booking card 370px; and a grid column sized "1fr" grows
   to its widest child, so the whole page followed it. Let the picker's
   columns shrink, and stop the column growing past the screen. */
.datepick-grid { grid-template-columns: repeat(7, minmax(0, 1fr)); }
@media (max-width: 1000px) {
  .detail { grid-template-columns: minmax(0, 1fr); }
  .detail > * { min-width: 0; }
}
@media (max-width: 480px) {
  .book-card { padding: var(--space-5) var(--space-4); }
  .datepick { padding: var(--space-2); }
  /* Days keep a comfortable height to tap while their width shrinks. */
  .datepick-day { aspect-ratio: auto; min-height: 0; height: 40px; }
  .datepick-pad { aspect-ratio: auto; height: 40px; }
}

/* ---- Automatic messages ------------------------------------------------- */
.auto-list { display: grid; gap: var(--space-4); max-width: 760px; }
.auto-card { display: grid; gap: var(--space-4); }
.auto-head { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--space-4); }
.auto-head h3 { font-size: var(--text-lg); margin-bottom: var(--space-1); }
.auto-toggle {
  flex: none; display: inline-flex; align-items: center; gap: var(--space-2);
  min-height: 44px; cursor: pointer; font-size: var(--text-sm); font-weight: 600;
}
.auto-days .row { align-items: center; }
.auto-chips { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: calc(-1 * var(--space-2)); }
.auto-preview {
  margin: 0; padding: var(--space-3);
  background: var(--surface-sunken); border-radius: var(--radius-sm);
  font-size: var(--text-sm); color: var(--text-secondary);
  white-space: pre-wrap; overflow-wrap: anywhere;
}

/* ---- "More tools" for new vendors --------------------------------------- */
.tools-hint {
  position: relative; display: grid; gap: var(--space-3);
  margin: calc(-1 * var(--space-3)) 0 var(--space-6);
  padding: var(--space-4) var(--space-8) var(--space-4) var(--space-5);
  background: var(--action-tint); border-radius: var(--radius);
}
.tools-hint[hidden] { display: none; }
.tools-hint-text b { display: block; color: var(--action-on-tint); }
.tools-hint-text span { font-size: var(--text-sm); color: var(--action-on-tint); }
.tools-hint-chips { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.tool-chip {
  display: grid; gap: 2px; text-align: left;
  min-height: 44px; padding: var(--space-2) var(--space-3);
  background: var(--surface-raised); border: var(--border-width) solid var(--border);
  border-radius: var(--radius-sm);
}
.tool-chip:hover { border-color: var(--border-strong); }
.tool-chip b { font-size: var(--text-sm); color: var(--text-primary); }
.tool-chip span { font-size: var(--text-xs); color: var(--text-tertiary); }
.tools-hint-close { position: absolute; top: var(--space-2); right: var(--space-2); color: var(--action-on-tint); }
.tools-hint-close svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; }

/* Customize panel: what each section is for */
.cz-text { display: grid; min-width: 0; }
.cz-desc { font-size: var(--text-xs); color: var(--text-tertiary); font-weight: 400; }

/* ---- Leaving a review (booking page) -------------------------------------
   Five radio buttons drawn as stars. The inputs stay in the page, just
   invisible, so arrow keys and screen readers work as a normal radio group;
   thread.js lights the stars up to the one hovered or chosen. */
.review-box-title { font-size: var(--text-xl); margin-bottom: var(--space-2); }
.star-input { border: 0; padding: 0; margin: 0; min-width: 0; }
.star-input legend { padding: 0; margin-bottom: var(--space-2); }
.star-input-row { display: flex; gap: var(--space-1); }
.star-input-row input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; }
.star-input-row label {
  display: grid; place-items: center;
  width: 44px; height: 44px; border-radius: var(--radius-sm); cursor: pointer;
}
.star-input-row svg {
  width: 32px; height: 32px;
  fill: none; stroke: var(--text-tertiary); stroke-width: 1.4; stroke-linejoin: round;
}
.star-input-row label.is-on svg { fill: var(--gold-500); stroke: var(--gold-500); }
:root[data-theme="dark"] .star-input-row label.is-on svg { fill: var(--gold-800); stroke: var(--gold-800); }
.star-input-row input:focus-visible + label { outline: 2px solid var(--action); outline-offset: 2px; }
.star-input-hint { font-size: var(--text-sm); color: var(--text-tertiary); min-height: 1.5em; margin-top: var(--space-1); }

/* ---- Files: sending in chat -------------------------------------------- */
.chat-composer .input { min-width: 0; }     /* the paperclip must not push Send off a phone */
.chat-attach {
  flex: none; width: 44px; height: 44px; display: grid; place-items: center;
  border-radius: var(--radius-full); color: var(--text-secondary);
  border: var(--border-width) solid var(--border-strong); background: var(--surface-raised);
}
.chat-attach:hover { color: var(--text-primary); }
.chat-attach svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.chat-attach.is-busy { opacity: .5; cursor: progress; }

.msg-file {
  display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 2px var(--space-3);
  padding: var(--space-2) var(--space-3); margin-bottom: var(--space-2);
  border: var(--border-width) solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface-raised); color: var(--text-primary); text-decoration: none;
}
.msg-file:hover { border-color: var(--border-strong); }
.msg-file img {
  grid-column: 1 / -1; width: 100%; max-height: 220px; object-fit: cover;
  border-radius: var(--radius-sm); margin-bottom: var(--space-1);
}
.msg-file-icon {
  grid-row: span 2; display: grid; place-items: center; width: 34px; height: 34px;
  border-radius: var(--radius-sm); background: var(--surface-sunken); color: var(--text-secondary);
}
.msg-file-icon svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linejoin: round; }
.msg-file-name { font-size: var(--text-sm); font-weight: var(--weight-medium); overflow-wrap: anywhere; }
.msg-file-size { font-size: var(--text-xs); color: var(--text-tertiary); }

/* ---- Projects: task comments and files --------------------------------- */
.pj-task { flex-wrap: wrap; }
.pj-task-cbtn {
  flex: none; display: inline-flex; align-items: center; justify-content: center; gap: 3px;
  min-width: 36px; height: 36px; padding: 0 var(--space-2);
  border-radius: var(--radius-sm); color: var(--text-tertiary);
  font-size: var(--text-xs); font-weight: var(--weight-bold);
}
.pj-task-cbtn:hover, .pj-task-cbtn[aria-expanded="true"] { background: var(--surface-sunken); color: var(--text-primary); }
.pj-task-cbtn.has-comments { color: var(--text-secondary); }
.pj-task-cbtn svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linejoin: round; }
.pj-comments { flex: 1 0 100%; padding: 0 0 var(--space-4) 30px; }
.pj-comment-list { list-style: none; margin: 0 0 var(--space-3); padding: 0; display: grid; gap: var(--space-2); }
.pj-comment-list li { padding: var(--space-2) var(--space-3); background: var(--surface-sunken); border-radius: var(--radius-sm); }
.pj-comment-list p { font-size: var(--text-sm); white-space: pre-wrap; overflow-wrap: anywhere; }
.pj-comment-meta { display: flex; gap: var(--space-3); align-items: baseline; margin-top: 2px; font-size: var(--text-xs); color: var(--text-tertiary); }
.pj-comment-add { display: flex; gap: var(--space-2); }
.pj-comment-add .input { flex: 1; min-width: 0; }
@media (max-width: 520px) { .pj-comments { padding-left: 0; } }

.pj-sub { font-size: var(--text-sm); margin: var(--space-6) 0 var(--space-3); display: flex; gap: var(--space-3); align-items: baseline; }
.pj-files { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-3); }
.pj-file { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-3); font-size: var(--text-sm); }
.pj-file-name { font-weight: var(--weight-medium); text-align: left; overflow-wrap: anywhere; }
.pj-file-actions { display: flex; gap: var(--space-3); margin-left: auto; }

/* ---- Calendar: projects not booked yet --------------------------------- */

.swatch-tentative { background: var(--action-tint); outline: 1.5px dashed var(--action); outline-offset: -2px; }

/* ---- Booking link, compact ----------------------------------------------
   One line for the link and its buttons, one for the hint. The caption is a
   copy button, not a box. (.booking-link above still styles the payments
   card on the Invoices tab.) */
.share-bar {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-2);
  background: var(--accent-tint);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-5);
}
.share-bar-main { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3) var(--space-5); }
.share-bar-text { flex: 1 1 240px; min-width: 0; }
.share-bar h3 { font-size: var(--text-lg); color: var(--accent-on-tint); margin: 0; }
.share-bar-url {
  display: block; margin-top: 2px;
  font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--text-primary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.share-bar-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.share-bar-hint { font-size: var(--text-sm); color: var(--text-secondary); }
.share-bar-hint .btn-link { font-size: inherit; }
.share-bar .form-status { margin-top: var(--space-1); }
@media (max-width: 640px) {
  .share-bar { padding: var(--space-4); }
  .share-bar-actions { width: 100%; }
  /* Three equal buttons across a phone; min-width 0 lets them share it. */
  .share-bar-actions .btn { flex: 1 1 0; min-width: 0; padding-inline: var(--space-2); }
}

/* ---- Projects: customizing the board ----------------------------------- */
.pj-customize { margin-bottom: var(--space-6); }
.pj-customize h3 { margin-bottom: var(--space-2); }
.pj-cz-list { list-style: none; margin: var(--space-5) 0 var(--space-3); padding: 0; display: grid; gap: var(--space-2); }
.pj-cz-row {
  display: grid; align-items: center; gap: var(--space-2);
  grid-template-columns: auto minmax(0, 1fr) minmax(0, 18rem) auto;
  grid-template-areas: "move name kind remove";
  padding: var(--space-2);
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-sm);
}
.pj-cz-move { grid-area: move; }
.pj-cz-name { grid-area: name; }
.pj-cz-kind { grid-area: kind; }
.pj-cz-remove { grid-area: remove; }
.pj-cz-remove:disabled { opacity: .3; cursor: default; }
.pj-cz-moves {
  display: grid; gap: var(--space-3); margin-top: var(--space-4);
  padding: var(--space-4); border-radius: var(--radius-sm);
  background: var(--gold-100); color: var(--gold-800);
}
.pj-cz-moves .label { color: inherit; }
.pj-cz-cards { border: 0; padding: 0; margin: var(--space-6) 0 var(--space-5); min-width: 0;
  display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-5); }
.pj-cz-cards legend { width: 100%; margin-bottom: var(--space-2); }
.pj-cz-actions { align-items: center; }
.pj-cz-reset { margin-left: auto; }
@media (max-width: 640px) {
  .pj-customize { padding: var(--space-4); }
  .pj-cz-row {
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas: "move name remove" "move kind remove";
  }
  /* Arrows stacked, so the name and type get the width. */
  .pj-cz-move { flex-direction: column; }
  .pj-cz-move button { width: 36px; height: 40px; }
  .pj-cz-reset { margin-left: 0; width: 100%; text-align: left; }
}

/* ---- Projects: the whole flow across the page ---------------------------
   Columns share the width, so on a laptop the six default stages sit side by
   side and read left to right, Inquiry to Completed. More columns, or a
   phone, scroll sideways as before. */
.pj-col { flex: 1 0 172px; }
.pj-col-desc {
  margin-top: calc(-1 * var(--space-2)); padding: 0 var(--space-4) var(--space-3);
  font-size: var(--text-xs); line-height: 1.4; color: var(--text-secondary);
}
.pj-card-meta { flex-wrap: wrap; }
@media (max-width: 640px) { .pj-col { flex: 0 0 240px; } }

/* ---- Quotes ------------------------------------------------------------- */
.quote-terms {
  margin: var(--space-3) 0 0 auto;
  max-width: 60ch;
  text-align: right;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.quote-notes { white-space: pre-line; }
.quote-name { margin-top: var(--space-4); max-width: 26rem; }
.signed-block.is-muted { background: var(--surface-sunken); border-color: var(--border); }

/* Quote and invoice tables fit the card at every width. Descriptions wrap,
   even a long unbroken word, so the table never widens the page; amounts
   stay on one line. */
.invoice-sheet th + th, .invoice-sheet td + td { padding-left: var(--space-3); }
.invoice-sheet td:first-child { overflow-wrap: anywhere; }
.invoice-sheet th:last-child, .invoice-sheet td:last-child { white-space: nowrap; }
@media (max-width: 520px) {
  /* Room for the description on a phone. Qty and Amount still say what
     each line costs. */
  .invoice-sheet th:nth-child(3), .invoice-sheet td:nth-child(3) { display: none; }
}

/* ---- Quote or invoice: named on every form and card ---------------------- */
.doc-kind {
  display: inline-flex; align-items: center; vertical-align: middle;
  padding: 1px var(--space-2);
  border: var(--border-width) solid; border-radius: var(--radius-sm);
  font-size: var(--text-xs); font-weight: var(--weight-bold); line-height: 1.6;
  letter-spacing: .07em; text-transform: uppercase; white-space: nowrap;
}
.doc-kind-quote   { color: var(--action-on-tint); border-color: var(--action); }
.doc-kind-invoice { color: var(--text-secondary); border-color: var(--border-strong); }
.lead-head h3 .doc-kind { margin-right: var(--space-2); }
.doc-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); }
.doc-head-title { display: flex; align-items: center; gap: var(--space-3); min-width: 0; }
.doc-head-title h3 { margin: 0; }
.doc-explain { margin: var(--space-3) 0 var(--space-5); max-width: 62ch; font-size: var(--text-sm); color: var(--text-secondary); }

/* A vendor's own photo, shown whole inside its box (cards and the profile
   cover), over a blurred copy of itself that fills whatever space is left. */
.photo-fill { position: absolute; inset: 0; overflow: hidden; background: var(--surface-sunken); }
.photo-fill img { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.photo-fill .photo-bg { object-fit: cover; filter: blur(18px) saturate(1.1); transform: scale(1.15); opacity: .85; }
.photo-fill .photo-main { object-fit: contain; }

/* A real cover photo fills its frame. object-position carries the focal
   point the vendor set, and defaults to the centre when they have not. */
.photo-cover {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; display: block;
}

/* The vendor mark. On a card it sits over the corner of the cover; beside a
   name it is simply the first thing on the line. White behind it, because a
   logo is nearly always drawn for white and looks broken on anything else. */
.vendor-mark {
  position: absolute; left: var(--space-3); bottom: var(--space-3); z-index: 2;
  width: 46px; height: 46px; border-radius: var(--radius-full);
  background: #FFFFFF; box-shadow: var(--shadow-1);
  border: var(--border-width) solid var(--border);
  display: grid; place-items: center; overflow: hidden; flex: none;
}
.vendor-mark img { width: 82%; height: 82%; object-fit: contain; display: block; }
.vendor-mark.is-large { position: static; width: 64px; height: 64px; }

.detail-name { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.detail-name h1 { margin: 0; }

/* The logo row in the listing form: the mark as it will actually look,
   beside the controls that change it. */
.logo-field { display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap; }
.logo-preview {
  width: 84px; height: 84px; flex: none;
  border-radius: var(--radius-full); background: #FFFFFF;
  border: var(--border-width) solid var(--border);
  display: grid; place-items: center; overflow: hidden;
}
.logo-preview img { width: 82%; height: 82%; object-fit: contain; display: block; }
.logo-empty { font-size: var(--text-xs); color: var(--text-tertiary); }

/* Aiming a cover. The frame is the shape the cover is actually shown in, so
   what you drag is what you get. */
.aim { margin-top: var(--space-4); }
.aim-frame {
  position: relative; width: 100%; max-width: 520px; aspect-ratio: 4 / 3;
  overflow: hidden; border-radius: var(--radius);
  border: var(--border-width) solid var(--border);
  background: var(--surface-sunken); cursor: grab; touch-action: none;
  user-select: none;
}
.aim-frame.is-dragging { cursor: grabbing; }
.aim-frame img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; display: block; pointer-events: none;
}
/* Thirds, the way every crop tool marks them. */
.aim-frame::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(to right, transparent 33.2%, rgba(255,255,255,.5) 33.2%, rgba(255,255,255,.5) 33.5%, transparent 33.5%,
      transparent 66.4%, rgba(255,255,255,.5) 66.4%, rgba(255,255,255,.5) 66.7%, transparent 66.7%),
    linear-gradient(to bottom, transparent 33.2%, rgba(255,255,255,.5) 33.2%, rgba(255,255,255,.5) 33.5%, transparent 33.5%,
      transparent 66.4%, rgba(255,255,255,.5) 66.4%, rgba(255,255,255,.5) 66.7%, transparent 66.7%);
}

/* ---- Where a vendor works ----------------------------------------------- */
.meta-travel::before { content: "·"; margin-right: var(--space-2); }
.travel-box { border: 0; padding: 0; margin: 0; min-width: 0; display: grid; gap: var(--space-2); }
/* Sections of the listing form read as peers, so a fieldset legend sits the
   same distance from what is above it as an <h3> does. .travel-box zeroes
   its own margin, which inside .stack leaves no gap at all. */
[data-edit-listing] > .travel-box,
[data-edit-listing] > .form-fold { margin-top: var(--space-5); }
.travel-box .combo-add-row { margin-top: var(--space-2); }
.travel-chips { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.travel-chips p { margin: 0; }

/* ---- Vendor dashboard on a phone: keep the toolbar inside the page -------
   The sideways-scrolling pill row pulls itself out to the screen edges with
   negative margins. That only works for a row sitting directly in the page's
   padded container: inside the stacked toolbar it made the row wider than the
   page, so the whole dashboard scrolled sideways and the Export button went
   with it. */
@media (max-width: 760px) {
  .dash-toolbar { min-width: 0; }
  .dash-toolbar .pill-nav { margin-inline: 0; padding-inline: 0; max-width: 100%; }
  /* Title, then the filters, then the quiet export action at its own size. */
  .dash-toolbar .toolbar-actions { flex-direction: column; align-items: stretch; }
  .dash-toolbar .toolbar-actions [data-export] { align-self: flex-start; }
}

/* Deposit and balance sit together on the invoice, so the pair is what gets
   pushed to the right, not each button on its own. */
.pay-box .pay-actions { margin-left: auto; gap: var(--space-3); flex-wrap: wrap; }
.pay-box .pay-actions .btn { margin-left: 0; }
@media (max-width: 620px) {
  .pay-box .pay-actions { margin-left: 0; width: 100%; }
  .pay-box .pay-actions .btn { flex: 1 1 100%; }
}

/* The first few rows of an upload, so the vendor can see it read the file
   the way they expected before anything is saved. */
.qb-sample {
  list-style: none; margin: var(--space-3) 0; padding: 0;
  display: grid; gap: var(--space-1);
  font-size: var(--text-sm); color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}

/* ---- Header on a phone --------------------------------------------------
   The bar keeps what people actually tap: the logo, signing in or their
   account, and the menu. Favorites moves into the menu where it can carry a
   label, and the theme switch goes — a phone already has a light/dark
   setting of its own, which the site follows. */
.nav-fav { display: none; }
.nav-fav-count {
  min-width: 20px; height: 20px; padding: 0 6px;
  border-radius: var(--radius-full);
  background: var(--action); color: var(--action-text);
  font-size: 11px; font-weight: var(--weight-bold); line-height: 20px;
  text-align: center;
}
.nav-fav-count[hidden] { display: none; }

@media (max-width: 620px) {
  .header-actions .theme-toggle,
  .header-actions > a.icon-btn { display: none; }
  .site-nav .nav-fav { display: flex; align-items: center; gap: var(--space-2); }
}

/* The menu's own link colour out-ranked .btn-primary, so "Start planning"
   sat in the menu with muted text on clay, and turned grey on hover. Only
   phones saw it, since that is where the button moves into the menu. */
.site-nav .btn.btn-primary,
.site-nav .btn.btn-primary:hover {
  color: var(--action-text);
  background: var(--action);
}
.site-nav .btn.btn-primary:hover { background: var(--action-hover); }

/* The nav is what pushed the actions to the right edge, via margin-right:auto.
   Below 981px it becomes a fixed drop-down and leaves the flow, taking that
   push with it, so sign-in and the menu button drifted in to sit beside the
   logo. Push the group itself instead. */
@media (max-width: 980px) {
  .header-actions { margin-left: auto; }
}

/* Subtotal and tax sit above the total: same column, quieter, and without
   the rule that separates the total from the lines above it. */
.invoice-total.invoice-sub {
  border-top: 0; padding-top: 0;
  font-size: var(--text-base); color: var(--text-secondary);
}
.invoice-total.invoice-sub b {
  font-family: inherit; font-size: var(--text-base);
  font-weight: var(--weight-bold); color: var(--text-primary);
}

/* Linking a quote or invoice that was made before the project existed. */
.pj-link { margin-top: var(--space-3); display: grid; gap: var(--space-3); }

/* On a phone the project's two columns stack, and Money, Documents and Files
   ended up below the whole Details form — far enough down that they read as
   missing. They come first instead: what the job is worth and what has been
   sent, then the tasks and the form. */
@media (max-width: 900px) {
  .pj-side { order: -1; }
}
.pj-danger { text-align: right; }
@media (min-width: 901px) { .pj-danger { grid-column: 2; } }
@media (max-width: 900px) { .pj-danger { order: 99; } }

/* The four ways to add a document read as one set: equal width, two up,
   rather than three on one line and the fourth wrapping on its own. */
.pj-doc-actions {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2);
}
.pj-doc-actions .btn { width: 100%; }

/* ---- Review pass: small things that read as broken ---------------------- */

/* A label with a link beside it (Password / Forgot password?). Without this
   the block display on .field > .label wins and the two run together as one
   sentence: "Password Forgot password?". */
.field > .label.row-between { display: flex; }

/* The first block under the vendor's name. A profile with no About section
   used to drop "Reviews" straight onto the category line. */
.detail-title + .detail-section { margin-top: var(--space-7); }

/* No reviews yet is not the same as nothing to say: a card shows "New"
   rather than a 0.0 average built from no ratings. */
.rating-new { color: var(--text-tertiary); font-weight: var(--weight-medium); }

/* On a phone the sort label and its menu share one line rather than the
   label wrapping onto two. */
@media (max-width: 600px) {
  .results-head { align-items: flex-start; }
  .sort-row { width: 100%; }
  .sort-row label { flex: none; }
  .sort-row .select { flex: 1; width: auto; }
}

/* "Show 10 more" under the service filters. */
.filter-more { display: inline-block; margin-top: var(--space-2); }

/* A section's controls sit together on the right of its heading, in every
   panel: the filters and the export button are one group, not two things
   the heading has to squeeze between. */
.dash-toolbar .toolbar-actions {
  display: flex; align-items: center; gap: var(--space-3);
  flex-wrap: wrap; min-width: 0;
}

/* ---- Folded panels -----------------------------------------------------
   A tool a vendor uses once, if ever, states what it is on one line and
   stays out of the way until they open it. */
.fold > summary {
  display: flex; align-items: center; gap: var(--space-3);
  cursor: pointer; list-style: none;
}
.fold > summary::-webkit-details-marker { display: none; }
.fold > summary::after {
  content: ''; flex: none; margin-left: auto;
  width: 9px; height: 9px;
  border-right: 2px solid var(--text-tertiary);
  border-bottom: 2px solid var(--text-tertiary);
  transform: rotate(45deg); transform-origin: 65% 65%;
  transition: transform .18s var(--ease);
}
.fold[open] > summary::after { transform: rotate(225deg); }
.fold-title { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.fold-body { margin-top: var(--space-5); }

/* Ticking several categories, and the sub-types under them. Two columns so a
   fifteen-item list does not run the height of the form. */
.cat-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-1) var(--space-4);
}
@media (max-width: 560px) { .cat-grid { grid-template-columns: 1fr; } }

/* ---- Closing an account ------------------------------------------------
   Set apart from the rest of the page, and quiet until it is opened: the
   button to start is an ordinary secondary, not a red one begging to be
   pressed. */
.danger-box {
  margin-top: var(--space-8);
  border-color: var(--border-strong);
}
.danger-box h3 { margin-bottom: var(--space-3); }
.danger-box p { margin-bottom: var(--space-4); }
.danger-box .row { gap: var(--space-3); margin-top: var(--space-4); flex-wrap: wrap; }
.danger-box [data-close-confirm] { margin-top: var(--space-5); }
.danger-btn {
  border-color: var(--red-500);
  color: var(--red-500);
}
.danger-btn:hover { background: var(--red-500); color: #fff; }

/* ---- Start times -------------------------------------------------------
   Tap the hour rather than scrolling a spinner. A taken slot stays visible
   and legible, struck through, so the day reads as a real diary instead of
   a list with holes in it. */
.slotpick {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}
.slot {
  min-height: 44px;
  padding: var(--space-2) var(--space-3);
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border-strong);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font: inherit;
  font-size: var(--text-sm);
  cursor: pointer;
  transition: border-color .15s var(--ease), background .15s var(--ease);
}
.slot:hover:not(:disabled) { border-color: var(--action); }
.slot.is-on {
  background: var(--action);
  border-color: var(--action);
  color: var(--action-text);
  font-weight: var(--weight-bold);
}
.slot.is-taken {
  color: var(--text-tertiary);
  border-color: var(--border);
  background: transparent;
  text-decoration: line-through;
  cursor: not-allowed;
}

/* ---- Packages editor (dashboard) --------------------------------------- */
.pkg-row { padding: var(--space-4); border: var(--border-width) solid var(--border); border-radius: var(--radius); margin-bottom: var(--space-3); background: var(--surface-sunken); }
.pkg-row .field { margin-bottom: var(--space-3); }
.pkg-foot { display: flex; justify-content: space-between; align-items: center; gap: var(--space-3); flex-wrap: wrap; }

/* A verified business. Sits beside the name in a heading, so it is pinned to
   a fixed size rather than inheriting the heading's -- otherwise it would be
   one size on a card's h3 and another on a profile's h1. */
.badge-verified {
  margin-left: var(--space-2);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  vertical-align: middle;
  white-space: nowrap;
}

/* The avatar as the control. It carries a camera badge, so it should be the
   thing you press -- previously the badge looked like a button and was not
   one, and the real button sat beside it saying the same thing. */
.avatar-btn {
  border: 0; padding: 0; cursor: pointer;
  -webkit-appearance: none; appearance: none;
}
.avatar-btn:hover .avatar-badge { filter: brightness(1.12); }
.avatar-btn:focus-visible { outline: 2px solid var(--action); outline-offset: 3px; }
