/* ============================================================
   ServiceLow — stylesheet

   One file, no build step. Organised as:
     1. Tokens        6. Cards & lists
     2. Base          7. Discover
     3. Layout        8. Public provider page
     4. Navigation    9. Jobs, calendar, reviews
     5. Forms        10. Invoice & print

   Class names are the ones the pages already use — if you're changing
   something, find it by name rather than adding a parallel one.
   ============================================================ */

/* ---------- 1. Tokens -------------------------------------- */

:root {
  /* Navy carries the weight, orange is what you press, blue is for
     links and anything functional. Three jobs, three colours — if you
     find yourself wanting a fourth, you probably want a shade. */

  --navy-900: #0F1724;   /* deepest — hero gradient, strongest text */
  --navy-800: #172033;   /* the brand navy */
  --navy-700: #24304A;
  --navy-600: #33415F;
  --navy-500: #475777;
  --navy-100: #D6DBE4;
  --navy-50:  #EEF0F4;

  --brand:      #F97316;   /* brand orange */
  --brand-dark: #EA580C;
  --brand-50:   #FFF3E9;

  --blue:      #3B82F6;    /* links, focus, anything purely functional */
  --blue-dark: #2563EB;
  --blue-50:   #EFF5FF;

  /* Errors must not wear the brand colour — an error that looks like
     the button you just pressed is no warning at all. Same family as
     the orange and the blue, so it sits with them. */
  --danger:    #DC2626;
  --danger-50: #FEF2F2;

  --warn:      #B45309;    /* caution, not failure */
  --warn-50:   #FEF6E7;

  --paper:        #FFFDF9;   /* off-white */
  --paper-raised: #FFFFFF;
  --paper-sunk:   #F5F6F8;

  --ink:       #172033;
  --ink-soft:  #55607A;
  --ink-faint: #8A93A6;

  --line:      #E5E7EB;      /* cool gray */
  --line-soft: #EFF1F5;

  /* Job statuses — shared by badges, calendar chips and the legend so
     they can never drift apart. Amber sits well away from the brand
     orange so "in progress" never reads as a button. */
  --job-blue:  #2563EB;  --job-blue-bg:  #EAF2FE;
  --job-amber: #92510E;  --job-amber-bg: #FBEFDD;
  --job-green: #15803D;  --job-green-bg: #E6F4EA;
  --job-grey:  #64748B;  --job-grey-bg:  #EDEFF3;

  --shadow-sm: 0 1px 2px rgba(23, 32, 51, 0.05);
  --shadow:    0 1px 3px rgba(23, 32, 51, 0.06), 0 6px 16px rgba(23, 32, 51, 0.05);
  --shadow-lg: 0 2px 6px rgba(23, 32, 51, 0.06), 0 16px 40px rgba(23, 32, 51, 0.10);

  --r-sm: 8px;
  --r: 12px;
  --r-lg: 18px;
  --r-pill: 999px;

  --font: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --display: "Plus Jakarta Sans", system-ui, -apple-system, "Segoe UI", sans-serif;

  --radius: var(--r);   /* older name, still referenced in places */
}

/* ---------- 2. Base ---------------------------------------- */

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.55;
  background: var(--paper);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { font-family: var(--display); letter-spacing: -0.015em; }

a { color: var(--blue-dark); }

::selection { background: var(--brand-50); }

:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 2px;
  border-radius: 3px;
}

[hidden] { display: none !important; }

/* ---------- 3. Layout -------------------------------------- */

.wrap { max-width: 420px; margin: 3rem auto; padding: 0 1.25rem; }
.wrap.wide { max-width: 880px; }
.wrap.page { max-width: 880px; }

/* The browse pages fill the window like a marketplace should. Forms
   and settings stay at a readable width — a single input stretched to
   1300px is worse, not better. */
.wrap.full { max-width: 1320px; margin: 1.75rem auto 0; padding: 0 1.5rem; }

/* ---------- Site header (public pages) ---------------------- */

.site-header {
  background: var(--paper-raised);
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 30;
}
.hdr-inner {
  max-width: 1320px; margin: 0 auto; padding: 0.85rem 1.5rem;
  display: flex; align-items: center; gap: 1.5rem;
}

.logo {
  font-family: var(--display); font-weight: 800; font-size: 1.5rem;
  letter-spacing: -0.035em; color: var(--navy-900); text-decoration: none;
  flex: 0 0 auto;
}
.logo span { color: var(--brand); }

.hdr-search {
  flex: 1 1 auto; position: relative; display: flex; align-items: center;
  max-width: 640px;
}
.hdr-search-icon {
  position: absolute; left: 0.95rem; width: 20px; height: 20px;
  fill: none; stroke: var(--ink-faint); stroke-width: 2;
  stroke-linecap: round; pointer-events: none;
}
.hdr-search input {
  width: 100%; padding: 0.7rem 7.5rem 0.7rem 2.75rem;
  background: var(--paper-sunk); border-color: transparent;
  border-radius: var(--r-pill);
}
.hdr-search input:focus { background: var(--paper-raised); }
.hdr-search-go {
  position: absolute; right: 0.3rem; padding: 0.5rem 1.1rem; font-size: 0.85rem;
}

/* `margin-left:auto` is what pins Log in / Sign up to the far right.
   Without it they sit right up against the search box, because the
   search box stops growing at its max-width. */
.hdr-actions { flex: 0 0 auto; margin-left: auto; display: flex; align-items: center; gap: 0.7rem; }
.hdr-link {
  font-size: 0.9rem; font-weight: 600; color: var(--navy-800);
  text-decoration: none; white-space: nowrap;
}
.hdr-link:hover { color: var(--brand-dark); }

.btn-solid {
  display: inline-block; font-family: var(--display); font-weight: 700;
  font-size: 0.9rem; text-decoration: none; cursor: pointer; white-space: nowrap;
  color: #fff; background: var(--brand); border: none;
  border-radius: var(--r-pill); padding: 0.6rem 1.3rem;
  transition: background 0.12s ease;
}
.btn-solid:hover { background: var(--brand-dark); }

.btn-outline {
  font-family: var(--font); font-weight: 600; font-size: 0.88rem; cursor: pointer;
  color: var(--navy-800); background: none; border: 1.5px solid var(--line);
  border-radius: var(--r-pill); padding: 0.5rem 1.1rem; white-space: nowrap;
  transition: all 0.12s ease;
}
.btn-outline:hover { border-color: var(--navy-800); }

/* The category strip under the header. */
.cat-bar { background: var(--paper-raised); border-bottom: 1px solid var(--line); }
.cat-bar-inner {
  max-width: 1320px; margin: 0 auto; padding: 0 1.5rem;
  display: flex; gap: 0.4rem; overflow-x: auto;
  scrollbar-width: none;
}
.cat-bar-inner::-webkit-scrollbar { display: none; }
.cat-link {
  padding: 0.75rem 0.9rem; font-size: 0.88rem; font-weight: 600;
  color: var(--ink-soft); text-decoration: none; white-space: nowrap;
  border-bottom: 3px solid transparent; transition: color 0.12s ease;
}
.cat-link:hover { color: var(--navy-900); }
.cat-link.active { color: var(--navy-900); border-bottom-color: var(--brand); }

/* ---- the account dropdown ---- */

.hdr-menu { position: relative; }
.hdr-account {
  display: flex; align-items: center; gap: 0.45rem;
  font-family: var(--font); font-weight: 600; font-size: 0.9rem;
  color: var(--navy-800); background: none; border: none; cursor: pointer;
  padding: 0.4rem 0.2rem; white-space: nowrap;
}
.hdr-account:hover { color: var(--brand-dark); }
.hdr-person { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.7; }
.caret { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }

.hdr-panel {
  position: absolute; right: 0; top: calc(100% + 0.6rem); z-index: 40;
  min-width: 15rem; padding: 0.5rem;
  background: var(--paper-raised); border: 1px solid var(--line);
  border-radius: var(--r); box-shadow: var(--shadow-lg);
  display: flex; flex-direction: column;
}
.hdr-panel[hidden] { display: none; }
.hdr-hello {
  margin: 0.3rem 0.7rem 0.55rem; padding-bottom: 0.55rem;
  font-family: var(--display); font-weight: 700; font-size: 0.95rem;
  color: var(--navy-900); border-bottom: 1px solid var(--line-soft);
}
.hdr-panel a, .hdr-panel button {
  text-align: left; font-family: var(--font); font-size: 0.9rem; font-weight: 500;
  color: var(--navy-800); text-decoration: none; cursor: pointer;
  background: none; border: none; border-radius: var(--r-sm);
  padding: 0.55rem 0.7rem; white-space: nowrap;
}
.hdr-panel a:hover, .hdr-panel button:hover { background: var(--paper-sunk); color: var(--navy-900); }
.hdr-panel button {
  margin-top: 0.35rem; padding-top: 0.75rem;
  border-top: 1px solid var(--line-soft); border-radius: 0;
  color: var(--ink-soft); font-weight: 600;
}

/* ---- "More" on the category bar ---- */

/* Overflow goes behind a button instead of running off the screen
   where a mouse can reach it but a finger can't. */
.cat-more { position: relative; display: flex; }
.cat-more-btn {
  display: flex; align-items: center; gap: 0.3rem;
  font-family: var(--font); background: none; border: none; cursor: pointer;
  border-bottom: 3px solid transparent;
}
.cat-more-panel {
  display: none; position: absolute; right: 0; top: 100%; z-index: 40;
  min-width: 15rem; padding: 0.5rem;
  background: var(--paper-raised); border: 1px solid var(--line);
  border-radius: 0 0 var(--r) var(--r); box-shadow: var(--shadow-lg);
}
.cat-more:hover .cat-more-panel, .cat-more-panel.open { display: block; }
.cat-more-link {
  display: block; font-size: 0.88rem; font-weight: 500; color: var(--navy-800);
  text-decoration: none; border-radius: var(--r-sm); padding: 0.55rem 0.7rem;
  white-space: nowrap;
}
.cat-more-link:hover { background: var(--paper-sunk); }
.cat-more-link.active { color: var(--brand-dark); font-weight: 700; }

/* The bar no longer needs to scroll on a laptop, so let the panel hang
   out of it. Below 860px it goes back to scrolling (see the block
   further down) and the spill links take over from "More". */
.cat-bar, .cat-bar-inner { overflow: visible; }
.cat-spill { display: none; }

