/* ═══════════════════════════════════════════════════════════════════════════
   myquack redesign layer (loads AFTER style.css → overrides it)
   Brand: teal #1698A3 + warm cream. Light + dark. Squared, flat, no AI tells.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Type: force the brand sans everywhere (consistent, not OS-dependent) ──── */
:root{
  --font-display: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-body:    "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

/* ── LIGHT tokens → warm cream + teal ───────────────────────────────────────*/
:root{
  color-scheme: light;
  --bg:#F4EEE1; --surface:#FFFFFF; --surface-2:#F4EEE1; --surface-3:#EBE3D3; --card:#FFFFFF;
  --text:#182320; --soft:#545E5A; --muted:#6F7772;
  --orange:#1698A3; --accent:#1698A3; --accent-press:#127E88;
  --gold:#B7852B; --ember:#D6452F; --green:#12876A; --blue:#2F6FE0; --purple:#7C5CBF;
  --emerald:#0E5F57;
  --border:rgba(24,60,58,0.14); --border-2:rgba(24,60,58,0.22);
  --glass-bg:rgba(255,255,255,0.58); --glass-border:rgba(24,60,58,0.16); --glass-highlight:rgba(255,255,255,0.9);
  --shadow-sm:0 1px 2px rgba(60,50,30,0.05), 0 1px 3px rgba(60,50,30,0.05);
  --shadow-md:0 2px 10px rgba(60,50,30,0.06), 0 16px 34px rgba(60,50,30,0.07);
  --radius:8px; --radius-lg:10px; --radius-sm:5px;
  --ink-on-accent:#FFFFFF;
}
/* ── DARK tokens → deep teal-charcoal + cream ───────────────────────────────*/
:root[data-theme="dark"]{
  color-scheme: dark;
  --bg:#0E1A18; --surface:#15211F; --surface-2:#1B2725; --surface-3:#273330; --card:#15211F;
  --text:#EDE6D7; --soft:#B2BBB5; --muted:#869089;
  --orange:#2FB4BE; --accent:#2FB4BE; --accent-press:#2698A2;
  --gold:#D6A64E; --ember:#E9634C; --green:#3BB98C; --blue:#5B94F0; --purple:#A08AD6;
  --emerald:#0C4F49;
  --border:rgba(120,205,205,0.16); --border-2:rgba(120,205,205,0.26);
  --glass-bg:rgba(21,33,31,0.66); --glass-border:rgba(120,205,205,0.20); --glass-highlight:rgba(255,255,255,0.05);
  --shadow-sm:0 1px 2px rgba(0,0,0,0.4);
  --shadow-md:0 8px 26px rgba(0,0,0,0.45);
  --ink-on-accent:#06201F;
}
@media (prefers-color-scheme: dark){
  :root[data-theme="system"]{
    color-scheme: dark;
    --bg:#0E1A18; --surface:#15211F; --surface-2:#1B2725; --surface-3:#273330; --card:#15211F;
    --text:#EDE6D7; --soft:#B2BBB5; --muted:#869089;
    --orange:#2FB4BE; --accent:#2FB4BE; --accent-press:#2698A2;
    --gold:#D6A64E; --ember:#E9634C; --green:#3BB98C; --blue:#5B94F0; --purple:#A08AD6;
    --emerald:#0C4F49; --border:rgba(120,205,205,0.16); --border-2:rgba(120,205,205,0.26);
    --glass-bg:rgba(21,33,31,0.66); --glass-border:rgba(120,205,205,0.20);
    --shadow-sm:0 1px 2px rgba(0,0,0,0.4); --shadow-md:0 8px 26px rgba(0,0,0,0.45);
    --ink-on-accent:#06201F;
  }
}

/* ── Page backdrop ──────────────────────────────────────────────────────────
   Glass is a lens. Over a flat colour it refracts nothing, which is exactly why the
   frosting was invisible: the page was one solid cream, so blurring it returned the same
   cream. Every glassmorphism reference works because there is a photograph behind it.

   This is that photograph, reduced to its essentials: a real image (the gardening shot
   already in the category set) downsampled to 64x43 and blurred until it stops reading as
   any particular industry and becomes an abstract organic field, then pulled toward the
   brand tokens. Two bytes shy of nothing (~0.17KB) and the browser scales it up smoothly,
   so a full-viewport soft field costs no runtime blur.

   `fixed` so it sits still while the page scrolls — the parallax is what makes panels feel
   like they are floating ABOVE something rather than painted onto it. The solid colour
   stays underneath as the fallback if the image ever fails. */
html{
  background:var(--bg) url('../img/brand/field-light.webp') center center / cover no-repeat fixed;
}
/* data-theme lives on :root, and :root IS <html>, so these target the same element. */
:root[data-theme="dark"]{ background-image:url('../img/brand/field-dark.webp'); }
@media (prefers-color-scheme: dark){
  :root[data-theme="system"]{ background-image:url('../img/brand/field-dark.webp'); }
}
/* body must not paint over it — it was an opaque cream sheet hiding the whole thing. */
body{ font-family:var(--font-body); background:transparent; color:var(--text); }
a{ color:var(--accent); }

/* ── Squared, flat components (kill pills + big radii + glow) ────────────────*/
.btn{ border-radius:7px !important; box-shadow:none !important; font-weight:600; letter-spacing:0; }
.btn-primary{ background:var(--accent); color:var(--ink-on-accent); border:1px solid transparent; }
.btn-primary:hover{ background:var(--accent-press); }
.btn-ghost{ background:transparent; color:var(--text); border:1px solid var(--border-2); }
.btn-ghost:hover{ border-color:var(--text); }
.btn-sm{ border-radius:6px !important; }

/* ── Blocks: one treatment, shared with the calendar ─────────────────────────
   Four different container radii were in play (8px here, 12px inline on booking cards,
   10px on the calendar, 14px on the modal) and elevation was inconsistent — booking cards
   and payout items carried a shadow while the sections around them did not. Mixed radii
   and mixed elevation is what makes a page read as assembled rather than designed.

   The calendar settled on flat surfaces with hairline borders and it looks right, so that
   is now the rule: containers share --radius-lg, inner chips step down to --radius, and
   nothing in this group floats. The genuinely floating surfaces — the frosted provider
   cards, the modal, the right-click menu, toasts — keep their shadows, because those
   actually sit above the page. */
.provider-card,.settings-section,.card,.pcard,.booking-card,.frame,
.cal-body,.kpi-card,.payout-item{ border-radius:var(--radius-lg) !important; }

/* Inner rows step DOWN. .service-row and .earn-worked were in the container list above,
   which put a container-sized corner on 16 quack rows nested inside a section — a card
   inside a card, which is exactly the fragmented look this pass is removing. */
.service-row,.earn-worked,.review-item,.offer-row{ border-radius:var(--radius) !important; }

/* Flat + hairline. .provider-card is deliberately absent: it is part of the glass layer
   over the page backdrop and its inset highlight is doing real work. */
.booking-card,.review-item,.payout-item,.settings-section,.kpi-card{ box-shadow:none !important; }

/* Symmetric padding. The bottom was 0.5rem against 1.25rem elsewhere, so every section
   sat visibly tighter at the base than the top. */
.settings-section{ padding:1.15rem 1.15rem !important; }
.glass{ -webkit-backdrop-filter:none !important; backdrop-filter:none !important; background:var(--card) !important; }

/* A card that is itself a link must never underline. The global `a:hover` rule was
   underlining every word inside a provider card on hover — name, tags, blurb, price —
   because the whole card is one anchor. */
a.provider-card, a.provider-card:hover,
a.provider-card *, a.provider-card:hover * { text-decoration: none !important; }
a.provider-card:hover{ border-color:var(--accent); }

/* ── Tags: ONE definition, site-wide ─────────────────────────────────────────
   Previously five treatments were declared across redesign.css, browse.html and
   provider_public.html, plus an inline per-industry colour, so a single row could
   carry emerald, gold, pink, grey and accent at once. Colour now means something:
   teal marks the one claim a client cares about (documents reviewed), everything
   else is neutral metadata. Same size, same border, same radius. */
.pc-tag,.badge,.chip,.pill,.earn-badge{ border-radius:var(--radius-sm) !important; }
.pc-tag{
  display:inline-flex !important; align-items:center; gap:5px;
  font-size:0.72rem !important; font-weight:600 !important; line-height:1.35;
  padding:0.22rem 0.5rem !important;
  background:transparent !important;
  /* --soft, not --muted. On the frosted card these measured 2.76:1, well under the 4.5:1
     WCAG AA needs for text this size. They are secondary metadata, but secondary is not the
     same as unreadable. */
  color:var(--soft) !important;
  border:1px solid var(--border) !important;
}
/* The verification badge is the only one that earns colour. */
.pc-tag--verified{
  /* Brand teal on a near-white card measures 2.76:1 — the badge that matters most was the
     least readable one on the page. --emerald is the same family, dark enough to clear AA.
     Dark mode keeps --accent, which is the light teal and already has plenty of contrast
     against a dark card; --emerald there would be near-invisible. */
  color:var(--emerald) !important;
  border-color:color-mix(in srgb, var(--accent) 45%, transparent) !important;
}
:root[data-theme="dark"] .pc-tag--verified{ color:var(--accent) !important; }
@media (prefers-color-scheme: dark){
  :root[data-theme="system"] .pc-tag--verified{ color:var(--accent) !important; }
}
/* .pc-tag--seen removed: "You've booked before" is now a corner flag on the card
   (.pc-seen-flag in browse.html), not one tag among five in the tag row. */

/* input focus + fields */
input,select,textarea{ border-radius:7px !important; }
input:focus,select:focus,textarea:focus{ outline:2px solid color-mix(in srgb,var(--accent) 55%,transparent); outline-offset:1px; }

/* Autofilled fields — Chrome paints its own pale blue over the field background and its
   own text colour over ours, which on the login form left two blue boxes sitting in a
   cream card, and is unreadable outright in dark mode. There is no property to switch it
   off, so the background is repainted with an inset shadow (the one thing autofill does
   not override) and the text colour forced. */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active,
textarea:-webkit-autofill,
select:-webkit-autofill{
  -webkit-text-fill-color: var(--text);
  -webkit-box-shadow: 0 0 0 100px var(--card) inset;
          box-shadow: 0 0 0 100px var(--card) inset;
  caret-color: var(--text);
  transition: background-color 9999s ease-in-out 0s;   /* outlast Chrome's own fade-in */
}

/* ── Header ─────────────────────────────────────────────────────────────────*/
/* Frosted, with a caveat worth writing down: the bar is `position: sticky`, which keeps it
   in normal flow, so page content flows AFTER it and never passes UNDERNEATH it. Measured
   on /browse at several scroll positions and nothing is ever behind the bar. That means
   backdrop-filter has nothing to refract here and the frost cannot actually show; what you
   get is the body colour tinting through, not glass.
   It is kept because it costs almost nothing and becomes correct the moment the bar is made
   `fixed`. If you want real glass on the header, that is the change to make — plus top
   padding on every page that has no hero, which is currently all of them but /browse.
   Opaque first so a browser without backdrop-filter, or a viewer who has asked for reduced
   transparency, gets a solid readable bar rather than a washed-out one. */
.navbar{ background:var(--surface); border-bottom:1px solid var(--border); backdrop-filter:none; }
:root[data-theme="dark"] .navbar{ background:var(--bg); }

@supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .navbar, :root[data-theme="dark"] .navbar{
    background:var(--glass-bg);
    -webkit-backdrop-filter:blur(var(--glass-blur,22px)) saturate(180%);
    backdrop-filter:blur(var(--glass-blur,22px)) saturate(180%);
    border-bottom:1px solid var(--glass-border);
    /* The lit top edge is what reads as "glass" rather than "translucent". */
    box-shadow:inset 0 1px 0 0 var(--glass-highlight);
  }
  /* Once scrolled there IS content underneath, so let it settle a little deeper. */
  .navbar.scrolled, :root[data-theme="dark"] .navbar.scrolled{
    box-shadow:inset 0 1px 0 0 var(--glass-highlight),
               0 1px 2px rgba(20,40,38,.04),
               0 10px 30px -14px rgba(20,40,38,.20);
  }
}
@media (prefers-reduced-transparency:reduce){
  .navbar, :root[data-theme="dark"] .navbar{
    background:var(--surface) !important;
    -webkit-backdrop-filter:none !important; backdrop-filter:none !important;
  }
  :root[data-theme="dark"] .navbar{ background:var(--bg) !important; }
}
.brand-logo--full{ height:34px !important; }
.brand-logo--mark{ height:34px !important; width:34px !important; }
.navbar.scrolled .brand-logo--mark{ max-width:44px !important; }
/* teal logo on light; light on dark.
   NOTE: .brand-logo is NOT handled here. base.html carries an inline <style> that comes
   after this file and wins, so the rule that actually applies to the nav wordmark, the
   right-click menu wordmark and the auth wordmark lives there. Kept for .mq-logo only;
   putting .brand-logo back here just recreates a rule that silently loses. */
:root[data-theme="dark"] .mq-logo{ filter:brightness(0) invert(0.94); }
@media (prefers-color-scheme: dark){
  :root[data-theme="system"] .mq-logo{ filter:brightness(0) invert(0.94); }
}
.nav-link.active{ color:var(--accent); }

/* theme toggle button */
.theme-toggle{ background:transparent; border:1px solid var(--border-2); border-radius:7px; width:36px; height:34px;
  display:inline-grid; place-items:center; cursor:pointer; color:var(--soft); }
.theme-toggle:hover{ color:var(--text); border-color:var(--text); }
.theme-toggle .ic-sun{ display:none; } .theme-toggle .ic-moon{ display:block; }
:root[data-theme="dark"] .theme-toggle .ic-sun{ display:block; }
:root[data-theme="dark"] .theme-toggle .ic-moon{ display:none; }

/* ── Full-bleed video hero — adapts to theme (light video in light, dark in dark) ──*/
.mq-hero{ position:relative; width:100%; min-height:clamp(360px,56vh,560px); background:#FAF8F1;
  display:grid; align-items:center; overflow:hidden; border-bottom:1px solid var(--border); }
.mq-hero-vid{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; z-index:0; }
.mq-hero::after{ content:""; position:absolute; inset:0; z-index:1;
  background:linear-gradient(90deg, rgba(250,248,241,0.94) 0%, rgba(250,248,241,0.64) 48%, rgba(250,248,241,0.22) 100%); }