@media (max-width: 860px) {
  .hdr-inner { flex-wrap: wrap; gap: 0.75rem 1rem; padding: 0.75rem 1rem; }
  .hdr-search { order: 3; flex: 1 1 100%; max-width: none; }
  .hdr-actions { margin-left: auto; }
  .hdr-search input { padding-right: 1rem; }
  .hdr-search-go { display: none; }
  .wrap.full { padding: 0 1rem; }

  /* Back to a scrolling strip, with every category in it. */
  .cat-bar-inner {
    padding: 0 1rem; overflow-x: auto; scrollbar-width: none;
  }
  .cat-more { display: none; }
  .cat-spill { display: block; }
}

/* ---------- Customer home: welcome band + tile columns -----

   A visiting customer gets the marketplace header, not the work
   sidebar, and their home page is a wide band of "here's where you
   are" followed by grouped links — not a narrow column of cards. */

.welcome {
  display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: 1rem;
  align-items: stretch;
  background: var(--paper-sunk); border-radius: var(--r-lg);
  padding: 1.5rem; margin: 1.5rem 0 2rem;
}
.welcome-me { align-self: center; min-width: 0; }
.welcome-me h1 {
  margin: 0; font-size: 1.65rem; font-weight: 800; color: var(--navy-900);
  letter-spacing: -0.03em;
}
.welcome-me p { margin: 0.3rem 0 0; font-size: 0.9rem; }