.mq-hero-inner{ position:relative; z-index:2; max-width:1160px; width:100%; margin:0 auto; padding:56px 24px; }
.mq-eyebrow{ font-weight:700; letter-spacing:.16em; text-transform:uppercase; font-size:.72rem; color:var(--accent-press); }
.mq-hero-h1{ font-family:var(--font-display); font-weight:600; color:#16211E; letter-spacing:-.02em;
  font-size:clamp(2.1rem,5vw,3.5rem); line-height:1.04; margin:.5rem 0 0; max-width:15ch; }
.mq-hero-sub{ color:#3F4A45; font-size:1.05rem; line-height:1.55; max-width:44ch; margin:1rem 0 1.6rem; }
.mq-hero-cta{ display:flex; gap:.7rem; flex-wrap:wrap; }
.mq-hero .btn-ghost{ color:#16211E; border-color:rgba(20,50,45,.28); }
.mq-hero .btn-ghost:hover{ border-color:#16211E; background:rgba(20,50,45,.05); }
.mq-hero-trust{ display:flex; gap:18px; flex-wrap:wrap; margin-top:1.5rem; color:#5A635E; font-size:.82rem; font-weight:500; }
.mq-hero-trust span{ display:inline-flex; align-items:center; gap:6px; }
:root[data-theme="dark"] .mq-hero{ background:#0B0B0C; }
:root[data-theme="dark"] .mq-hero-vid{ filter:brightness(0.62); }
:root[data-theme="dark"] .mq-hero::after{ background:linear-gradient(90deg, rgba(8,8,9,0.86) 0%, rgba(8,8,9,0.55) 46%, rgba(8,8,9,0.25) 100%); }
:root[data-theme="dark"] .mq-eyebrow{ color:#7FE0DE; }
:root[data-theme="dark"] .mq-hero-h1{ color:#F6F1E6; }
:root[data-theme="dark"] .mq-hero-sub{ color:#D9D2C4; }
:root[data-theme="dark"] .mq-hero .btn-ghost{ color:#F6F1E6; border-color:rgba(246,241,230,.4); }
:root[data-theme="dark"] .mq-hero .btn-ghost:hover{ border-color:#F6F1E6; background:rgba(246,241,230,.08); }
:root[data-theme="dark"] .mq-hero-trust{ color:#BEB6A6; }
@media (prefers-reduced-motion: reduce){ .mq-hero-vid{ display:none; } }

/* ── Section shell ──────────────────────────────────────────────────────────*/
.mq-section{ max-width:1160px; margin:0 auto; padding:56px 24px; }
.mq-sec-head{ display:flex; align-items:flex-end; justify-content:space-between; gap:16px; flex-wrap:wrap; margin-bottom:22px; }
.mq-sec-head h2{ font-family:var(--font-display); font-weight:600; font-size:1.65rem; letter-spacing:-.01em; color:var(--text); }
.mq-sec-head p{ color:var(--muted); font-size:.9rem; margin-top:3px; }
.mq-sec-head a{ font-weight:600; font-size:.88rem; color:var(--accent); text-decoration:none; white-space:nowrap; }

/* category photo cards */
/* An index, not a card grid. Tinted rounded tiles in fifteen different pastels read as a
   template — the colour carried no meaning. This is set like a printed directory: hairline
   rules, one accent, the count aligned right where the eye can compare it. */
.mq-cats{ display:grid; grid-template-columns:repeat(auto-fill,minmax(280px,1fr));
  gap:0 2.5rem; border-top:1px solid var(--border); }
.mq-cat{ display:flex; align-items:center; gap:.75rem; padding:.85rem .25rem;
  border-bottom:1px solid var(--border); text-decoration:none; color:var(--text);
  transition:padding-left .18s var(--ease-out,ease), color .18s ease; }
.mq-cat:hover{ padding-left:.75rem; color:var(--accent); }
.mq-cat-ic{ flex:0 0 auto; color:var(--muted); display:inline-flex;
  transition:color .18s ease; }
.mq-cat:hover .mq-cat-ic{ color:var(--accent); }
.mq-cat b{ flex:1; min-width:0; font-weight:550; font-size:.95rem; letter-spacing:-.005em;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* Count sits in a fixed column so the numbers line up down the page. Blank when a
   category is empty — an explicit "0" advertises the thing we don't want to advertise. */
.mq-cat-n{ flex:0 0 2.2rem; text-align:right; font-family:var(--font-mono,monospace);
  font-size:.78rem; color:var(--muted); font-variant-numeric:tabular-nums; }
@media(max-width:520px){ .mq-cats{ grid-template-columns:1fr; gap:0; } }

/* text category chips (all categories) */
.mq-catlist{ display:flex; flex-wrap:wrap; gap:8px; margin-top:26px; }
.mq-catlist a{ display:inline-flex; align-items:center; gap:7px; padding:.5rem .85rem; border:1px solid var(--border);
  border-radius:7px; background:var(--card); color:var(--soft); text-decoration:none; font-size:.86rem; font-weight:500; }
.mq-catlist a:hover{ border-color:var(--accent); color:var(--text); }

/* ── Trust band (contained to its content width — no dead space either side) ──*/
.mq-trust{ max-width:1160px; margin:0 auto 2.5rem; background:var(--surface-2);
  border:1px solid var(--border); border-radius:var(--radius); overflow:hidden; }
.mq-trust-in{ display:grid; grid-template-columns:repeat(3,1fr); }
.mq-trust .c{ padding:28px 30px; border-right:1px solid var(--border); }
.mq-trust .c:last-child{ border-right:0; }
.mq-trust .c h3{ font-family:var(--font-display); font-weight:600; font-size:1.08rem; display:flex; align-items:center; gap:9px; margin:0 0 8px; color:var(--text); }
.mq-trust .c h3 .ic{ width:20px; height:20px; color:var(--accent); flex:0 0 auto; }
.mq-trust .c p{ color:var(--soft); font-size:.9rem; line-height:1.6; margin:0; }
@media(max-width:760px){ .mq-trust-in{ grid-template-columns:1fr; } .mq-trust .c{ border-right:0; border-bottom:1px solid var(--border); } .mq-trust .c:last-child{ border-bottom:0; } }

/* ── Footer + duck easter-egg ───────────────────────────────────────────────*/
.site-footer{ position:relative; overflow:hidden; background:var(--surface); border-top:1px solid var(--border); }
.mq-duck-mark{ position:absolute; right:-40px; bottom:-46px; width:min(42vw,440px); aspect-ratio:681/794; pointer-events:none; z-index:0;
  background:currentColor; color:var(--accent); opacity:.05;
  -webkit-mask:url("/static/img/brand/duck-mark.webp") center/contain no-repeat; mask:url("/static/img/brand/duck-mark.webp") center/contain no-repeat; }
:root[data-theme="dark"] .mq-duck-mark{ opacity:.07; }
.site-footer-inner{ position:relative; z-index:1; }

/* ── Profanity blur on reviews ──────────────────────────────────────────────*/
.blur-word{ filter:blur(5px); -webkit-user-select:none; user-select:none; background:color-mix(in srgb,var(--muted) 22%,transparent);
  border-radius:3px; padding:0 .12em; }

/* ── Misc polish ────────────────────────────────────────────────────────────*/
.hero-bubble{ display:none !important; }   /* kill the old floating AI bubbles */
.provider-rating,.rate{ color:var(--gold); }
.pc-cta,.check-go,.go{ color:var(--accent); }
.empty-state .empty-ico{ opacity:.35; }
.finish-banner{ background:color-mix(in srgb,var(--accent) 10%, var(--card)); border-color:var(--accent); }


/* ── Toasts ─────────────────────────────────────────────────────────────────
   Flash messages, top-right under the header. Frosted, because they float over the page
   — the case where backdrop-filter has something behind it to work with. Opaque first so
   a browser without it, or a viewer who asked for reduced transparency, still gets a
   solid readable card. */
.toasts{
  position:fixed; top:calc(58px + 0.75rem); right:0.9rem; z-index:300;
  display:flex; flex-direction:column; gap:0.5rem;
  width:min(24rem, calc(100vw - 1.8rem)); pointer-events:none;
}
.toast{
  pointer-events:auto; display:flex; align-items:flex-start; gap:0.6rem;
  padding:0.7rem 0.8rem; border-radius:10px;
  background:var(--card); border:1px solid var(--glass-border,var(--border));
  color:var(--text); font-size:0.86rem; line-height:1.45;
  box-shadow:inset 0 1px 0 0 var(--glass-highlight),
             0 2px 6px rgba(20,40,38,.05), 0 14px 34px -12px rgba(20,40,38,.28);
  /* A left edge carries the meaning, so the whole card need not be tinted. */
  border-left:3px solid var(--green);
  animation:toastIn .22s cubic-bezier(.22,1,.36,1);
  transition:opacity .2s ease, transform .2s ease;
}
@supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .toast{ background:var(--glass-bg);
    -webkit-backdrop-filter:blur(var(--glass-blur,22px)) saturate(180%);
    backdrop-filter:blur(var(--glass-blur,22px)) saturate(180%); }
}
.toast--error, .toast--danger, .toast--warning{ border-left-color:var(--ember); }
.toast-msg{ flex:1 1 auto; }
.toast-x{
  flex:0 0 auto; background:none; border:0; color:var(--muted);
  font-size:1.15rem; line-height:1; cursor:pointer; padding:0 .1rem; border-radius:5px;
}
.toast-x:hover{ color:var(--text); }
.toast--out{ opacity:0; transform:translateX(12px); }
@keyframes toastIn{ from{ opacity:0; transform:translateX(16px); } to{ opacity:1; transform:none; } }
@media (prefers-reduced-motion:reduce){
  .toast{ animation:none; transition:none; }
}
@media (prefers-reduced-transparency:reduce){
  .toast{ background:var(--card) !important;
    -webkit-backdrop-filter:none !important; backdrop-filter:none !important; }
}
@media (max-width:560px){
  /* Full width under the header on a phone, where a 24rem card would hang off the edge. */
  .toasts{ left:0.9rem; right:0.9rem; width:auto; }
}


/* ── Calendar surface ────────────────────────────────────────────────────────
   Shared by BOTH calendars: the month grid (_calendar.html, on the bookings pages) and
   the booking picker (_bookingcal.html, on a provider's listing). This lived inline in
   _calendar.html, so the picker never got it and kept rendering the old 78px bordered
   cells while the other calendar looked new — the two drifted apart invisibly.
/* ── Calendar surface ─────────────────────────────────────────────────────
   Previously every cell drew its own background, 1px border and 8px radius with a 4px
   gap, so a month rendered as 42 separate cards. The chrome outweighed the content —
   on a page with one blocked slot, the loudest thing on screen was the lattice.

   Now the grid itself is the border colour and the 1px gap becomes the hairline
   between days, so the month reads as one surface with divisions rather than a pile
   of tiles. Cells own no border at all. */
/* The weekday header must share the body's column rhythm, or its labels drift off
   their columns — 7 columns means 6 gaps, so 4px vs 1px is ~18px of accumulated skew. */
.cal-dow { gap: 1px; padding: 0 1px; }
.cal-body { gap: 1px; background: var(--border); border: 1px solid var(--border);
  overflow: hidden; }
.cal-body .cal-day { background: var(--card); border: 0; border-radius: 0;
  min-height: 64px; padding: 5px 6px; }

/* Days from the neighbouring month are context, not content: recede the whole cell
   rather than fading a card that should not have been drawn in the first place. */
.cal-body .cal-day--out { background: var(--surface-2); }
.cal-body .cal-day--out .cal-daynum { opacity: 0.5; }
.cal-body .cal-day--out .cal-ev { opacity: 0.45; }

/* A flat tint, not a 45-degree hatch. Stripes are texture, and texture competes with
   the events sitting on top of them. */
.cal-body .cal-day--closed { background: var(--surface-2); background-image: none; }

/* Rings, not borders — a border would fight the hairline grid and shift the cell. */
.cal-body .cal-day--today { border: 0; box-shadow: inset 0 0 0 2px var(--accent); }

.cal-daynum { font-size: 0.72rem; }

/* Imported and blocked time read as quiet chips. They were dashed outlines, and a
   dashed border reads as provisional — like something half-entered. */
.cal-body .cal-ev--external { border: 0;
  background: color-mix(in srgb, var(--soft) 16%, transparent); color: var(--soft); }
.cal-body .cal-ev--mine {
  background: color-mix(in srgb, var(--accent) 18%, transparent); color: var(--text); }

/* The nav is a pair, not two loose buttons at opposite ends of the page. */
.cal-nav { display: inline-flex; gap: 0.35rem; }
/* Public holiday name in the day cell. Quiet — it is context, not an alert, and it
   appears on both the provider and customer calendars. */
.cal-hol { display: block; font-size: 0.62rem; line-height: 1.25; color: var(--gold);
  margin-top: 1px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