.welcome-card {
  display: flex; align-items: center; gap: 0.9rem; text-decoration: none;
  background: var(--paper-raised); border: 1px solid var(--line);
  border-radius: var(--r); padding: 1.1rem 1.2rem;
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.welcome-card:hover { border-color: var(--navy-100); box-shadow: var(--shadow-sm); }
.wc-icon {
  flex: 0 0 auto; display: flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; border-radius: 50%; background: var(--brand-50);
}
.wc-icon svg {
  width: 21px; height: 21px; fill: none; stroke: var(--brand-dark);
  stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
}
.welcome-card b {
  display: block; font-family: var(--display); font-size: 1rem;
  color: var(--navy-900); line-height: 1.25;
}
.welcome-card small {
  display: block; margin-top: 0.15rem; font-size: 0.82rem; color: var(--ink-soft);
}

/* Three columns of grouped links. */
.tile-cols { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; }
.tile-col {
  background: var(--paper-sunk); border-radius: var(--r-lg); padding: 1.25rem;
  display: flex; flex-direction: column; gap: 0.6rem;
}
.tile-col h3 {
  display: flex; align-items: center; gap: 0.6rem;
  margin: 0 0 0.3rem; font-size: 1.05rem; font-weight: 800; color: var(--navy-900);
}
.tile-col h3 svg {
  width: 22px; height: 22px; flex: 0 0 auto;
  fill: none; stroke: var(--brand); stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}
.tile-col a {
  display: flex; align-items: center; justify-content: space-between; gap: 0.6rem;
  font-size: 0.9rem; font-weight: 500; color: var(--navy-800); text-decoration: none;
  background: var(--paper-raised); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 0.8rem 0.95rem;
  transition: border-color 0.12s ease;
}
.tile-col a:hover { border-color: var(--navy-100); color: var(--navy-900); }
.tile-col a span { color: var(--ink-faint); }

@media (max-width: 900px) {
  .welcome { grid-template-columns: 1fr 1fr; }
  .welcome-me { grid-column: 1 / -1; }
  .tile-cols { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  .welcome { grid-template-columns: 1fr; padding: 1.2rem; }
  .welcome-me h1 { font-size: 1.35rem; }
}

/* ---------- The work-area shell: sidebar + content ---------

   Providers and the admin work in these pages, so the nav lives down
   the left and the content gets the whole width beside it. Customers
   get the marketplace header instead — they're visiting, not working. */

.app { display: flex; align-items: stretch; min-height: 100vh; }

.app-nav {
  flex: 0 0 232px; width: 232px;
  background: var(--navy-900); color: #fff;
  display: flex; flex-direction: column;
  position: sticky; top: 0; align-self: flex-start; height: 100vh;
}
.app-nav .logo { color: #fff; }
.nav-top {
  display: flex; align-items: center; justify-content: space-between;
  padding: 1.1rem 1.25rem; flex: 0 0 auto;
}
.nav-burger { display: none; }

.nav-links {
  display: flex; flex-direction: column; gap: 0.15rem;
  padding: 0.5rem 0.75rem 1rem; flex: 1 1 auto; overflow-y: auto;
}
/* `flex: 0 0 auto` matters. `.nav-links` is a COLUMN flex container, so
   a grow factor here stretches each item *vertically* to eat the spare
   height — which made every page except Settings look wrong, because
   Settings' open sub-list was using that space up. The link only needs
   to grow sideways, and it only sits beside anything inside `.nav-row`,
   so that is the one place the grow belongs. */
.nav-item {
  display: flex; align-items: center; gap: 0.7rem; flex: 0 0 auto; min-width: 0;
  font-size: 0.9rem; font-weight: 600; color: #AEB7C7; text-decoration: none;
  border-radius: var(--r-sm); padding: 0.6rem 0.75rem;
  transition: background 0.12s ease, color 0.12s ease;
}
.nav-row .nav-item { flex: 1 1 auto; }
.nav-item:hover { background: rgba(255, 255, 255, 0.07); color: #fff; }
.nav-item.on { background: var(--brand); color: #fff; }
.nav-icon {
  width: 19px; height: 19px; flex: 0 0 auto;
  fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}

/* Settings and the pages under it. */
.nav-row { display: flex; align-items: center; gap: 0.15rem; }
.nav-caret {
  flex: 0 0 auto; display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; cursor: pointer;
  background: none; border: none; border-radius: var(--r-sm); color: #AEB7C7;
}
.nav-caret:hover { background: rgba(255, 255, 255, 0.07); color: #fff; }
.nav-caret .caret { transition: transform 0.15s ease; }
.nav-group.open .nav-caret .caret { transform: rotate(180deg); }

.nav-sub { display: none; flex-direction: column; margin: 0.15rem 0 0.35rem 2.4rem; }
.nav-group.open .nav-sub { display: flex; }
.nav-sub a {
  font-size: 0.84rem; font-weight: 500; color: #98A2B5; text-decoration: none;
  padding: 0.4rem 0.75rem; border-radius: var(--r-sm);
}
.nav-sub a:hover { color: #fff; }
.nav-sub a.on { color: #fff; font-weight: 700; }

.nav-foot { margin-top: auto; padding-top: 1rem; }
.nav-who {
  margin: 0 0.75rem 0.4rem; font-size: 0.78rem; color: #8892A5;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nav-signout {
  width: 100%; text-align: left; font-family: var(--font);
  font-size: 0.86rem; font-weight: 600; color: #AEB7C7;
  background: none; border: none; cursor: pointer;
  border-radius: var(--r-sm); padding: 0.55rem 0.75rem;
}
.nav-signout:hover { background: rgba(255, 255, 255, 0.07); color: #fff; }

/* The admin's sections are tabs on one page, not separate pages, so
   they're buttons in the sidebar rather than links. */
.nav-links > button.navtab,
.nav-links > .navtab {
  display: flex; align-items: center; gap: 0.7rem; width: 100%;
  font-family: var(--font); font-size: 0.9rem; font-weight: 600;
  color: #AEB7C7; background: none; border: none; cursor: pointer;
  text-align: left; border-radius: var(--r-sm); padding: 0.6rem 0.75rem;
}
.nav-links > button.navtab:hover { background: rgba(255, 255, 255, 0.07); color: #fff; }
.nav-links > button.navtab.active { background: var(--brand); color: #fff; }

.app-main {
  flex: 1 1 auto; min-width: 0;
  padding: 1.75rem 2rem 4rem;
  background: var(--paper);
}
.app-main > .card-head:first-child, .app-main > h1:first-child { margin-top: 0; }

/* ---- Post a job / request a booking ---- */

.ask-hero {
  background: linear-gradient(135deg, var(--navy-800), var(--navy-900));
  border-radius: var(--r-lg); padding: 2rem 2rem 1.75rem;
  color: #fff; margin-bottom: 1.5rem; position: relative; overflow: hidden;
}
/* A warm bloom in the corner, so the band isn't a flat navy slab. */
.ask-hero::after {
  content: ''; position: absolute; right: -60px; top: -80px;
  width: 280px; height: 280px; border-radius: 50%;
  background: radial-gradient(circle, rgba(249, 115, 22, 0.32), transparent 68%);
  pointer-events: none;
}
.ask-hero h1 {
  margin: 0 0 0.5rem; font-size: 1.7rem; font-weight: 800;
  letter-spacing: -0.03em; color: #fff; position: relative;
}
.ask-hero p {
  margin: 0; font-size: 0.97rem; line-height: 1.6; max-width: 34rem;
  color: #C9D0DC; position: relative;
}
.ask-points {
  display: flex; flex-wrap: wrap; gap: 0.5rem 1.4rem;
  list-style: none; margin: 1.1rem 0 0; padding: 0; position: relative;
}
.ask-points li {
  display: flex; align-items: center; gap: 0.4rem;
  font-size: 0.85rem; font-weight: 600; color: #fff;
}
.ask-points li::before {
  content: ''; flex: 0 0 auto; width: 7px; height: 7px;
  border-radius: 50%; background: var(--brand);
}

/* One numbered step per card. */
.ask-step {
  background: var(--paper-raised); border: 1px solid var(--line);
  border-radius: var(--r-lg); margin-bottom: 1rem; overflow: hidden;
}
.ask-head {
  display: flex; align-items: flex-start; gap: 0.9rem;
  padding: 1.2rem 1.4rem; background: var(--paper-sunk);
  border-bottom: 1px solid var(--line);
}
.ask-num {
  flex: 0 0 auto; display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 50%;
  font-family: var(--display); font-weight: 800; font-size: 0.92rem;
  color: #fff; background: var(--brand);
}
.ask-head h2 {
  margin: 0; font-size: 1.05rem; font-weight: 800; color: var(--navy-900);
}
.ask-head p { margin: 0.15rem 0 0; font-size: 0.85rem; }
.ask-body { padding: 1.3rem 1.4rem; }
.ask-body > :first-child { margin-top: 0; }

.ask-send {
  background: var(--brand-50); border: 1px solid #F9DCC4;
  border-radius: var(--r-lg); padding: 1.3rem 1.4rem; margin-top: 1.4rem;
}
.ask-send .field-hint { margin: 0.7rem 0 0; color: var(--navy-700); }

/* The thank-you. */
.ask-done { text-align: center; padding: 2.5rem 1.5rem; }
.ask-tick {
  display: inline-flex; align-items: center; justify-content: center;
  width: 60px; height: 60px; border-radius: 50%;
  background: var(--job-green-bg); margin-bottom: 1rem;
}
.ask-tick svg {
  width: 30px; height: 30px; fill: none; stroke: var(--job-green);
  stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round;
}
.ask-done h2 { margin: 0 0 0.5rem; font-size: 1.4rem; color: var(--navy-900); }
.ask-done p { margin: 0 auto 1.5rem; max-width: 32rem; color: var(--ink-soft); }
.ask-done .btn-row { justify-content: center; }

@media (max-width: 560px) {
  .ask-hero { padding: 1.5rem 1.25rem; }
  .ask-hero h1 { font-size: 1.35rem; }
  .ask-head { padding: 1rem; }
  .ask-body { padding: 1.1rem 1rem; }
}

/* The short booking reference — HM-1042. Monospace digits so a column
   of them lines up, and quiet enough not to compete with the name it
   sits beside. */
.ref-tag {
  display: inline-block; margin-left: 0.5rem; vertical-align: middle;
  font-family: ui-monospace, "Cascadia Mono", "Segoe UI Mono", Menlo, monospace;
  font-size: 0.72rem; font-weight: 600; letter-spacing: 0.02em;
  color: var(--ink-soft); background: var(--paper-sunk);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 0.12rem 0.4rem; white-space: nowrap;
}
.title .ref-tag { font-size: 0.68rem; }

/* ---- A row of filters above a list ---- */

.filter-bar {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.6rem 0.9rem;
  margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--line-soft);
}
.filter-bar > div { flex: 1 1 10rem; min-width: 0; }
/* The search box earns more room than the selects. */
.filter-bar > div:first-child { flex: 2 1 16rem; }
.filter-bar label { margin: 0 0 0.25rem; font-size: 0.72rem; letter-spacing: 0.04em; text-transform: uppercase; }
.filter-bar input, .filter-bar select { padding: 0.5rem 0.65rem; font-size: 0.88rem; }
.filter-bar-end { flex: 0 0 auto; }
.filter-bar-end .small { height: 38px; }

@media (max-width: 620px) {
  .filter-bar > div, .filter-bar > div:first-child { flex: 1 1 100%; }
}

/* Stars in a fold summary shouldn't wrap or shrink. */
.rev-stars { flex: 0 0 auto; white-space: nowrap; }

/* ---- A request: one scannable line that opens ---- */

/* Native <details>, so it works with no JavaScript and the keyboard
   gets it for free. */
.fold { padding: 0; overflow: hidden; }
.fold + .fold { margin-top: 0.8rem; }

.fold-sum {
  display: flex; align-items: center; gap: 1rem; cursor: pointer;
  padding: 1rem 1.2rem; list-style: none;
}
.fold-sum::-webkit-details-marker { display: none; }
.fold-sum:hover { background: var(--paper-sunk); }
.fold[open] .fold-sum { border-bottom: 1px solid var(--line-soft); }

.fold-main { display: flex; flex-direction: column; gap: 0.15rem; flex: 1 1 auto; min-width: 0; }
.fold-main b {
  font-family: var(--display); font-size: 1rem; font-weight: 700;
  color: var(--navy-900); letter-spacing: -0.01em;
}
.fold-sub {
  font-size: 0.83rem; color: var(--ink-soft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fold-right { display: flex; align-items: center; gap: 0.7rem; flex: 0 0 auto; }

.fold-chev {
  width: 18px; height: 18px; flex: 0 0 auto;
  fill: none; stroke: var(--ink-faint); stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round;
  transition: transform 0.15s ease;
}
.fold[open] .fold-chev { transform: rotate(180deg); }

.fold-body { padding: 1.2rem; }
.fold-body > :first-child { margin-top: 0; }

@media (max-width: 560px) {
  .fold-sum { flex-wrap: wrap; gap: 0.5rem 0.8rem; padding: 0.9rem 1rem; }
  .fold-main { flex: 1 1 100%; }
  .fold-body { padding: 1rem; }
}

/* "‹ Back to wherever you came from", above a detail page's title. */
.crumb { margin: 0 0 0.9rem; font-size: 0.88rem; }
.crumb a { display: inline-flex; align-items: center; gap: 0.3rem; font-weight: 600; }
.crumb svg {
  width: 16px; height: 16px; fill: none; stroke: currentColor;
  stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round;
}

/* The strip above the login card. */
.auth-top {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; margin-bottom: 1.5rem;
}
.auth-top .brand { margin: 0; text-decoration: none; }
.auth-top .brand span { color: var(--brand); }
.auth-top .back { display: inline-flex; align-items: center; gap: 0.3rem; }
.auth-top .back svg {
  width: 16px; height: 16px; fill: none; stroke: currentColor;
  stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round;
}

/* A single job, an invoice, one form. Nothing here wants 1300px, and
   the same width reads the same whichever side you're on. */
.detail { max-width: 980px; margin: 0 auto; }
.detail .subnav { margin-bottom: 1.5rem; }

/* The page title strip at the top of a work page. */
.page-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; margin-bottom: 1.4rem;
}
.page-head h1 {
  margin: 0; font-size: 1.5rem; font-weight: 800; color: var(--navy-900);
  letter-spacing: -0.03em;
}
.page-head p { margin: 0.25rem 0 0; }

@media (max-width: 900px) {
  .app { display: block; min-height: 0; }
  .app-nav {
    width: auto; height: auto; position: sticky; top: 0; z-index: 30;
    flex: none; display: block;
  }
  .nav-top { padding: 0.8rem 1rem; }
  .nav-burger {
    display: flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; cursor: pointer;
    background: none; border: none; border-radius: var(--r-sm);
  }
  .nav-burger svg {
    width: 24px; height: 24px; fill: none; stroke: #fff;
    stroke-width: 2; stroke-linecap: round;
  }
  .nav-links { display: none; padding: 0 0.75rem 1rem; }
  .nav-links.open { display: flex; }
  .nav-foot { margin-top: 0.5rem; }
  .app-main { padding: 1.25rem 1rem 3rem; }
}

.brand {
  font-family: var(--display);
  font-weight: 800;
  font-size: 1.3rem;
  letter-spacing: -0.03em;
  color: var(--navy-900);
  margin-bottom: 1.5rem;
}
.brand .muted {
  font-weight: 700;
  font-size: 0.72em;
  color: var(--brand);
  letter-spacing: 0;
}

.topbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; margin-bottom: 1.75rem;
}
.topbar .brand { margin-bottom: 0; }

.switch-line { text-align: center; font-size: 0.88rem; color: var(--ink-soft); margin-top: 1.2rem; }
.switch-line a { color: var(--blue-dark); font-weight: 600; text-decoration: none; }
.switch-line a:hover { text-decoration: underline; }

.muted { color: var(--ink-soft); font-size: 0.88rem; }

.sr-label {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

/* ---------- 4. Navigation ---------------------------------- */

.subnav { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-bottom: 1.5rem; }
.subnav a {
  font-size: 0.85rem; font-weight: 600; text-decoration: none;
  color: var(--ink-soft); background: var(--paper-raised);
  border: 1px solid var(--line); border-radius: var(--r-pill);
  padding: 0.45rem 0.85rem; transition: all 0.12s ease;
}
.subnav a:hover { color: var(--navy-900); border-color: var(--navy-100); }
.subnav a.active {
  background: var(--navy-800); border-color: var(--navy-800); color: #fff;
  box-shadow: var(--shadow-sm);
}
/* ---- social media links ---- */

.social-row { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.social-link {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; flex: 0 0 auto;
  color: var(--navy-700); background: var(--paper-raised);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  transition: all 0.12s ease;
}
/* Brand orange on hover rather than each platform's own colour — five
   different brand colours in a row would fight the page, and nothing
   else here borrows somebody else's palette. */
.social-link:hover {
  color: #fff; background: var(--brand);
  border-color: var(--brand); transform: translateY(-1px);
}
.social-link svg {
  width: 19px; height: 19px;
  fill: none; stroke: currentColor; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
}

/* ---- the signup security check ---- */

/* Turnstile renders a fixed-size iframe, so this just gives it room and
   keeps it off the button. Hidden entirely when no key is configured. */
.turnstile-row { margin: 1.1rem 0 0; min-height: 65px; }
.turnstile-row[hidden] { display: none; }

/* ---- photos of your work ---- */

/* Editing side, on the profile page. `auto-fill` rather than a fixed
   column count so it reflows from four across down to two on a phone
   without a breakpoint for each step. */
.gallery-grid {
  display: grid; gap: 0.9rem; margin: 1rem 0;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}
.gphoto {
  background: var(--paper-sunk); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 0.5rem;
}
.gphoto img {
  display: block; width: 100%; aspect-ratio: 4 / 3;
  object-fit: cover; border-radius: var(--r-sm); background: var(--line-soft);
}
.gphoto .gcap { margin: 0.5rem 0 0; font-size: 0.8rem; padding: 0.4rem 0.5rem; }
.gphoto-row { display: flex; gap: 0.3rem; margin-top: 0.45rem; }
/* The two arrows stay their own width; Remove takes what's left. */
.gphoto-row .gdel { flex: 1 1 auto; }
.gphoto-row .gmove { flex: 0 0 auto; padding: 0.38rem 0.6rem; }

/* Public side, on the provider page. Bigger, because here the picture
   is the point rather than a thing being managed. */
.work-grid {
  display: grid; gap: 0.7rem;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
}
.work-shot {
  position: relative; display: block; overflow: hidden;
  border-radius: var(--r-sm); background: var(--line-soft);
  text-decoration: none;
}
.work-shot img {
  display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  transition: transform 0.2s ease;
}
.work-shot:hover img { transform: scale(1.04); }
/* A caption sits over the foot of the picture, so a photo without one
   loses no height and the grid stays even. */
.work-cap {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 1.6rem 0.6rem 0.5rem;
  font-size: 0.78rem; font-weight: 600; color: #fff; line-height: 1.3;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.72), transparent);
}

/* ---- photos on a job ---- */

/* Reuses `.work-grid` for the layout; this is just the tile, which
   needs a foot the public gallery doesn't (who added it, and the
   buttons for your own). */
.jphoto {
  background: var(--paper-sunk); border: 1px solid var(--line);
  border-radius: var(--r-sm); overflow: hidden;
}
.jphoto img {
  display: block; width: 100%; aspect-ratio: 4 / 3;
  object-fit: cover; background: var(--line-soft);
}
.jphoto-foot {
  padding: 0.5rem 0.55rem;
  display: flex; flex-direction: column; gap: 0.4rem;
}
.jphoto-foot .muted { font-size: 0.74rem; }
.jphoto-foot .btn-row { gap: 0.3rem; }
.jphoto-foot .small { font-size: 0.74rem; padding: 0.3rem 0.55rem; }

/* ---- earnings ---- */

/* The money at the end of a month row. `.list li` is a flex row, so
   this just needs to stop shrinking and to line up with the others. */
.month-worth {
  flex: 0 0 auto; font-family: var(--display); font-weight: 800;
  font-size: 1rem; color: var(--navy-900); white-space: nowrap;
}

/* Inside a month row the bar sits under the title rather than beside a
   percentage, so it needs its own width and a little air. */
.list .bar-row { margin: 0.4rem 0 0.3rem; max-width: 22rem; }
.list .bar-row > span:first-child { flex: 0 0 0; }

/* ---- the subscription notice on the provider dashboard ---- */

/* `.notice` is normally one line of text. Here it holds a heading, a
   line of explanation and the Subscribe buttons, so its children need
   spacing the plain version never had. */
.plan-head {
  margin: 0; font-family: var(--display); font-weight: 700;
  font-size: 0.98rem; color: inherit;
}
.plan-line { margin: 0.4rem 0 0; font-size: 0.9rem; opacity: 0.92; }
.plan-line[hidden] { display: none; }
#plan-actions:not(:empty) { margin-top: 0.85rem; }
#plan-actions .field-hint { margin-bottom: 0; }

/* ---- "there's something waiting" ---- */

/* A count on a navigation link. Brand orange, because it is a thing to
   act on — and orange is what you press. It carries `hidden` in the
   markup and is only ever unhidden once a real number has arrived, so
   an empty circle can never flash up while the count is in flight. */
.nav-badge {
  margin-left: auto; flex: 0 0 auto;
  min-width: 1.35rem; padding: 0 0.4rem;
  font-family: var(--display); font-size: 0.72rem; font-weight: 800;
  line-height: 1.35rem; text-align: center;
  color: #fff; background: var(--brand); border-radius: var(--r-pill);
}
.nav-badge[hidden] { display: none; }

/* The active sidebar item is already filled with brand orange, so an
   orange badge on it would be invisible. Invert it there. */
.nav-item.on .nav-badge { background: #fff; color: var(--brand-dark); }

/* In the row of customer tabs the link is a pill that shrinks to its
   text, so there is no spare width for `margin-left: auto` to push
   against — the badge just sits beside the label. */
.subnav a { display: inline-flex; align-items: center; gap: 0.45rem; }
.subnav .nav-badge { margin-left: 0; }

/* Same badge inside the account dropdown. */
.hdr-panel a { display: flex; align-items: center; gap: 0.6rem; }

/* On the closed Account button, just a dot. A number there would need
   explaining; a dot only has to say "open this". */
.hdr-dot {
  width: 8px; height: 8px; flex: 0 0 auto;
  background: var(--brand); border-radius: 50%;
}
.hdr-dot[hidden] { display: none; }

/* The same dot on the burger the sidebar folds into under 900px. Sat
   on the corner of the button rather than in the flow, so it can't
   shift the icon. The ring is the sidebar's own navy, which keeps the
   dot legible where it overlaps the top bar of the burger. */
.nav-burger { position: relative; }
.nav-dot {
  position: absolute; top: 4px; right: 4px;
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--brand); border: 2px solid var(--navy-900);
}
.nav-dot[hidden] { display: none; }

.subnav.second { margin-top: -1rem; }
.subnav.second a { font-size: 0.8rem; padding: 0.35rem 0.75rem; }
.subnav.second a.active { background: var(--brand); border-color: var(--brand); }

/* Wrap rather than scroll. The admin panel has seven of these and they
   clip at this page width — a hidden tab you have to discover by
   dragging is worse than a second row. */
.tabs {
  display: flex; flex-wrap: wrap; gap: 0.4rem 1.4rem;
  border-bottom: 1px solid var(--line); margin-bottom: 1.4rem;
}
.tab {
  background: none; border: none; cursor: pointer; white-space: nowrap;
  font-family: var(--font); font-weight: 600; font-size: 0.92rem;
  color: var(--ink-soft); padding: 0 0 0.7rem; border-bottom: 2px solid transparent;
  margin-bottom: -1px; transition: color 0.12s ease;
}
.tab:hover { color: var(--navy-900); }
.tab.active { color: var(--navy-900); border-bottom-color: var(--brand); }

.view-toggle { display: flex; gap: 0.3rem; }
.view-toggle .small.on {
  background: var(--navy-800); border-color: var(--navy-800); color: #fff;
}

/* ---------- 5. Forms --------------------------------------- */

label {
  display: block; font-size: 0.8rem; font-weight: 600;
  color: var(--ink-soft); margin: 1rem 0 0.35rem;
  letter-spacing: 0.01em;
}
.optional { font-weight: 400; text-transform: none; color: var(--ink-faint); }

input, select, textarea {
  width: 100%; font-family: var(--font); font-size: 0.95rem;
  padding: 0.7rem 0.8rem; color: var(--ink);
  background: var(--paper-raised);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
textarea { line-height: 1.55; resize: vertical; }

input:hover, select:hover, textarea:hover { border-color: #CBD2DC; }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px var(--blue-50);
}
input:disabled { background: var(--paper-sunk); color: var(--ink-faint); }
input[type="file"] { padding: 0.5rem; font-size: 0.85rem; background: var(--paper-sunk); }

.field-hint { font-size: 0.8rem; color: var(--ink-faint); margin: 0.4rem 0 0; line-height: 1.45; }

.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 1rem; }
/* Three across, but the last one (a year) is half the width of the
   other two — a four-digit box as wide as a job title looks wrong. */
.grid-3 { display: grid; grid-template-columns: 2fr 2fr 1fr; gap: 0 1rem; }
@media (max-width: 680px) { .grid-3 { grid-template-columns: 1fr; } }
@media (max-width: 560px) { .grid-2 { grid-template-columns: 1fr; } }

/* Buttons ---------------------------------------------------- */

/* `a.primary` too, the same way `.small` covers both below. A link that
   is the main action of a card — Pay monthly on the dashboard — has to
   look identical to a button that is. Without the `a` selector it drew
   as plain underlined text, which is what happened first time.
   `inline-flex` and the centring are for the same reason as `.small`:
   a <button> centres its own label and an <a> does not. */
button.primary, a.primary {
  display: block; width: 100%; margin-top: 1.3rem; cursor: pointer;
  font-family: var(--display); font-weight: 700; font-size: 0.95rem;
  text-align: center; text-decoration: none;
  color: #fff; background: var(--brand); border: none;
  border-radius: var(--r-sm); padding: 0.8rem 1rem;
  box-shadow: 0 1px 2px rgba(234, 88, 12, 0.28);
  transition: background 0.12s ease, transform 0.06s ease;
}
button.primary:hover, a.primary:hover { background: var(--brand-dark); color: #fff; }
button.primary:active, a.primary:active { transform: translateY(1px); }
button.primary:disabled { opacity: 0.55; cursor: default; transform: none; }
button.primary.inline, a.primary.inline {
  display: inline-flex; align-items: center; justify-content: center;
  width: auto; margin-top: 0; padding: 0.65rem 1.25rem;
}

button.ghost {
  font-family: var(--font); font-weight: 600; font-size: 0.85rem;
  color: var(--navy-700); background: var(--paper-raised); cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r-pill);
  padding: 0.45rem 0.95rem; transition: all 0.12s ease;
}
button.ghost:hover { background: var(--navy-50); border-color: var(--navy-100); }

/* `inline-flex` + centring, not `inline-block`. A <button> centres its
   own label; an <a> doesn't. Side by side in a flex row they stretch to
   the same height and the link's text sits 5px higher than the
   button's — which is exactly what happened to Copy / Open on the
   provider dashboard. Centring here fixes every pairing at once. */
button.small, a.small {
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font); font-weight: 600;
  font-size: 0.8rem; text-decoration: none; cursor: pointer; white-space: nowrap;
  color: var(--navy-700); background: var(--paper-raised);
  border: 1px solid var(--line); border-radius: var(--r-pill);
  padding: 0.38rem 0.8rem; transition: all 0.12s ease;
}
button.small:hover, a.small:hover { background: var(--navy-50); border-color: var(--navy-100); }
button.small.danger { color: var(--danger); }
button.small.danger:hover { background: var(--danger-50); border-color: #F8C9C9; }
button.small:disabled { opacity: 0.5; cursor: default; }

a.contact {
  display: inline-block; font-family: var(--display); font-weight: 700;
  font-size: 0.9rem; text-decoration: none; color: #fff;
  background: var(--navy-700); border-radius: var(--r-sm);
  padding: 0.7rem 1.2rem; transition: background 0.12s ease;
}
a.contact:hover { background: var(--navy-900); }
a.contact.alt {
  background: var(--paper-raised); color: var(--navy-700);
  border: 1px solid var(--line);
}
a.contact.alt:hover { background: var(--navy-50); border-color: var(--navy-100); }

.btn-row { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.btn-row.spaced { margin-top: 1.2rem; }

/* Choosers --------------------------------------------------- */

.role-toggle { display: flex; gap: 0.5rem; margin-bottom: 1rem; }
.role-toggle label { flex: 1; cursor: pointer; margin: 0; }
.role-toggle input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.role-toggle span {
  display: block; text-align: center; font-weight: 600; font-size: 0.9rem;
  color: var(--ink-soft); background: var(--paper-raised);
  border: 1.5px solid var(--line); border-radius: var(--r-sm); padding: 0.65rem;
  transition: all 0.12s ease;
}
.role-toggle input:checked + span {
  border-color: var(--navy-700); background: var(--navy-700); color: #fff;
}
.role-toggle input:focus-visible + span { box-shadow: 0 0 0 3px var(--blue-50); }

.chips { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.4rem; }
.chips label { margin: 0; cursor: pointer; text-transform: none; font-size: 0.82rem; font-weight: 600; }
.chips input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.chips span {
  display: block; border: 1.5px solid var(--line); border-radius: var(--r-pill);
  padding: 0.35rem 0.8rem; color: var(--ink-soft); background: var(--paper-raised);
  transition: all 0.12s ease;
}
.chips input:checked + span { border-color: var(--navy-700); background: var(--navy-700); color: #fff; }
.chips input:focus-visible + span { box-shadow: 0 0 0 3px var(--blue-50); }

/* A chip you can take off again — used for the suggested services an
   admin manages. */
.chip-x {
  background: none; border: none; cursor: pointer; padding: 0 0 0 0.3rem;
  font-family: var(--font); font-size: 1rem; line-height: 1;
  color: var(--ink-faint);
}
.chip-x:hover { color: var(--danger); }
.chips label:has(.chip-x) { cursor: default; }

.check-row {
  display: flex; align-items: flex-start; gap: 0.65rem;
  margin: 1rem 0 0; font-size: 0.9rem; font-weight: 500;
  color: var(--ink); text-transform: none;
}
.check-row input { width: auto; margin: 0.2rem 0 0; flex: 0 0 auto; accent-color: var(--navy-700); }
.check-row .sub { display: block; font-weight: 400; font-size: 0.82rem; color: var(--ink-faint); margin-top: 0.15rem; }

.copy-row { display: flex; gap: 0.5rem; margin-top: 0.4rem; }
.copy-row input { font-size: 0.82rem; background: var(--paper-sunk); }

.upload-row { display: flex; align-items: center; gap: 1rem; margin-top: 0.6rem; }

/* ---------- 6. Cards, lists, feedback ---------------------- */

.card {
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 1.5rem;
  box-shadow: var(--shadow-sm);
}
.card + .card { margin-top: 1.2rem; }

.card-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; margin: 0 0 1.1rem; flex-wrap: wrap;
}
.card-head h2 { margin: 0; font-size: 1.05rem; font-weight: 700; color: var(--navy-900); }
.card-head p { margin: 0; }

h3.group {
  margin: 1.6rem 0 0; font-size: 0.74rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.07em; color: var(--ink-faint);
}
h3.group:first-child { margin-top: 0; }

.list { list-style: none; margin: 0; padding: 0; }
.list li {
  display: flex; align-items: center; gap: 0.8rem; flex-wrap: wrap;
  padding: 0.8rem 0; border-bottom: 1px solid var(--line-soft);
}
.list li:last-child { border-bottom: none; }
.list li:first-child { padding-top: 0; }
.list .grow { flex: 1; min-width: 0; }
.list .title { font-weight: 600; font-size: 0.93rem; }
.list .title a { color: var(--navy-900); text-decoration: none; }
.list .title a:hover { text-decoration: underline; }
.list .sub { font-size: 0.8rem; color: var(--ink-faint); margin-top: 0.15rem; }
.list input { font-size: 0.88rem; padding: 0.5rem 0.65rem; }
.list .check-row { margin: 0; white-space: nowrap; }

.empty {
  font-size: 0.9rem; color: var(--ink-faint);
  text-align: center; padding: 1.6rem 0.5rem; line-height: 1.5;
}
.empty a { color: var(--blue-dark); font-weight: 600; }

.kv { margin: 0; font-size: 0.9rem; }
.kv div {
  display: flex; gap: 0.8rem; padding: 0.55rem 0;
  border-bottom: 1px solid var(--line-soft);
}
.kv div:last-child { border-bottom: none; }
.kv dt { flex: 0 0 8.5rem; color: var(--ink-faint); font-weight: 600; font-size: 0.82rem; }
.kv dd { margin: 0; min-width: 0; }

.status {
  font-size: 0.88rem; padding: 0.75rem 0.95rem;
  border-radius: var(--r-sm); margin: 0 0 1.2rem; font-weight: 500;
}
.status.error { background: var(--danger-50); color: var(--danger); }
.status.success { background: var(--job-green-bg); color: var(--job-green); }

.notice {
  font-size: 0.88rem; border-radius: var(--r-sm);
  padding: 0.8rem 1rem; margin: 0 0 1.2rem;
  background: var(--navy-50); color: var(--navy-900);
}
.notice.warn { background: var(--warn-50); color: var(--warn); }
/* An ordinary link inside a notice takes the notice's colour, so it
   reads as part of the sentence. A link that is a BUTTON must not —
   `a.primary` inside a warning drew orange-on-amber and was close to
   unreadable. Both selectors are one class + one element, so without
   the exclusion whichever is written later simply wins. */
/* A nudge is a notice with a button in it, so the text and the button
   need separating — a `.notice` is otherwise a single line. The button
   keeps its own colour via the exclusion below. */
.nudge { display: flex; flex-direction: column; align-items: flex-start; gap: 0.7rem; }
.nudge p { margin: 0; }
@media (max-width: 520px) { .nudge .primary { width: 100%; } }

.notice a:not(.primary):not(.small) { color: inherit; font-weight: 700; }

.badge {
  display: inline-block; font-size: 0.7rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.05em;
  border-radius: var(--r-pill); padding: 0.25rem 0.6rem; white-space: nowrap;
  background: var(--navy-100); color: var(--navy-900);
}
.badge.off   { background: var(--job-grey-bg);  color: var(--job-grey); }
.badge.warn  { background: var(--warn-50);       color: var(--warn); }
.badge.dot-blue  { background: var(--job-blue-bg);  color: var(--job-blue); }
.badge.dot-amber { background: var(--job-amber-bg); color: var(--job-amber); }
.badge.dot-green { background: var(--job-green-bg); color: var(--job-green); }
.badge.dot-grey  { background: var(--job-grey-bg);  color: var(--job-grey); }

.placeholder-note {
  margin-top: 1.5rem; font-size: 0.82rem; color: var(--ink-faint);
  border-left: 2px solid var(--line); padding-left: 0.85rem;
}

/* Stat cards ------------------------------------------------- */

.stat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.8rem; margin-bottom: 1.4rem; }
@media (max-width: 680px) { .stat-grid { grid-template-columns: 1fr 1fr; } }

.stat {
  background: var(--paper-raised); border: 1px solid var(--line);
  border-radius: var(--r); padding: 1rem 1.1rem;
  box-shadow: var(--shadow-sm);
}
.stat b {
  display: block; font-family: var(--display); font-size: 1.75rem;
  font-weight: 800; color: var(--navy-900); line-height: 1.05;
  letter-spacing: -0.03em;
}
.stat span { display: block; font-size: 0.78rem; color: var(--ink-faint); margin-top: 0.3rem; }
a.stat { text-decoration: none; display: block; transition: all 0.12s ease; }
a.stat:hover { border-color: var(--navy-100); box-shadow: var(--shadow); }

/* ---------- 7. Discover ------------------------------------ */

.hero {
  position: relative; overflow: hidden;
  background: linear-gradient(135deg, var(--navy-800) 0%, var(--navy-900) 60%);
  border-radius: var(--r-lg);
  padding: 3.5rem 3rem;
  margin: 0 0 2rem;
  color: #fff;
  box-shadow: var(--shadow-lg);
}
/* A soft brand glow in the corner so the block isn't a flat slab. */
.hero::after {
  content: ''; position: absolute; right: -8%; top: -55%;
  width: 46%; aspect-ratio: 1; border-radius: 50%;
  background: radial-gradient(circle, rgba(249, 115, 22, 0.30), transparent 68%);
  pointer-events: none;
}
.hero-text { position: relative; z-index: 1; max-width: 46rem; }
.hero h1 {
  margin: 0 0 0.6rem; font-size: 2.8rem; line-height: 1.05;
  letter-spacing: -0.04em; color: #fff; font-weight: 800;
}
.hero p { margin: 0 0 1.8rem; color: rgba(255, 255, 255, 0.76); font-size: 1.05rem; max-width: 34rem; }

/* Section headings on the wide pages. */
.section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; margin: 2.5rem 0 1.1rem;
}
.section-head h2 { margin: 0; font-size: 1.4rem; color: var(--navy-900); }

.search-row { display: flex; gap: 0.5rem; }
.search-row input[type="search"] { flex: 1 1 auto; min-width: 0; }
.search-row select { flex: 0 0 11rem; }
.search-row button { flex: 0 0 auto; }
.search-row input, .search-row select { border-color: transparent; padding: 0.8rem; }
.search-row input:focus, .search-row select:focus { box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.25); }

.hero-alt { margin: 1rem 0 0; font-size: 0.88rem; color: rgba(255, 255, 255, 0.72); }
.hero-alt a { color: #fff; font-weight: 700; text-decoration: underline; text-underline-offset: 2px; }

@media (max-width: 760px) {
  .hero { padding: 2rem 1.4rem; }
  .hero h1 { font-size: 1.8rem; }
  .hero p { font-size: 0.97rem; }
  .section-head { margin: 1.8rem 0 0.9rem; }
  .section-head h2 { font-size: 1.2rem; }
  .search-row { flex-wrap: wrap; }
  .search-row input[type="search"] { flex: 1 1 100%; }
  .search-row select { flex: 1 1 auto; }
}

/* How it works — three steps under the hero. */
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; margin-bottom: 1.5rem; }
@media (max-width: 680px) { .steps { grid-template-columns: 1fr; gap: 0.6rem; } }
.step {
  background: var(--paper-raised); border: 1px solid var(--line);
  border-radius: var(--r); padding: 1.1rem 1.2rem; box-shadow: var(--shadow-sm);
}
.step b {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.6rem; height: 1.6rem; margin-bottom: 0.6rem;
  font-family: var(--display); font-size: 0.82rem; font-weight: 800;
  color: #fff; background: var(--brand); border-radius: var(--r-pill);
}
.step h3 { margin: 0 0 0.25rem; font-size: 0.95rem; color: var(--navy-900); }
.step p { margin: 0; font-size: 0.85rem; color: var(--ink-soft); line-height: 1.5; }

/* The pitch to tradespeople. A marketplace's hard problem is having
   anyone in it, so this gets real estate rather than a footnote. */
/* Warm rather than cold — this block is asking tradespeople to sign up,
   so it should feel like the orange side of the palette. */
.band {
  background: var(--brand-50); border: 1px solid #F9DCC4;
  border-radius: var(--r-lg); padding: 1.8rem 2rem; margin: 1.6rem 0;
}
.band-text h2 { margin: 0 0 0.5rem; font-size: 1.35rem; color: var(--navy-900); }
.band-text p { margin: 0 0 1rem; font-size: 0.95rem; color: var(--ink-soft); max-width: 40rem; line-height: 1.6; }
.band-btn { margin-top: 0.4rem; }

.ticks { list-style: none; margin: 0 0 1.2rem; padding: 0; }
.ticks li {
  position: relative; padding-left: 1.6rem; margin: 0.4rem 0;
  font-size: 0.92rem; color: var(--ink);
}
.ticks li::before {
  content: '✓'; position: absolute; left: 0; top: -0.05em;
  color: var(--brand); font-weight: 800;
}

/* "How ServiceLow works" — the answers to why should I trust this. */
.trust-p { margin: 0.35rem 0 1.1rem; font-size: 0.9rem; color: var(--ink-soft); line-height: 1.6; }
.trust-p:last-child { margin-bottom: 0; }

/* Long-form pages: privacy, terms. */
.prose { max-width: 42rem; }
.prose h1 { margin: 0 0 0.3rem; font-size: 1.7rem; color: var(--navy-900); }
.prose h2 {
  margin: 2rem 0 0.6rem; font-size: 1.1rem; color: var(--navy-900);
  padding-top: 1.2rem; border-top: 1px solid var(--line-soft);
}
.prose h2:first-of-type { border-top: none; padding-top: 0; margin-top: 1.5rem; }
.prose h3.group { margin: 1.3rem 0 0.4rem; }
.prose p { margin: 0 0 0.9rem; font-size: 0.95rem; line-height: 1.65; }
.prose ul { margin: 0 0 1rem; padding-left: 1.2rem; }
.prose li { margin: 0.35rem 0; font-size: 0.95rem; line-height: 1.6; }
.prose b { color: var(--navy-900); }

/* Footer — full-bleed navy. Sits at the bottom of the window whatever
   container it was dropped into, which is why the negative margins are
   there: it has to escape the page's padding to reach the edges. */
.site-foot {
  margin: 4rem calc(50% - 50vw) 0; padding: 3rem calc(50vw - 50%) 0;
  background: var(--navy-900); color: #fff;
}
.foot-inner {
  max-width: 1320px; margin: 0 auto; padding: 0 0 2.5rem;
  display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 2rem;
}
@media (max-width: 760px) {
  .foot-inner { grid-template-columns: 1fr 1fr; gap: 1.8rem; }
  .foot-brand-col { grid-column: 1 / -1; }
}

.foot-brand {
  font-family: var(--display); font-weight: 800; font-size: 1.45rem;
  color: #fff; letter-spacing: -0.03em;
}
.foot-brand span { color: var(--brand); }
.foot-line {
  margin: 0.6rem 0 0; font-size: 0.88rem; line-height: 1.6;
  color: rgba(255, 255, 255, 0.62); max-width: 24rem;
}

.foot-col { display: flex; flex-direction: column; gap: 0.55rem; }
.foot-col h3 {
  margin: 0 0 0.35rem; font-size: 0.75rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.09em; color: var(--brand);
}
.foot-col a {
  font-size: 0.88rem; color: rgba(255, 255, 255, 0.78);
  text-decoration: none; transition: color 0.12s ease;
}
.foot-col a:hover { color: #fff; }

.foot-bottom {
  max-width: 1320px; margin: 0 auto; padding: 1.5rem 0 2.5rem;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  display: flex; justify-content: space-between; gap: 1.5rem; flex-wrap: wrap;
}
.foot-fine {
  margin: 0; font-size: 0.78rem; line-height: 1.6;
  color: rgba(255, 255, 255, 0.45); max-width: 42rem;
}

@media (max-width: 560px) {
  .band { padding: 1.4rem 1.2rem; }
  .band-text h2 { font-size: 1.15rem; }
}

.cat-grid { display: grid; grid-template-columns: repeat(8, 1fr); gap: 0.75rem; }
/* Four across is tight on a tablet — the longer category names wrap to
   three lines and the row grows to match. */
@media (max-width: 1000px) { .cat-grid { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 820px) { .cat-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 620px) { .cat-grid { grid-template-columns: repeat(2, 1fr); } }

.cat {
  display: flex; flex-direction: column; align-items: center; gap: 0.6rem;
  text-align: center; cursor: pointer; text-decoration: none;
  font-family: var(--font); font-weight: 600; font-size: 0.85rem; line-height: 1.3;
  color: var(--navy-900); background: var(--paper-raised);
  border: 1px solid var(--line); border-radius: var(--r);
  padding: 1.25rem 0.85rem; transition: all 0.14s ease;
}
.cat:hover {
  border-color: var(--navy-100); box-shadow: var(--shadow);
  transform: translateY(-2px);
}
.cat.on { border-color: var(--navy-800); background: var(--navy-800); color: #fff; }

/* Drawn icons, not emoji — they take the brand colour and look the
   same on every device. */
.cat-icon {
  display: flex; align-items: center; justify-content: center;
  width: 46px; height: 46px; flex: 0 0 auto;
  background: var(--brand-50); border-radius: 50%;
}
.cat.on .cat-icon { background: rgba(255, 255, 255, 0.14); }
.cat-svg {
  width: 24px; height: 24px;
  fill: none; stroke: var(--brand); stroke-width: 1.9;
  stroke-linecap: round; stroke-linejoin: round;
}
.cat.on .cat-svg { stroke: #fff; }
.cat-emoji { font-size: 1.35rem; line-height: 1; }

.pgrid {
  display: grid; gap: 1.25rem;
  grid-template-columns: repeat(auto-fill, minmax(270px, 1fr));
}
.pgrid .empty { grid-column: 1 / -1; }
/* A card grid sitting straight on top of the next card looked like one
   block with a seam through it. */
.pgrid + .card { margin-top: 1.5rem; }

.pcard {
  position: relative; display: flex; flex-direction: column;
  background: var(--paper-raised); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow-sm);
  transition: transform 0.14s ease, box-shadow 0.14s ease, border-color 0.14s ease;
}
.pcard:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow); border-color: var(--navy-100);
}

/* 16:9 rather than a letterbox strip — photos of real work need room. */
.pcard-media {
  display: block; aspect-ratio: 16 / 9; overflow: hidden; text-decoration: none;
  background: linear-gradient(140deg, var(--navy-700), var(--navy-900));
  border-radius: calc(var(--r-lg) - 1px) calc(var(--r-lg) - 1px) 0 0;
}
.pcard-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pcard-initial {
  display: flex; align-items: center; justify-content: center;
  width: 100%; height: 100%; color: rgba(255, 255, 255, 0.85);
  font-family: var(--display); font-size: 2.6rem; font-weight: 800;
}

/* The profile photo straddles the banner, the way a person expects a
   face to sit on a cover image. Positioned from the top of the body,
   not the card — the card's height varies, the seam doesn't. */
.pcard-avatar {
  position: absolute; left: 1.1rem; top: -26px;
  width: 52px; height: 52px; border-radius: 50%; object-fit: cover;
  border: 3px solid var(--paper-raised); background: var(--paper-sunk);
  box-shadow: var(--shadow-sm); z-index: 1;
}
.pcard-avatar-blank {
  display: flex; align-items: center; justify-content: center;
  font-family: var(--display); font-weight: 800; font-size: 1.15rem;
  color: var(--navy-800);
}

.pcard-body {
  position: relative;
  padding: 2.1rem 1.1rem 1.1rem; display: flex; flex-direction: column; flex: 1;
}
.pcard-body h3 { margin: 0; font-size: 1.05rem; line-height: 1.25; }
.pcard-body h3 a { color: var(--navy-900); text-decoration: none; }
.pcard-body h3 a:hover { color: var(--brand-dark); }

.pcard-line {
  display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap;
  margin-top: 0.35rem; font-size: 0.82rem;
}
.pcard-rating { display: inline-flex; align-items: center; gap: 0.35rem; }
.pcard-rating .stars { font-size: 0.86rem; }
.pcard-rating b { color: var(--navy-900); }

.pcard-meta {
  display: flex; align-items: center; gap: 0.3rem;
  margin: 0.45rem 0 0; font-size: 0.82rem; color: var(--ink-soft);
}
.pcard-meta .pin {
  width: 14px; height: 14px; flex: 0 0 auto;
  fill: none; stroke: var(--ink-faint); stroke-width: 1.8;
}

.pcard-tags { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-top: 0.75rem; }
.tag {
  font-size: 0.75rem; font-weight: 600; color: var(--navy-700);
  background: var(--paper-sunk); border-radius: var(--r-sm);
  padding: 0.25rem 0.55rem; white-space: nowrap;
}
.tag-more { color: var(--ink-faint); }

.pcard-foot {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 0.6rem; margin-top: auto; padding-top: 1rem; font-size: 0.82rem;
}
.pcard-from { display: flex; flex-direction: column; line-height: 1.15; }
.pcard-from span { font-size: 0.72rem; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.05em; }
.pcard-from b { font-family: var(--display); font-size: 1.1rem; color: var(--navy-900); }
.pcard-open { font-size: 0.78rem; font-weight: 600; color: var(--job-green); }

/* The heart floats on the banner, out of the content's way. */
.save-btn {
  position: absolute; top: 0.7rem; right: 0.7rem; z-index: 2;
  display: flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; cursor: pointer;
  background: rgba(255, 255, 255, 0.92); border: none;
  border-radius: 50%; box-shadow: var(--shadow-sm);
  transition: background 0.12s ease, transform 0.12s ease;
}
.save-btn svg {
  width: 19px; height: 19px;
  fill: none; stroke: var(--navy-700); stroke-width: 1.9; stroke-linejoin: round;
}
.save-btn:hover { transform: scale(1.08); }
.save-btn:hover svg { stroke: var(--brand); }
.save-btn.on svg { fill: var(--brand); stroke: var(--brand); }
.save-btn:disabled { opacity: 0.6; cursor: default; }

.price { font-weight: 700; color: var(--navy-800); font-size: 0.92rem; white-space: nowrap; }

/* ---------- Discover: the catalogue ------------------------ */

.browse { display: grid; grid-template-columns: 250px 1fr; gap: 2rem; align-items: start; }
@media (max-width: 900px) { .browse { grid-template-columns: 1fr; gap: 1.2rem; } }

.filters { position: sticky; top: 5.5rem; }

/* On a phone the filter panel is a full screen of controls in front of
   the results, so it collapses behind a button instead. */
.filter-toggle { display: none; }
@media (max-width: 900px) {
  .filters { position: static; display: none; }
  .filters.open { display: block; }
  .filter-toggle {
    display: inline-flex; align-items: center; gap: 0.5rem;
    grid-column: 1 / -1; justify-self: start;
    font-family: var(--font); font-weight: 600; font-size: 0.9rem;
    color: var(--navy-900); background: var(--paper-raised);
    border: 1px solid var(--line); border-radius: var(--r-pill);
    padding: 0.55rem 1.1rem; cursor: pointer;
  }
  .filter-toggle b {
    font-size: 0.72rem; line-height: 1; color: #fff; background: var(--brand);
    border-radius: var(--r-pill); padding: 0.2rem 0.45rem;
  }
}
.filters .card { padding: 1.2rem; }
.filter-group + .filter-group { margin-top: 1.4rem; padding-top: 1.4rem; border-top: 1px solid var(--line-soft); }
.filter-group h3 {
  margin: 0 0 0.7rem; font-size: 0.75rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-faint);
}
.filter-list { display: flex; flex-direction: column; gap: 0.1rem; }
.filter-list button {
  display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
  width: 100%; text-align: left; cursor: pointer;
  font-family: var(--font); font-size: 0.88rem; font-weight: 500;
  color: var(--ink-soft); background: none; border: none;
  border-radius: var(--r-sm); padding: 0.45rem 0.55rem;
  transition: all 0.12s ease;
}
.filter-list button:hover { background: var(--paper-sunk); color: var(--navy-900); }
.filter-list button.on { background: var(--navy-800); color: #fff; font-weight: 600; }
.filter-list button.on .count { color: rgba(255, 255, 255, 0.7); }
.filter-list .count { font-size: 0.78rem; color: var(--ink-faint); }

.browse-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; margin-bottom: 1.2rem;
}
.browse-head h1 { margin: 0; font-size: 1.6rem; color: var(--navy-900); }
.browse-head .muted { font-size: 0.9rem; }

.chips-row { display: flex; flex-wrap: wrap; gap: 0.45rem; margin-bottom: 1.2rem; }
.chip-active {
  display: inline-flex; align-items: center; gap: 0.4rem;
  font-size: 0.82rem; font-weight: 600; color: var(--navy-800);
  background: var(--brand-50); border: 1px solid #F9DCC4;
  border-radius: var(--r-pill); padding: 0.35rem 0.75rem;
}
.chip-active button {
  background: none; border: none; cursor: pointer; padding: 0;
  font-size: 1rem; line-height: 1; color: var(--ink-faint);
}
.chip-active button:hover { color: var(--danger); }

/* ---------- 8. Public provider page ------------------------ */

.public-banner {
  width: 100%; aspect-ratio: 3 / 1; object-fit: cover; display: block;
  background: linear-gradient(140deg, var(--navy-700), var(--navy-900));
  max-height: 340px;
}
.public-head { display: flex; gap: 1.1rem; align-items: flex-start; margin-top: -2.75rem; }
.public-head img,
.public-head .avatar-preview {
  width: 96px; height: 96px; border-radius: 50%; object-fit: cover; flex: 0 0 auto;
  border: 4px solid var(--paper); background: var(--paper-sunk);
  box-shadow: var(--shadow); color: var(--navy-700);
}
.public-head .who { padding-top: 3rem; min-width: 0; }
.public-head h1 {
  margin: 0; font-size: 1.5rem; font-weight: 800; color: var(--navy-900);
  word-wrap: break-word; letter-spacing: -0.03em;
}
.public-head .who p { margin: 0.25rem 0 0; }

.banner-preview {
  width: 100%; aspect-ratio: 3 / 1; object-fit: cover; display: block;
  border-radius: var(--r); border: 1px solid var(--line); background: var(--paper-sunk);
}
.avatar-preview {
  width: 88px; height: 88px; border-radius: 50%; object-fit: cover; display: block;
  border: 1px solid var(--line); background: var(--paper-sunk);
}
.image-blank {
  display: flex; align-items: center; justify-content: center;
  font-size: 0.8rem; color: var(--ink-faint); text-align: center; padding: 0.5rem;
}

.hours { width: 100%; border-collapse: collapse; font-size: 0.88rem; }
.hours th, .hours td { text-align: left; padding: 0.5rem 0; border-bottom: 1px solid var(--line-soft); }
.hours tr:last-child th, .hours tr:last-child td { border-bottom: none; }
.hours th { font-weight: 600; color: var(--ink-faint); width: 8rem; }
.hours td.closed { color: var(--ink-faint); }
.hours tr.today th, .hours tr.today td { color: var(--navy-900); font-weight: 700; }

/* The line under the business name — rating, jobs, open/closed. */
.who-line {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.4rem;
  margin-top: 0.4rem; font-size: 0.9rem;
}
.who-rating { display: inline-flex; align-items: center; gap: 0.35rem; }
.who-rating b { font-size: 0.95rem; color: var(--navy-900); }
.dot-sep { color: var(--line); font-style: normal; margin-right: 0.4rem; }

/* Content left, contact card right — the card follows you down. */
.provider-grid {
  display: grid; grid-template-columns: minmax(0, 1fr) 320px;
  gap: 1.25rem; align-items: start; margin-top: 1.5rem;
}
.provider-side { position: sticky; top: 1rem; }
.side-card { padding: 1.2rem; }
.side-price {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 0.5rem; padding-bottom: 0.9rem; margin-bottom: 0.9rem;
  border-bottom: 1px solid var(--line-soft);
}
.side-price span { font-size: 0.85rem; color: var(--ink-soft); }
.side-price b {
  font-family: var(--display); font-size: 1.35rem; font-weight: 800;
  color: var(--navy-900); letter-spacing: -0.02em;
}
.side-card .contact { text-align: center; }
.side-card .contact:first-child { background: var(--brand); }
.side-card .contact:first-child:hover { background: var(--brand-dark); }
.side-card .field-hint { margin: 0.8rem 0 0; }
.side-card h3.group {
  margin: 1.3rem 0 0.2rem; padding-top: 1.1rem;
  border-top: 1px solid var(--line-soft);
}

/* Services and prices on the public page. Read-only, so a plain list
   rather than the editable `.list` rows used inside the dashboard. */
.svc-list { list-style: none; margin: 0; padding: 0; }
.svc-list li {
  display: flex; align-items: center; gap: 0.8rem;
  padding: 0.8rem 0; border-bottom: 1px solid var(--line-soft);
}
.svc-list li:last-child { border-bottom: none; padding-bottom: 0; }
.svc-list li:first-child { padding-top: 0; }
.svc-list .svc-name { flex: 1 1 auto; font-weight: 600; color: var(--navy-900); min-width: 0; }
.svc-list .svc-price { flex: 0 0 auto; font-size: 0.88rem; color: var(--ink-soft); }
.svc-list .empty { width: 100%; }

/* On a phone the contact card goes first — it's what you came for. */
@media (max-width: 900px) {
  .provider-grid { grid-template-columns: 1fr; }
  .provider-side { position: static; order: -1; }
}
@media (max-width: 560px) {
  .public-head { gap: 0.8rem; margin-top: -2rem; }
  .public-head img, .public-head .avatar-preview { width: 72px; height: 72px; }
  .public-head .who { padding-top: 2.2rem; }
  .public-head h1 { font-size: 1.25rem; }
}

/* ---------- 9. Jobs, calendar, reviews --------------------- */

/* Editable rows. Written as `.list .x` so they beat `.list .grow`. */
.list .svc-name-wrap { flex: 1 1 12rem; }
.list .svc-price-wrap { flex: 0 0 7.5rem; }
.list .svc-price-wrap input { width: 100%; }

.day-row { flex-wrap: wrap; }
.day-name { flex: 0 0 6.5rem; font-weight: 600; font-size: 0.9rem; }
.day-times { display: flex; align-items: center; gap: 0.5rem; flex: 1 1 15rem; }
.day-times input { width: auto; flex: 1 1 6rem; }
.day-times .to { font-size: 0.85rem; color: var(--ink-faint); }
.day-row.closed .day-times { opacity: 0.45; }

.card.fold .card-head { align-items: center; }
.card.fold .kv dd .muted { display: block; font-size: 0.82rem; margin-top: 0.15rem; }

.request-note {
  margin: 1.1rem 0 0; font-size: 0.92rem; line-height: 1.6; white-space: pre-wrap;
  border-left: 3px solid var(--navy-100); padding-left: 1rem; color: var(--ink);
}

.photo-row { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1rem; }
.photo-row:empty { display: none; }
.photo-row img {
  width: 92px; height: 92px; object-fit: cover; display: block;
  border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--paper-sunk);
}

.quote-form {
  margin-top: 1.1rem; padding: 1rem 1.1rem 1.1rem;
  background: var(--paper-sunk); border-radius: var(--r);
}
.quote-form label { margin-top: 0.6rem; }
.quote-form .grid-2 > div:first-child label { margin-top: 0; }

/* Calendar --------------------------------------------------- */

.cal-bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.8rem; flex-wrap: wrap; margin-bottom: 1.1rem;
}
.cal-bar h2 { margin: 0; font-size: 1.1rem; color: var(--navy-900); }

.legend { display: flex; flex-wrap: wrap; gap: 1rem; font-size: 0.82rem; color: var(--ink-soft); }
.legend-item { display: flex; align-items: center; gap: 0.4rem; }
.legend i { width: 0.7rem; height: 0.7rem; border-radius: 3px; display: block; }
.legend i.dot-blue  { background: var(--job-blue); }
.legend i.dot-amber { background: var(--job-amber); }
.legend i.dot-green { background: var(--job-green); }
.legend i.dot-grey  { background: var(--job-grey); }

.chip-job {
  display: block; text-decoration: none; font-size: 0.75rem; line-height: 1.3;
  border-radius: 5px; padding: 0.24rem 0.42rem; margin-top: 0.2rem;
  border-left: 3px solid; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chip-job b { font-weight: 700; }
.chip-job.dot-blue  { background: var(--job-blue-bg);  border-color: var(--job-blue);  color: var(--job-blue); }
.chip-job.dot-amber { background: var(--job-amber-bg); border-color: var(--job-amber); color: var(--job-amber); }
.chip-job.dot-green { background: var(--job-green-bg); border-color: var(--job-green); color: var(--job-green); }
.chip-job.dot-grey  { background: var(--job-grey-bg);  border-color: var(--job-grey);  color: var(--job-grey); }
.chip-job:hover { filter: brightness(0.95); }

.cal-card { padding: 0.8rem; overflow-x: auto; }
.cal-grid {
  display: grid; grid-template-columns: repeat(7, minmax(6.2rem, 1fr));
  gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--r-sm);
  overflow: hidden;
}
.cal-head {
  background: var(--paper-sunk); text-align: center; padding: 0.5rem 0;
  font-size: 0.7rem; font-weight: 700; color: var(--ink-faint);
  text-transform: uppercase; letter-spacing: 0.06em;
}
.cal-cell { background: var(--paper-raised); min-height: 5.6rem; padding: 0.3rem; }
.cal-cell.other-month { background: var(--paper); }
.cal-cell.other-month .cal-date { color: var(--line); }
.cal-cell.today { box-shadow: inset 0 0 0 2px var(--brand); }

.cal-date {
  display: inline-block; font-size: 0.78rem; font-weight: 700;
  color: var(--ink-faint); text-decoration: none; padding: 0.1rem 0.3rem;
  border-radius: 4px;
}
.cal-date:hover { background: var(--navy-50); color: var(--navy-900); }
.cal-cell.today .cal-date { color: var(--brand-dark); }

.cal-day { padding: 0.85rem 0; border-bottom: 1px solid var(--line-soft); }
.cal-day:last-child { border-bottom: none; }
.cal-day:first-child { padding-top: 0; }
.cal-day-head { display: flex; align-items: center; gap: 0.5rem; font-size: 0.92rem; }
.cal-day-head .small { margin-left: auto; padding: 0.15rem 0.55rem; }
.cal-day.today .cal-day-head b { color: var(--brand-dark); }
.cal-day-jobs { margin-top: 0.4rem; }
.cal-day .chip-job { white-space: normal; font-size: 0.85rem; padding: 0.45rem 0.6rem; }
.cal-empty { margin: 0.4rem 0 0; font-size: 0.82rem; color: var(--ink-faint); }

/* --- how full a day is, and whether it is a working one -------------
   The calendar used to answer only "what have I got on". These answer
   "how much of the day is gone" and "am I even open", which is the same
   question for a tutor, a caterer, a salon and a plumber. */

/* Pushed onto its own line under the day name on a phone, where the
   head would otherwise wrap mid-sentence. */
.cal-note { font-size: 0.78rem; color: var(--ink-faint); font-weight: 500; }
.cal-off { color: var(--ink-faint); font-style: italic; }
@media (max-width: 560px) {
  .cal-day-head { flex-wrap: wrap; }
  .cal-note { flex-basis: 100%; order: 3; }
  .cal-day-head .small { order: 2; }
}

/* A day off is dimmed rather than hidden — it is still a date you can
   add a job to, people do work Saturdays. */
.cal-day-off { opacity: 0.55; }
.cal-cell.cal-day-off { background: var(--paper-sunk); }

/* A clash is the one diary mistake that costs a customer, so it is
   allowed to be loud. Danger red, not the brand colour. */
.cal-clash { margin: 0.45rem 0 0; }
.chip-job.chip-clash { box-shadow: inset 0 0 0 1.5px var(--danger); }
.cal-cell-clash { box-shadow: inset 0 0 0 2px var(--danger); }
/* Today AND a clash: the clash wins, because it is the one that needs
   acting on. Written after so it takes precedence on equal specificity. */
.cal-cell.today.cal-cell-clash { box-shadow: inset 0 0 0 2px var(--danger); }

/* Legend swatches for the two signals that are not a status colour. */
.legend-clash { box-shadow: inset 0 0 0 2px var(--danger); background: transparent !important; }
.legend-off { background: var(--paper-sunk) !important; border: 1px solid var(--line); }

/* "+2 more" in a month cell. A link, not a chip — it does something
   different from the chips above it. */
.cal-more-jobs {
  display: block; font-size: 0.72rem; font-weight: 700; margin-top: 0.25rem;
  padding: 0.18rem 0.42rem; color: var(--blue); text-decoration: none;
}
.cal-more-jobs:hover { text-decoration: underline; }

/* In the wide day/week list the customer's name rides along after the
   service, dimmed so the service still reads first. */
.cal-day .chip-job .muted { font-weight: 500; opacity: 0.8; }

/* Reviews ---------------------------------------------------- */

.stars { color: var(--brand); letter-spacing: 0.06em; font-size: 1rem; white-space: nowrap; }
.stars .half { position: relative; display: inline-block; }
.stars .half i {
  position: absolute; left: 0; top: 0; width: 50%;
  overflow: hidden; font-style: normal;
}

.star-pick { display: flex; gap: 0.15rem; margin-top: 0.4rem; }
.star {
  background: none; border: none; cursor: pointer; padding: 0.1rem 0.15rem;
  font-size: 2rem; line-height: 1; color: var(--line); font-family: var(--font);
  transition: color 0.1s ease, transform 0.1s ease;
}
.star.on, .star:hover { color: var(--brand); }
.star:hover { transform: scale(1.08); }

.score { display: flex; align-items: center; gap: 1.1rem; }
.score-big {
  font-family: var(--display); font-size: 2.8rem; font-weight: 800;
  color: var(--navy-900); line-height: 1; letter-spacing: -0.04em;
}

.breakdown { margin-top: 1.3rem; display: grid; gap: 0.35rem; }
.bar-row { display: flex; align-items: center; gap: 0.6rem; font-size: 0.8rem; }
.bar-row > span:first-child { flex: 0 0 1.8rem; color: var(--ink-faint); }
.bar { flex: 1; height: 0.5rem; background: var(--line-soft); border-radius: var(--r-pill); overflow: hidden; }
.bar i { display: block; height: 100%; background: var(--brand); border-radius: var(--r-pill); }

.reply {
  margin-top: 1rem; padding: 0.8rem 1rem;
  background: var(--paper-sunk); border-radius: var(--r); font-size: 0.88rem;
}
.reply b { display: block; font-size: 0.76rem; color: var(--ink-faint); margin-bottom: 0.25rem;
  text-transform: uppercase; letter-spacing: 0.05em; }
.reply p { margin: 0; white-space: pre-wrap; }

.review-item { padding: 1rem 0; border-bottom: 1px solid var(--line-soft); }
.review-item:first-child { padding-top: 0; }
.review-item:last-child { border-bottom: none; padding-bottom: 0; }
.review-top { display: flex; align-items: baseline; justify-content: space-between; gap: 0.8rem; }
.review-top .muted { font-size: 0.8rem; }
.review-item > p { margin: 0.45rem 0 0; font-size: 0.92rem; line-height: 1.55; white-space: pre-wrap; }

/* ---------- 10. Invoice & print ---------------------------- */

.invoice {
  background: var(--paper-raised); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 2rem; margin-bottom: 1.2rem;
  box-shadow: var(--shadow-sm);
}
.invoice-head {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 1.5rem; flex-wrap: wrap; padding-bottom: 1.3rem;
  border-bottom: 2px solid var(--navy-900);
}
.invoice-head h1 { margin: 0; font-size: 1.4rem; color: var(--navy-900); font-weight: 800; }
.invoice-head p { margin: 0.35rem 0 0; font-size: 0.85rem; }
.invoice-meta { text-align: right; }
.invoice-no { font-family: var(--display); font-size: 1.15rem; font-weight: 800; color: var(--navy-900); }
.invoice-meta p { margin: 0.2rem 0 0.45rem; font-size: 0.82rem; }

.invoice-parties { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; margin: 1.3rem 0; }
.invoice-parties p { margin: 0.25rem 0 0; font-size: 0.92rem; }
.invoice-parties .muted { font-size: 0.82rem; }

.invoice-lines { width: 100%; border-collapse: collapse; margin-top: 0.8rem; }
.invoice-lines th, .invoice-lines td {
  text-align: left; padding: 0.65rem 0; border-bottom: 1px solid var(--line-soft);
  font-size: 0.92rem; vertical-align: top;
}
.invoice-lines th { font-weight: 600; color: var(--ink-faint); width: 9rem; }
.invoice-lines td { white-space: pre-wrap; }
.invoice-lines td.amount { text-align: right; font-variant-numeric: tabular-nums; }
.invoice-lines tr.balance th, .invoice-lines tr.balance td {
  border-bottom: none; border-top: 2px solid var(--navy-900);
  font-weight: 800; color: var(--navy-900); font-size: 1.05rem; padding-top: 0.8rem;
  font-family: var(--display);
}
.invoice-foot {
  margin: 1.5rem 0 0; font-size: 0.78rem; color: var(--ink-faint);
  border-top: 1px solid var(--line); padding-top: 0.9rem;
}

@media (max-width: 560px) {
  .invoice { padding: 1.2rem; }
  .invoice-parties { grid-template-columns: 1fr; gap: 1rem; }
  .invoice-meta { text-align: left; }
}

/* On paper: the document only. */
@media print {
  .no-print, .topbar, .subnav, .app-nav, .site-header { display: none !important; }
  body { background: #fff; }
  .wrap { margin: 0; max-width: none; padding: 0; }
  .app { display: block; min-height: 0; }
  .app-main { padding: 0; background: #fff; }
  .detail { max-width: none; }
  .invoice { border: none; padding: 0; box-shadow: none; }
  .invoice-head { border-bottom-color: #000; }
  .invoice-lines tr.balance th, .invoice-lines tr.balance td { border-top-color: #000; }
}

/* ---------- Narrow screens, last word --------------------- */

@media (max-width: 560px) {
  body { font-size: 15px; }
  .wrap { margin: 1.75rem auto; }
  .card { padding: 1.2rem; border-radius: var(--r); }
  .card-head { flex-wrap: wrap; }
  .tabs { gap: 1rem; }
  .tab { font-size: 0.86rem; }
  .list .svc-name-wrap { flex: 1 1 100%; }
  .list .svc-price-wrap { flex: 1 1 6rem; }
  .card.fold .kv dt { flex-basis: 5.5rem; }
  .kv dt { flex-basis: 6.5rem; }
  .cal-bar h2 { order: -1; flex: 1 1 100%; }
  .cal-grid { grid-template-columns: repeat(7, minmax(4.4rem, 1fr)); }
  .cal-cell { min-height: 4.4rem; }
  .public-head { gap: 0.8rem; }
  .public-head img { width: 72px; height: 72px; }
  .public-head .who { padding-top: 2.4rem; }
  .public-head h1 { font-size: 1.25rem; }
}
