/* ---- tokens.css ---- */
/* The variables every rule below reads. Colours come from site.json as
   :root variables the build writes; the rest is here. */

/* ==========================================================================
   Shared theme for every site.
   - Colors come from site.json and are injected as :root variables.
   - Typography and shape come from the [data-preset] blocks below.
   Edit here once and every site picks it up on the next build.
   ========================================================================== */

:root {
  --tint: color-mix(in srgb, var(--brand) 7%, var(--paper));
  --muted: color-mix(in srgb, var(--ink) 74%, var(--paper));
  --line: color-mix(in srgb, var(--ink) 14%, transparent);
  --link: var(--brand);
  --focus: var(--brand);

  --font-display: system-ui, sans-serif;
  --font-body: system-ui, sans-serif;
  --display-weight: 700;
  --display-stretch: 100%;
  --display-tracking: -0.01em;

  --radius: 6px;
  --radius-lg: 10px;
  --rule: 1px solid var(--line);

  /* Type scale: 17px base, ~1.25 ratio */
  --step--1: 0.875rem;
  --step-0: 1.0625rem;
  --step-1: 1.3rem;
  --step-2: 1.6rem;
  --step-3: clamp(1.75rem, 1.35rem + 1.6vw, 2.3rem);
  --step-4: clamp(2.05rem, 1.45rem + 2.6vw, 3rem);
  --hero-size: clamp(2.6rem, 1.6rem + 4.4vw, 4.4rem);
  --hero-measure: 16ch;
  --plate-size: clamp(2.2rem, 1rem + 5vw, 3.6rem);

  --text-scale: 1;
  --space-section: clamp(4rem, 3rem + 5vw, 7rem);
  --measure: 66ch;
  --max: 74rem;
}

html { font-size: calc(100% * var(--text-scale, 1)); }

/* ---- base.css ---- */
/* Type scale, rhythm, and the elements before any component. */

*, *::before, *::after { box-sizing: border-box; }

/* `hidden` means hidden, whatever a component says about its own display.
   The attribute is only `display: none` in the browser's own stylesheet, so
   any rule of ours that sets display — `.btn { display: inline-flex }` — beats
   it and the element stays on the page. Five components had each written
   their own `X[hidden] { display: none }` to work around that; the share
   button forgot to, and appeared without a script behind it to do anything.
   One rule, for everything, so the sixth cannot forget. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: 5.5rem; }

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

img { display: block; max-width: 100%; height: auto; }

h1, h2, h3 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  font-stretch: var(--display-stretch);
  letter-spacing: var(--display-tracking);
  line-height: 1.1;
  text-wrap: balance;
}

p { margin: 0 0 1em; }

p:last-child { margin-bottom: 0; }

a { color: var(--link); text-underline-offset: 0.2em; }

:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }

.icon { width: 1.25em; height: 1.25em; flex: none; }

.wrap { width: min(100% - 2.5rem, var(--max)); margin-inline: auto; }

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

.skip-link {
  position: absolute; left: 1rem; top: -10rem; z-index: 100;
  padding: 0.75rem 1rem; background: var(--ink); color: var(--on-ink); border-radius: var(--radius);
}

.skip-link:focus { top: 1rem; }

/* Motion is a courtesy, never a requirement: nothing on the page moves unless
   the visitor did something, and for those who have asked their system for
   less of it, nothing moves at all. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; }
}

/* ---- buttons.css ---- */
.btn {
  display: inline-flex; align-items: center; gap: 0.55em;
  padding: 0.85em 1.35em;
  border: 2px solid transparent; border-radius: var(--radius);
  font: 600 var(--step-0)/1.1 var(--font-body);
  text-decoration: none; cursor: pointer;
  transition: background-color 0.15s, color 0.15s, border-color 0.15s;
}

.btn .icon { width: 1.1em; height: 1.1em; }

.btn--accent { background: var(--accent); color: var(--on-accent); }

.btn--accent:hover { background: color-mix(in srgb, var(--accent) 86%, var(--ink)); }

.btn--brand { background: var(--brand); color: var(--on-brand); }

.btn--brand:hover { background: color-mix(in srgb, var(--brand) 84%, var(--ink)); }

.btn--ghost { background: transparent; color: inherit; border-color: currentColor; }

.btn--ghost:hover { background: color-mix(in srgb, currentColor 10%, transparent); }

.btn--sm { padding: 0.6em 1em; font-size: 0.95rem; }

.btn:disabled { opacity: 0.6; cursor: progress; }

/* ---- preview-bar.css ---- */
.preview-bar { background: var(--ink); color: var(--on-ink); font-size: 0.9rem; --focus: var(--accent); }

.preview-bar__inner { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1.25rem; padding-block: 0.6rem; }

.preview-bar p { margin: 0; flex: 1 1 22rem; }

.preview-bar__cta { color: inherit; font-weight: 700; }

.preview-bar__close {
  display: inline-grid; place-items: center; min-width: 1.75rem; min-height: 1.75rem; padding: 0.3rem;
  background: none; border: 0; color: inherit; cursor: pointer;
}


/* ---- header.css ---- */
/* An announcement across the top: one line, the accent colour, a link if there is one. */
.announce { background: var(--accent); color: var(--on-accent); font-size: 0.95rem; text-align: center; }
.announce p { margin: 0; padding: 0.55rem 0; }
.announce a { color: inherit; font-weight: 600; text-underline-offset: 0.15em; }

.site-header { position: sticky; top: 0; z-index: 20; background: var(--paper); border-bottom: 1px solid var(--line); }

.header__inner { display: flex; align-items: center; gap: 1.5rem; min-height: 4.5rem; }

.brand { display: flex; flex-direction: column; margin-right: auto; color: var(--ink); text-decoration: none; line-height: 1; }

.brand img { max-height: 2.75rem; width: auto; }

/* A mark beside the wordmark: the drawing left, the words stacked to its right. */
.brand--marked { flex-direction: row; align-items: center; gap: 0.7rem; }
.brand__icon { width: 2.5rem; height: 2.5rem; flex: 0 0 auto; }
.brand__text { display: flex; flex-direction: column; }

.brand__mark {
  font-family: var(--font-display); font-weight: var(--display-weight);
  font-stretch: var(--display-stretch); letter-spacing: var(--display-tracking);
  font-size: 1.55rem;
}

.brand__desc { margin-top: 0.3rem; font-size: 0.8rem; font-weight: 600; color: var(--muted); }

.site-nav ul { display: flex; gap: 1.75rem; margin: 0; padding: 0; list-style: none; }

.site-nav a { padding-block: 0.5rem; color: var(--ink); font-weight: 500; text-decoration: none; }

.site-nav a:hover { color: var(--brand); text-decoration: underline; }

.header__actions { display: flex; align-items: center; gap: 0.5rem; }

.nav-toggle {
  display: none; place-items: center; width: 2.75rem; height: 2.75rem; padding: 0;
  background: none; border: 1px solid var(--line); border-radius: var(--radius); color: var(--ink); cursor: pointer;
}

.nav-toggle .icon { width: 1.4rem; height: 1.4rem; }

.header-call__short { display: none; }

@media (max-width: 63.99rem) {
  .nav-toggle { display: inline-grid; }
  .site-nav {
    display: none; position: absolute; inset: 100% 0 auto 0;
    background: var(--paper); border-bottom: 1px solid var(--line);
    box-shadow: 0 12px 24px -12px color-mix(in srgb, var(--ink) 30%, transparent);
  }
  .site-nav.is-open { display: block; }
  .site-nav ul { flex-direction: column; gap: 0; width: min(100% - 2.5rem, var(--max)); margin-inline: auto; padding-block: 0.5rem 1rem; }
  .site-nav li + li { border-top: 1px solid var(--line); }
  .site-nav a { display: block; padding-block: 0.9rem; font-size: 1.1rem; }
  .header-call__num { display: none; }
  .header-call__short { display: inline; }
}

/* ---- hero.css ---- */
.hero { position: relative; padding-block: clamp(3rem, 2rem + 5vw, 6.5rem); }

.hero__grid { display: grid; gap: 2.5rem; align-items: center; }

.hero__title { font-size: var(--hero-size); line-height: 1; max-width: var(--hero-measure); }

.hero__text { max-width: 36ch; margin-top: 1.5rem; font-size: var(--step-1); line-height: 1.5; }

.hero__actions { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 2rem; }

.hero__badges {
  display: flex; flex-wrap: wrap; gap: 0.6rem 1.5rem;
  margin: 2rem 0 0; padding: 0; list-style: none;
  font-size: 0.95rem; font-weight: 600;
}

.hero__badges li { display: flex; align-items: center; gap: 0.4rem; }

.hero__badges .icon { width: 1.1em; height: 1.1em; color: var(--badge-icon, var(--brand)); stroke-width: 2.5; }

.hero__aside { position: relative; display: grid; gap: 1.25rem; }

.hero__photo { margin: 0; overflow: hidden; border-radius: var(--radius-lg); aspect-ratio: 4 / 3; }

.hero__photo img { width: 100%; height: 100%; object-fit: cover; }

.plate {
  container-type: inline-size;
  display: block; padding: 1.5rem 1.75rem;
  border-radius: var(--radius-lg);
  background: var(--plate-bg, var(--brand)); color: var(--plate-fg, var(--on-brand));
  text-decoration: none;
}

.plate__label { display: block; font-size: 0.95rem; font-weight: 600; }

.plate__value {
  display: block; margin-top: 0.35rem;
  font-family: var(--font-display); font-weight: var(--display-weight);
  font-stretch: var(--display-stretch); letter-spacing: var(--display-tracking);
  font-size: min(var(--plate-size), var(--plate-fit, 15cqi)); line-height: 1;
  /* The cap above is tuned to each preset's own typeface. With another one —
     chosen in the switcher, or set by `theme.font` — the script measures and
     shrinks the line to fit; without the script it wraps at the space rather
     than run off the edge of the plate. */
  white-space: normal;
}

.plate__note { display: block; margin-top: 0.8rem; font-size: 0.95rem; }

a.plate:hover .plate__value { text-decoration: underline; text-decoration-thickness: 0.06em; text-underline-offset: 0.12em; }

@media (min-width: 56rem) {
  .hero__grid { grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr); gap: 4rem; }
  .hero--photo .hero__photo { aspect-ratio: 4 / 5; }
}

/* workshop: dark van-panel hero with a two-tone fleet stripe */

/* storefront: arched shop-window photo, sign-style plate */

/* studio: open page, plate as a quiet card */

/* ---- sections.css ---- */
/* The sections between the hero and the contact block: services, about,
   areas, reviews, gallery and carousel, FAQ, embeds, and the contact form. */

.s { padding-block: var(--space-section); }

.s--tint { background: var(--tint); }

.s__head { max-width: 42rem; margin-bottom: clamp(2rem, 1.5rem + 2vw, 3.25rem); }

.s__head h2 { font-size: var(--step-4); }

.s__intro { margin-top: 1rem; font-size: var(--step-1); line-height: 1.5; color: var(--muted); }

.s__note, .s__more { margin-top: 2rem; color: var(--muted); }

.s__more a { font-weight: 600; }

/* Services */

.svc-list {
  display: grid; gap: 0 2.5rem; margin: 0; padding: 0; list-style: none;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr));
}

.svc { padding-block: 1.5rem 2rem; border-top: var(--rule); }

.svc__icon {
  display: inline-grid; place-items: center; width: 2.75rem; height: 2.75rem; margin-bottom: 1rem;
  border-radius: var(--radius); background: var(--tint); color: var(--brand);
}

.s--tint .svc__icon { background: var(--paper); }

.svc__icon .icon { width: 1.5rem; height: 1.5rem; }

.svc__title { margin-bottom: 0.5rem; font-size: var(--step-2); }

.svc p { color: var(--muted); }

.svc .svc__price { margin-top: 0.75rem; color: var(--ink); font-weight: 700; }
.svc__more { display: inline-block; margin-top: 0.75rem; font-weight: 600; }

/* About */

.about { display: grid; gap: 3rem; }

.about__text { max-width: var(--measure); }

.about__text .s__head { margin-bottom: 1.5rem; }

.about__sig { margin-top: 1.5rem; font-weight: 700; }

.about__photo { margin: 0 0 1.5rem; overflow: hidden; border-radius: var(--radius-lg); aspect-ratio: 4 / 3; }

.about__photo img { width: 100%; height: 100%; object-fit: cover; }

.checks { padding: 1.75rem; background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-lg); }

.s--plain .checks { background: var(--tint); border-color: transparent; }

.checks__h { margin-bottom: 1rem; font-size: var(--step-1); }

.checks ul { display: grid; gap: 1rem; margin: 0; padding: 0; list-style: none; }

.checks li { display: grid; grid-template-columns: 1.5rem 1fr; gap: 0.75rem; font-weight: 500; }

.checks .icon { width: 1.35rem; height: 1.35rem; margin-top: 0.15rem; color: var(--brand); stroke-width: 2.5; }

@media (min-width: 56rem) {
  .about { grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr); gap: 5rem; align-items: start; }
  .about--solo { grid-template-columns: 1fr; }
}

/* Service areas */

.areas { margin: 0; padding: 0; list-style: none; columns: 2 10rem; column-gap: 2.5rem; }

.areas li { padding-block: 0.7rem; border-bottom: 1px solid var(--line); break-inside: avoid; font-weight: 600; }

@media (min-width: 48rem) { .areas { columns: 4 10rem; } }

/* Testimonials */

.quotes { display: grid; gap: 1.5rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr)); }

.quote {
  display: flex; flex-direction: column; margin: 0; padding: 2rem;
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-lg);
}

.s--tint .quote { border-color: transparent; }

.quote blockquote { flex: 1; margin: 0; font-size: 1.15rem; line-height: 1.55; }

.quote blockquote::before {
  content: "\201C"; display: block; height: 2.2rem;
  font-family: var(--font-display); font-size: 4rem; line-height: 1; color: var(--brand);
}

.stars + blockquote::before { display: none; }

.quote figcaption { margin-top: 1.5rem; font-size: 0.95rem; }

.quote__name { display: block; font-weight: 700; }

.quote__detail { color: var(--muted); }

.stars { display: flex; gap: 0.15rem; margin: 0 0 0.75rem; color: color-mix(in srgb, var(--accent) 70%, var(--ink)); }

.stars .icon { width: 1.1rem; height: 1.1rem; fill: var(--accent); }

/* Gallery */

.gallery {
  display: grid; gap: 0.75rem; margin: 0; padding: 0; list-style: none; grid-auto-flow: dense;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (min-width: 48rem) { .gallery { grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); } }

.gallery figure { margin: 0; height: 100%; display: flex; flex-direction: column; }

.gallery img { flex: 1; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: var(--radius); }

.gallery figcaption { margin-top: 0.5rem; font-size: 0.9rem; color: var(--muted); }

/* Feature the first photo only when the rest fill the grid with no gaps */

@media (min-width: 48rem) {
  .gallery[data-count="3"] { grid-template-columns: 2fr 1fr; }
  .gallery[data-count="5"] { grid-template-columns: repeat(4, 1fr); }
  .gallery[data-count="3"] li:first-child { grid-row: span 2; }
  .gallery[data-count="5"] li:first-child { grid-column: span 2; grid-row: span 2; }
  .gallery[data-count="3"] li:first-child img, .gallery[data-count="5"] li:first-child img { aspect-ratio: auto; }
}

/* FAQ */

/* ---------- Carousel ----------
   A scroll-snap track, so it works before site.js runs and keeps working if
   the script fails: swipe on a phone, drag or shift-scroll on a desktop, tab
   in and use the arrow keys. The buttons underneath are an enhancement, not
   the mechanism. */

.carousel { position: relative; }

.carousel__track {
  display: flex; gap: 0.9rem; margin: 0; padding: 0 0 0.35rem; list-style: none;
  /* Snapping is only demanded where swiping is the interaction. On a
     desktop, `mandatory` makes Safari treat a two-finger scroll over the row
     as a horizontal gesture and snap, so the page underneath never moves;
     `proximity` lets the gesture's direction decide, and the arrows and dots
     still land exactly because they scroll to measured positions. */
  overflow-x: auto; scroll-snap-type: x proximity; scroll-behavior: smooth;
  overscroll-behavior-x: contain;
  /* The scrollbar is the only affordance without JavaScript, so it stays. */
  scrollbar-width: thin; scrollbar-color: var(--line) transparent;
}

@media (pointer: coarse) { .carousel__track { scroll-snap-type: x mandatory; } }

.carousel__track:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }

.carousel__track::-webkit-scrollbar { height: 6px; }

.carousel__track::-webkit-scrollbar-thumb { background: var(--line); border-radius: 999px; }

.carousel__slide {
  flex: 0 0 min(78%, 26rem); scroll-snap-align: start; margin: 0;
}

.carousel[data-per-view="1"] .carousel__slide { flex-basis: 100%; }

.carousel__slide figure { margin: 0; }

.carousel__slide img {
  width: 100%; aspect-ratio: var(--carousel-ratio, 3 / 2); object-fit: cover;
  border-radius: var(--radius-lg); background: var(--tint);
}

.carousel__slide figcaption { margin-top: 0.6rem; font-size: 0.9rem; color: var(--muted); }

.carousel__controls {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 0.75rem; margin-top: 1.1rem;
}

/* "2 of 8 pictures": under the arrows on a gallery, beside them on the examples row. */
.carousel__status { flex-basis: 100%; order: 2; margin: 0; text-align: center; font-size: 0.9rem; color: var(--muted); }

.carousel__nav {
  display: grid; place-items: center; width: 2.6rem; height: 2.6rem; flex: 0 0 auto;
  cursor: pointer; color: var(--ink); background: var(--paper);
  border: var(--rule); border-radius: 999px;
}

.carousel__nav:hover:not(:disabled) { color: var(--on-brand); background: var(--brand); border-color: var(--brand); }

.carousel__nav:disabled { opacity: 0.35; cursor: default; }

.carousel__nav .icon { width: 1.25rem; height: 1.25rem; }

.carousel__dots { display: flex; align-items: center; gap: 0.45rem; }

.carousel__dot {
  width: 0.5rem; height: 0.5rem; padding: 0; cursor: pointer;
  background: var(--line); border: 0; border-radius: 999px;
  transition: width 0.18s ease, background-color 0.18s ease;
}

.carousel__dot[aria-current="true"] { width: 1.5rem; background: var(--brand); }

/* Cards as a swipeable row — the examples on the studio, reviews on any site
   (`layout: "carousel"` on the section). One, two or three whole cards to a
   view by width — never a card cut off at the edge, which reads as a layout
   bug however deliberate it is. That the row continues is said instead by the
   controls, which sit above the row beside the heading where the eye already
   is, with "1–3 of 6 reviews" next to them; a row that already fits shows no
   controls at all. Slides stretch to the tallest and the card fills its slide,
   so a short review does not leave a card hanging above the others' bottom
   edge; a scrollbar under a row of cards reads as a mistake. A fraction here
   (3.2) would show a sliver of the next card, if that were ever wanted. */

.cards-carousel .carousel { display: flex; flex-direction: column; }

.cards-carousel .carousel__controls { order: -1; justify-content: flex-end; margin: 0 0 1.25rem; }

.cards-carousel .carousel__status { flex: 1 1 auto; order: 0; text-align: left; }

.cards-carousel .carousel__track {
  --cards-gap: 1.25rem; --cards-per-view: 1;
  gap: var(--cards-gap); padding-bottom: 0.25rem; scrollbar-width: none;
}

.cards-carousel .carousel__track::-webkit-scrollbar { display: none; }

.cards-carousel .carousel__slide {
  display: flex;
  flex-basis: calc((100% - var(--cards-gap) * (var(--cards-per-view) - 1)) / var(--cards-per-view));
}

.cards-carousel .carousel__slide > * { flex: 1; }

@media (min-width: 48rem) { .cards-carousel .carousel__track { --cards-per-view: 2; } }

@media (min-width: 72rem) { .cards-carousel .carousel__track { --cards-per-view: 3; } }

.carousel__dot:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }

@media (min-width: 48rem) {
  .carousel__slide { flex-basis: min(46%, 30rem); }
  .carousel[data-per-view="1"] .carousel__slide { flex-basis: 100%; }
}

/* Somebody who has asked their operating system to stop moving things means
   it: no smooth scrolling, no width transition, and autoplay never starts. */

@media (prefers-reduced-motion: reduce) {
  .carousel__track { scroll-behavior: auto; }
  .carousel__dot { transition: none; }
}

/* Embeds. A third party's iframe or widget arrives sized for somebody else's
   page; these are the two rules that stop it overflowing a phone. */

.s--html iframe { max-width: 100%; border: 0; }

.s--html .wrap > *:not(.s__head) { margin-inline: auto; }

.faq { max-width: 48rem; border-top: 1px solid var(--line); }

.faq__item { border-bottom: 1px solid var(--line); }

.faq__item summary {
  position: relative; padding: 1.3rem 2.5rem 1.3rem 0;
  font-size: 1.15rem; font-weight: 600; cursor: pointer; list-style: none;
}

.faq__item summary::-webkit-details-marker { display: none; }

.faq__item summary::after {
  content: ""; position: absolute; right: 0.4rem; top: 50%; width: 0.6rem; height: 0.6rem;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: translateY(-70%) rotate(45deg); transition: transform 0.2s;
}

.faq__item[open] summary::after { transform: translateY(-25%) rotate(-135deg); }

.faq__a { max-width: var(--measure); padding-bottom: 1.5rem; color: var(--muted); }

@media (min-width: 56rem) {
  .s--faq > .wrap { display: grid; grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr); gap: 4rem; align-items: start; }
  .s--faq .s__head { margin-bottom: 0; }
}

/* Call-to-action band */

.s--cta { padding-block: clamp(3rem, 2rem + 4vw, 5rem); background: var(--brand); color: var(--on-brand); --focus: var(--on-brand); }

.cta { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1.5rem 3rem; }

.cta h2 { font-size: var(--step-3); }

.cta p { max-width: 40rem; margin-top: 0.6rem; font-size: 1.1rem; }

.cta__actions { display: flex; flex-wrap: wrap; gap: 0.75rem; }

/* Contact */

.contact { display: grid; gap: 3rem; }

.contact__list { display: grid; gap: 1.25rem; margin: 0 0 2.5rem; }

.contact__list dt { font-size: 0.9rem; font-weight: 500; color: var(--muted); }

.contact__list dd { margin: 0.15rem 0 0; font-size: 1.25rem; font-weight: 600; }

.contact__list address { font-style: normal; }

.contact__list a { color: var(--ink); text-decoration-color: var(--line); }

.contact__list a:hover { text-decoration-color: currentColor; }

.contact__list .contact__dir { display: inline-block; margin-top: 0.4rem; font-size: 1rem; color: var(--link); }

.contact__sub { margin-bottom: 0.75rem; font-size: var(--step-1); }

.hours { width: 100%; max-width: 26rem; border-collapse: collapse; }

.hours th, .hours td { padding: 0.55rem 0; text-align: left; border-bottom: 1px solid var(--line); }

.hours th { padding-right: 1.5rem; font-weight: 600; }

.hours__note { margin-top: 1rem; font-weight: 700; color: var(--brand); }

.contact-form {
  align-self: start; padding: clamp(1.5rem, 1rem + 2vw, 2.5rem);
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-lg);
}

.contact-form h3 { margin-bottom: 1.5rem; font-size: var(--step-2); }

.field { display: grid; gap: 0.4rem; margin-bottom: 1.1rem; }

.field label { font-size: 0.95rem; font-weight: 600; }

.field input, .field select, .field textarea {
  width: 100%; padding: 0.75rem 0.9rem;
  font: inherit; color: inherit; background: var(--paper);
  border: 1px solid color-mix(in srgb, var(--ink) 30%, transparent); border-radius: var(--radius);
}

.field textarea { resize: vertical; min-height: 8rem; }

.field-row { display: grid; gap: 0 1rem; }

.field-row .field { margin-bottom: 0.5rem; }

.field-hint { margin: 0 0 1.1rem; font-size: 0.875rem; color: var(--muted); }

.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.form-status { margin: 1rem 0 0; font-weight: 600; }

.form-status:empty { display: none; }

.form-status.is-ok { color: #1a7f37; }

.form-status.is-error { color: #b42318; }

.form-note { margin-top: 1rem; font-size: 0.9rem; color: var(--muted); }

.map { margin-top: 3rem; overflow: hidden; aspect-ratio: 16 / 7; border: 1px solid var(--line); border-radius: var(--radius-lg); }

.map iframe { display: block; width: 100%; height: 100%; border: 0; }

@media (min-width: 36rem) { .field-row { grid-template-columns: 1fr 1fr; } }

@media (min-width: 56rem) { .contact { grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); gap: 5rem; } .contact--solo { grid-template-columns: 1fr; } }

@media (max-width: 47.99rem) { .map { aspect-ratio: 4 / 3; } }

/* ==========================================================================
   Preset character
   The four presets below were added after the original three. Their overrides
   are grouped per preset rather than scattered through each section, because
   each one is a coherent look rather than a tweak. One bold element each.
   ========================================================================== */

/* ---- Before and after: two pictures in one figure, each labelled ---- */
.pair { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; }
.pair__side { position: relative; display: block; }
.pair__side img { width: 100%; height: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: var(--radius); }
.pair__label {
  position: absolute; top: 0.5rem; left: 0.5rem; padding: 0.15rem 0.5rem; border-radius: 999px;
  background: rgb(0 0 0 / 0.55); color: #fff; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.04em;
}
.pair figcaption { grid-column: 1 / -1; }
.gallery .pair, .carousel__slide .pair { height: auto; }

/* ---- Holiday hours: under the regular hours, soonest first ---- */
.hours__special { margin: 0.75rem 0 0; padding: 0; list-style: none; font-size: 0.95rem; }
.hours__special li { display: flex; justify-content: space-between; gap: 1rem; padding: 0.35rem 0; border-top: 1px dashed var(--line); }

/* ---- People: the team, one card each ---- */
.people {
  display: grid; gap: 1.5rem; margin: 0; padding: 0; list-style: none;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 14rem), 1fr));
}
.person__photo { margin: 0 0 0.9rem; aspect-ratio: 4 / 5; overflow: hidden; border-radius: var(--radius-lg); background: var(--tint); }
.person__photo img { display: block; width: 100%; height: 100%; object-fit: cover; }
.person__name { margin: 0; font-size: var(--step-1); }
.person__role { margin: 0.15rem 0 0.5rem; color: var(--muted); font-size: 0.95rem; }
.person p { margin: 0; }

/* A picture shown whole (fit: "contain"): the frame takes the picture's own
   shape instead of imposing one, and nothing is cropped. */
.is-contain { aspect-ratio: auto; }
.is-contain img { height: auto; object-fit: contain; }

/* ---- beforeafter.css ---- */
/* Before and after: two photographs of the same place, one slider between
   them.

   The layout is chosen by whether the client script ran. Without it the pair
   sits side by side, which is what a magazine would print — a fine way to
   show the work and not a broken version of anything. With it, the two stack
   and a slider wipes between them.

   Shoot both photographs from the same spot: the frame crops them to one
   shape, and a pair taken from two different angles reads as two jobs. */

.ba-grid { display: grid; gap: 1.5rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); }

.ba { margin: 0; }

.ba figcaption { margin-top: 0.6rem; font-size: 0.9rem; color: var(--muted); }

.ba__img {
  width: 100%; height: 100%; display: block;
  aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: var(--radius-lg); background: var(--tint);
}

.ba__label {
  position: absolute; bottom: 0.6rem; z-index: 3;
  padding: 0.15rem 0.5rem; border-radius: 999px;
  font-size: 0.75rem; font-weight: 700; letter-spacing: 0.02em;
  /* Said in words, not only by which side it is on: "the left one" is not
     available to somebody looking at one photograph at a time. */
  background: rgb(0 0 0 / 0.66); color: #fff;
}

.ba__label--before { left: 0.6rem; }

.ba__label--after { right: 0.6rem; }

/* ---- Without the script: the pair, side by side ------------------------- */

.ba__frame { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; }

.ba__side { position: relative; display: block; }

.ba__handle, .ba__range { display: none; }

/* ---- With the script: one frame, wiped by the slider -------------------- */

.js .ba__frame {
  position: relative; display: block; gap: 0;
  aspect-ratio: 4 / 3; border-radius: var(--radius-lg); overflow: hidden;
  /* Where the wipe sits. The script writes this; the value here is what the
     range starts at, so the first paint already matches the thumb. */
  --ba: 50%;
}

.js .ba__side { position: absolute; inset: 0; }

.js .ba__img { aspect-ratio: auto; border-radius: 0; }

/* The after photograph is the base and the before is laid over it, clipped
   to everything left of the wipe. */
.js .ba__side--before { clip-path: inset(0 calc(100% - var(--ba)) 0 0); z-index: 2; }

.js .ba__handle {
  display: block; position: absolute; top: 0; bottom: 0; left: var(--ba);
  width: 2px; margin-left: -1px; z-index: 3;
  background: #fff; box-shadow: 0 0 0 1px rgb(0 0 0 / 0.25);
}

/* The range covers the whole frame and shows nothing but its thumb, so the
   photographs are what you see and the native control is what you use. */
.js .ba__range {
  display: block; position: absolute; inset: 0; z-index: 4;
  width: 100%; height: 100%; margin: 0; padding: 0;
  -webkit-appearance: none; appearance: none;
  background: transparent; cursor: ew-resize;
}

.js .ba__range:focus { outline: none; }

.ba__range::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 2.25rem; height: 2.25rem; border-radius: 999px;
  background: #fff; border: 2px solid var(--brand); box-shadow: 0 1px 6px rgb(0 0 0 / 0.3);
  cursor: ew-resize;
}

.ba__range::-moz-range-thumb {
  width: 2.25rem; height: 2.25rem; border-radius: 999px;
  background: #fff; border: 2px solid var(--brand); box-shadow: 0 1px 6px rgb(0 0 0 / 0.3);
  cursor: ew-resize;
}

.ba__range::-moz-range-track { background: transparent; border: 0; }

/* Focus has to be visible on the thumb itself: an outline around the frame
   would be an outline around a photograph, which says nothing about what the
   keyboard is about to move. */
.ba__range:focus-visible::-webkit-slider-thumb { outline: 3px solid var(--focus); outline-offset: 2px; }

.ba__range:focus-visible::-moz-range-thumb { outline: 3px solid var(--focus); outline-offset: 2px; }

/* ---- actions.css ---- */
/* The rating line, and the row of things a visitor can do besides call:
   pay an invoice, leave a review, save the contact, share the site.

   Both appear in more than one place — the rating in the hero and the
   footer, the actions in the contact section and the footer — so each is
   styled once here and adjusted where it lands. */

/* ---- The rating line ---------------------------------------------------- */

.rating {
  display: inline-flex; align-items: center; gap: 0.4rem;
  margin: 1.25rem 0 0; font-size: 0.95rem; font-weight: 600;
  /* Inherited, never stated: this line sits on a brand-coloured hero on one
     preset and on paper on the next, and the block around it has already had
     its colour checked for contrast. Naming ink here put dark text on a dark
     hero. */
  color: inherit; text-decoration: none;
}

.rating .icon {
  width: 1.1rem; height: 1.1rem;
  /* The one place the accent colour is a fill rather than a stroke: a hollow
     star reads as "not rated" at a glance. */
  fill: var(--accent); color: var(--accent);
}

a.rating:hover { text-decoration: underline; text-underline-offset: 0.2em; }

.rating--hero { margin-top: 1.5rem; }

.site-footer .rating { margin-top: 0.75rem; font-size: 0.9rem; }

/* ---- The row of actions ------------------------------------------------- */

.actions { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 1.75rem; }

/* In the footer they are links in a list, not buttons: four outlined
   rectangles at the bottom of a page is a toolbar, and nothing down there is
   urgent enough to be one. */
.footer__actions { margin-top: 0.75rem; }

/* The share control is a <button> wherever it appears, because there is
   nowhere for it to go. In the footer it has to look like the links beside
   it, which means undoing everything a button brings with it. */
.share--link {
  padding: 0; border: 0; background: none; cursor: pointer;
  font: inherit; color: inherit; text-align: left;
  /* Underlined like the links it sits among: a control that behaves like a
     link and does not look like one is a control nobody presses. */
  text-decoration: underline; text-underline-offset: 0.2em;
}

.share--link:hover { text-decoration-thickness: 2px; }

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

/* ---- pages.css ---- */
.simple { padding-block: clamp(5rem, 4rem + 6vw, 9rem); text-align: center; }

.simple h1 { font-size: var(--step-4); }

.simple p { max-width: 36rem; margin: 1rem auto 2rem; font-size: var(--step-1); color: var(--muted); }

/* A page of paragraphs — the accessibility statement — reads left-aligned. */
.simple--text { text-align: left; }
.simple--text p { margin: 1rem 0; max-width: 40rem; color: var(--ink); font-size: var(--step-0); }
.simple--text .simple__meta { color: var(--muted); }
.simple--text .btn { margin-top: 1.5rem; }

/* ---- footer.css ---- */
.site-footer {
  padding-block: 4rem 2rem; background: var(--ink); font-size: 0.95rem;
  color: color-mix(in srgb, var(--on-ink) 80%, var(--ink)); --focus: var(--accent);
}

.site-footer a { color: var(--on-ink); }

.footer__grid { display: grid; gap: 2.5rem; }

.footer__brand {
  margin-bottom: 0.5rem; color: var(--on-ink); line-height: 1.1;
  font-family: var(--font-display); font-weight: var(--display-weight); font-stretch: var(--display-stretch);
  font-size: var(--step-2);
}

.footer__h { margin-bottom: 0.75rem; font: 700 0.95rem/1.3 var(--font-body); color: var(--on-ink); }

.footer__list, .footer__social { display: grid; gap: 0.4rem; margin: 0; padding: 0; list-style: none; }

.footer__social { display: flex; flex-wrap: wrap; gap: 0.4rem 1.25rem; margin-top: 1rem; }

.footer__base {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0.5rem 1rem;
  margin-top: 3rem; padding-top: 1.5rem; font-size: 0.875rem;
  border-top: 1px solid color-mix(in srgb, var(--on-ink) 18%, transparent);
}

.footer__base p { margin: 0; }

@media (min-width: 48rem) { .footer__grid { grid-template-columns: 1.4fr 1fr 1fr; } }

/* Every link in the footer is a target of at least 24px, small type or not. */
.footer__list a, .footer__social a, .footer__base a { display: inline-block; padding-block: 0.2rem; }

/* ---- callbar.css ---- */
.callbar { display: none; }

@media (max-width: 47.99rem) {
  .has-callbar { padding-bottom: calc(4.25rem + env(safe-area-inset-bottom, 0px)); }
  .has-callbar .header-call { display: none; }
  .callbar {
    position: fixed; inset: auto 0 0 0; z-index: 30;
    display: flex; align-items: center; justify-content: center; gap: 0.6rem;
    padding: 1.1rem 1rem calc(1.1rem + env(safe-area-inset-bottom, 0px));
    background: var(--accent); color: var(--on-accent);
    font-size: 1.1rem; font-weight: 700; text-decoration: none;
    box-shadow: 0 -4px 16px -6px color-mix(in srgb, var(--ink) 40%, transparent);
  }
}

/* ---- form.css ---- */
/* The contact form's enquiry-mode chooser and the switcher panel. */

.ask { margin: 0 0 1rem; padding: 0; border: 0; }

.ask legend { padding: 0; font-size: 0.8rem; font-weight: 600; color: var(--muted); margin-bottom: 0.45rem; }

.ask__opt {
  display: inline-flex; align-items: center; gap: 0.45rem; cursor: pointer;
  padding: 0.45rem 0.8rem; margin: 0 0.4rem 0.4rem 0;
  border: 1px solid var(--line); border-radius: 999px; font-size: 0.92rem;
}

.ask__opt:has(input:checked) { border-color: var(--brand); background: var(--tint); font-weight: 600; }

.ask__opt input { accent-color: var(--brand); }

/* ---------- Theme switcher (previews only) ----------
   Deliberately not styled like the site around it: it is our tool sitting on
   the prospect's page, and should read as such rather than as a feature of
   their business's website. */

/* The claim page's second route: pay, or just say yes. Given the same visual
   weight as the plans, because for a lot of owners it is the only one they
   will use. */

/* The "+" between two prices that add up. Hidden from screen readers — the
   words already say "then", and a lone plus read aloud is noise. */

.tiers__join {
  display: grid; place-items: center; padding: 0;
  font-size: var(--step-3); font-weight: 700; color: var(--muted);
}

@media (max-width: 47.99rem) {
  .tiers__join { padding: 0.25rem 0; }
}

.plan__plus {
  display: block; margin-top: 0.35rem; font-size: var(--step-1);
  font-weight: 400; color: var(--muted);
}

.plan__badge {
  display: inline-block; margin-bottom: 0.5rem; padding: 0.2rem 0.6rem;
  font-size: 0.78rem; font-weight: 600; letter-spacing: 0.01em;
  color: var(--on-accent); background: var(--accent); border-radius: 999px;
}

.plan--featured { border-color: var(--accent); }

.claim__alt {
  margin-top: 2.5rem; padding: 1.75rem; text-align: center;
  background: var(--tint); border: var(--rule); border-radius: var(--radius-lg);
}

.claim__alt h2 { font-size: var(--step-2); margin-bottom: 0.5rem; }

.claim__alt p { max-width: 34rem; margin: 0 auto; color: var(--muted); }

.claim__alt-actions {
  display: flex; flex-wrap: wrap; gap: 0.75rem; justify-content: center; margin-top: 1.25rem;
}

.claim__alt-actions .btn { margin: 0; }

.themer { position: fixed; right: 1rem; bottom: 1rem; z-index: 40; font-size: 0.875rem; }

.themer__toggle {
  display: block; margin-left: auto; padding: 0.55rem 0.9rem; cursor: pointer;
  background: #1b1f23; color: #fff; border: 1px solid #333a41; border-radius: 999px;
  font: inherit; font-weight: 600; box-shadow: 0 6px 20px -8px rgb(0 0 0 / 0.5);
}

.themer__toggle:hover { background: #262b31; }

.themer__panel {
  margin-top: 0.6rem; width: min(20rem, calc(100vw - 2rem)); padding: 1rem;
  box-sizing: border-box;
  /* Five controls plus the code box is a tall panel, and a laptop in a hotel
     room is a short screen. Scroll inside rather than off the bottom. */
  max-height: min(34rem, calc(100vh - 5rem)); overflow-y: auto; overscroll-behavior: contain;
  background: #1b1f23; color: #e8edf1; border: 1px solid #333a41; border-radius: 12px;
  box-shadow: 0 16px 40px -12px rgb(0 0 0 / 0.6);
}

.themer__note { margin: 0 0 0.7rem; font-size: 0.78rem; color: #9fb0bd; line-height: 1.4; }

.themer__row { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.55rem; }

.themer__row > span { flex: 0 0 3.6rem; font-size: 0.78rem; color: #9fb0bd; }

.themer__preset {
  /* min-width:0 is what keeps a select inside a flex row: without it the
     intrinsic width of the longest option pushes it out of the panel. */
  flex: 1 1 auto; min-width: 0; max-width: 100%;
  padding: 0.4rem 0.5rem; font: inherit; font-size: 0.85rem; border-radius: 7px;
  background: #111518; color: #e8edf1; border: 1px solid #333a41;
}

.themer__knob {
  flex: 1 1 auto; min-width: 0; max-width: 100%;
  padding: 0.35rem 0.45rem; font: inherit; font-size: 0.82rem;
  background: #0f1317; color: #e8edf1; border: 1px solid #454d55; border-radius: 7px;
}

.themer__sws { display: flex; flex-wrap: wrap; gap: 0.35rem; }

.themer__sw {
  width: 1.6rem; height: 1.6rem; padding: 0; cursor: pointer;
  border: 1px solid #454d55; border-radius: 6px;
}

.themer__sw:hover { outline: 2px solid #7ab6f0; outline-offset: 1px; }

/* The code they send back. Monospaced and letter-spaced because it gets read
   off a screen and typed into a text message, and readonly because a code they
   have edited describes nothing. */

.themer__code {
  position: relative; margin: 0.75rem 0 0.7rem; padding-top: 0.7rem;
  border-top: 1px solid #333a41;
}

.themer__row--code { margin-bottom: 0.5rem; }

.themer__codebox {
  flex: 1 1 auto; min-width: 0; width: 100%; padding: 0.4rem 0.5rem;
  font: 600 0.95rem/1.2 ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: 0.16em; text-align: center; text-transform: uppercase;
  background: #0f1317; color: #f4d58d; border: 1px solid #454d55; border-radius: 7px;
}

.themer__codebox:focus { outline: 2px solid #7ab6f0; outline-offset: 1px; }

.themer__copy {
  width: 100%; padding: 0.4rem; cursor: pointer; font: inherit; font-size: 0.8rem; font-weight: 600;
  background: #2b333a; color: #e8edf1;
  border: 1px solid #454d55; border-radius: 7px;
}

.themer__copy:hover { border-color: #7ab6f0; }

.themer__help { margin: 0.55rem 0 0; font-size: 0.74rem; line-height: 1.45; color: #9fb0bd; }

.themer__reset {
  width: 100%; padding: 0.4rem; cursor: pointer; font: inherit; font-size: 0.8rem;
  background: none; color: #9fb0bd; border: 1px dashed #454d55; border-radius: 7px;
}

.themer__reset:hover { color: #e8edf1; border-color: #7ab6f0; }

@media (max-width: 47.99rem) {
  .has-callbar .themer { bottom: calc(4.75rem + env(safe-area-inset-bottom, 0px)); }
}

/* ---- portfolio.css ---- */
.works {
  display: grid; gap: 1.25rem; margin: 0; padding: 0; list-style: none;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 18rem), 1fr));
}

.work {
  /* The card is the list item, so an entry without a link still looks like one. */
  display: flex; flex-direction: column; overflow: hidden;
  border: var(--rule); border-radius: var(--radius-lg); background: var(--paper);
  transition: border-color .15s ease, transform .15s ease;
}

.work:has(.work__link):hover { border-color: var(--brand); transform: translateY(-2px); }

.work:has(.work__link:hover) .work__cta { text-decoration-color: currentColor; }

.work__link { display: flex; flex-direction: column; flex: 1; min-width: 0; text-decoration: none; color: inherit; }

/* The picture is the top of the site's own home page, cropped like a browser
   window: whatever is above the fold is what the card shows. */

.work__shot {
  display: block; aspect-ratio: 16 / 10; overflow: hidden;
  border-bottom: var(--rule); background: var(--tint);
}

.work__shot img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top; }

.work__shot--mark { display: grid; place-items: center; border-bottom: 0; }

.work__mark {
  font-size: 3rem; font-weight: 700; color: #fff;
  text-shadow: 0 1px 2px rgb(0 0 0 / 0.35);
}

.work__body { display: flex; flex-direction: column; gap: 0.35rem; flex: 1; min-width: 0; padding: 1rem 1.25rem 1.25rem; }

.work__meta { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; margin-bottom: 0.2rem; }

.work__tag {
  font-size: 0.75rem; font-weight: 700; letter-spacing: 0.02em; padding: 0.2rem 0.6rem; border-radius: 999px;
  background: color-mix(in srgb, var(--brand) 12%, var(--paper)); color: var(--brand);
}

.work__year { font-size: 0.8rem; color: var(--muted); font-variant-numeric: tabular-nums; }

.work__name { font-weight: 650; font-size: var(--step-1); line-height: 1.25; }

.work__detail { font-size: 0.87rem; color: var(--muted); }

.work__text { font-size: 0.95rem; line-height: 1.5; margin-top: 0.15rem; }

.work__cta {
  margin-top: auto; padding-top: 0.85rem; font-weight: 600; color: var(--brand);
  text-decoration: underline; text-decoration-color: transparent; text-underline-offset: 0.2em;
  transition: text-decoration-color .15s ease;
}

/* The same cards as a swipeable row (`layout: "carousel"` on the section).
   The row itself — whole cards, controls above beside the heading — is
   `.cards-carousel` in sections.css, shared with reviews. In a slide the
   screenshot fills the card's top edge to edge. */

.cards-carousel .carousel__slide .work__shot img { aspect-ratio: auto; border-radius: 0; }

/* ---- steps.css ---- */
.steps {
  display: grid; gap: 1.5rem; margin: 0; padding: 0; list-style: none;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  counter-reset: step;
}

.step { display: flex; gap: 1rem; align-items: flex-start; }

.step__n {
  flex: 0 0 auto; width: 2.25rem; height: 2.25rem; border-radius: 999px;
  display: grid; place-items: center; font-weight: 700;
  background: var(--brand); color: var(--on-brand);
}

.step__title { margin: 0 0 0.25rem; font-size: 1.05rem; }

.step p { margin: 0; color: var(--muted); }

/* ---- pricing.css ---- */
.tiers {
  display: grid; gap: 1.25rem; margin: 0; padding: 0; list-style: none;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
}

/* The joiner must not claim a column of its own: auto-fit would give the "+"
   the same width as a price card and push the two apart across the page. */

.tiers--joined { grid-template-columns: minmax(16rem, 1fr) auto minmax(16rem, 1fr); }

@media (max-width: 47.99rem) {
  .tiers--joined { grid-template-columns: 1fr; }
}

.tier {
  position: relative; display: flex; flex-direction: column; gap: 0.6rem;
  padding: 1.75rem; border: var(--rule); border-radius: var(--radius-lg); background: var(--paper);
}

.tier--featured { border-color: var(--brand); border-width: 2px; }

.tier__flag {
  position: absolute; top: -0.7rem; left: 1.5rem;
  background: var(--brand); color: var(--on-brand);
  font-size: 0.72rem; font-weight: 700; padding: 0.15rem 0.6rem; border-radius: 999px;
}

.tier__name { margin: 0; font-size: 1rem; }

.tier__price { margin: 0; font-size: 2.1rem; font-weight: 700; line-height: 1.1; }

.tier__per { font-size: 0.95rem; font-weight: 500; color: var(--muted); }

.tier__note { margin: 0; font-size: 0.9rem; color: var(--muted); }

.tier__list { list-style: none; margin: 0.4rem 0 0; padding: 0; display: grid; gap: 0.4rem; font-size: 0.92rem; }

.tier__list li { display: flex; gap: 0.5rem; align-items: flex-start; }

.tier__list .icon { flex: 0 0 auto; width: 1.1em; height: 1.1em; margin-top: 0.2em; color: var(--brand); }

.tier .btn { margin-top: auto; align-self: stretch; justify-content: center; }

/* ---- menu.css ---- */
/* The menu section: categories side by side where there is room, each dish on
   a dotted leader with its price, dietary tags as small abbreviations. */
.menu { display: grid; gap: 2.5rem 4rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); }
.menu__cat { margin: 0 0 0.25rem; font-size: var(--step-2); }
.menu__catnote { margin: 0 0 0.75rem; color: var(--muted); font-size: 0.95rem; }
.menu__items { margin: 0; padding: 0; list-style: none; }
.menu__item {
  display: grid; grid-template-columns: 1fr auto; gap: 0 1rem; padding: 0.6rem 0;
  border-bottom: 1px dotted color-mix(in srgb, var(--ink) 35%, transparent);
}
.menu__name { font-weight: 600; }
.menu__tags { margin-left: 0.4rem; font-size: 0.72rem; font-weight: 600; letter-spacing: 0.04em; color: var(--muted); }
.menu__tags abbr { text-decoration: none; }
.menu__price { font-family: var(--font-display); font-weight: var(--display-weight); white-space: nowrap; }
.menu__text { grid-column: 1 / -1; margin-top: 0.15rem; color: var(--muted); font-size: 0.95rem; }
.menu__legend { margin-top: 1.25rem; color: var(--muted); font-size: 0.85rem; }
.menu__pdf { margin-top: 1rem; }

/* ---- claim.css ---- */
.claim__includes { margin: 0 0 3rem; max-width: 44rem; }

.claim__gaps {
  max-width: 44rem; margin: 0 0 2.5rem; padding: 1.5rem;
  border-left: 3px solid var(--accent); background: var(--tint); border-radius: var(--radius);
}

.claim__gaps h2 { margin: 0 0 0.75rem; font-size: 1.05rem; }

.claim__gaps ul { margin: 0; padding-left: 1.1rem; display: grid; gap: 0.4rem; }

.claim__gaps-note { margin: 0.9rem 0 0; font-size: 0.85rem; color: var(--muted); }

.plans {
  display: grid; gap: 1.25rem; margin: 0 0 3rem; padding: 0; list-style: none;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}

.plan {
  display: flex; flex-direction: column; align-items: flex-start; gap: 0.5rem;
  padding: 1.75rem; border: var(--rule); border-radius: var(--radius-lg); background: var(--paper);
}

.plan__name { margin: 0; font-size: 1.05rem; }

.plan__price { margin: 0; font-size: 2.25rem; font-weight: 700; line-height: 1.1; }

.plan__per { font-size: 1rem; font-weight: 500; color: var(--muted); }

.plan__note { margin: 0; font-size: 0.9rem; color: var(--muted); }

.plan .btn { margin-top: auto; align-self: stretch; justify-content: center; }

.claim__foot { max-width: 44rem; margin: 0; }

.claim__contact { font-weight: 600; }

.claim__back { font-size: 0.9rem; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition: none !important; }
}

/* ---- presets/workshop.css ---- */
/* workshop: everything this look changes. The token block sets its typography
   and shape; the rules after it override the shared components. */

/* Trades & services: van-door lettering, fleet stripe, big phone number */
[data-preset="workshop"] {
  --font-display: "Archivo", "Arial Narrow", system-ui, sans-serif;
  --font-body: "Archivo", system-ui, sans-serif;
  --display-weight: 800;
  --display-stretch: 72%;
  --display-tracking: 0;
  --radius: 3px;
  --radius-lg: 4px;
  --rule: 3px solid var(--ink);
  --hero-size: clamp(3rem, 1.4rem + 6.4vw, 6rem);
  --hero-measure: 13ch;
  --plate-size: clamp(2.6rem, 0.9rem + 7.2vw, 4.6rem);
  --step-4: clamp(2.4rem, 1.5rem + 3.6vw, 3.6rem);
}
[data-preset="workshop"] .brand__mark { font-size: 1.9rem; }
[data-preset="workshop"] .hero {
  background: var(--ink); color: var(--on-ink);
  --focus: var(--accent); --badge-icon: var(--accent);
  padding-bottom: calc(clamp(3rem, 2rem + 5vw, 6.5rem) + 20px);
}
[data-preset="workshop"] .hero::after {
  content: ""; position: absolute; inset: auto 0 0 0; height: 20px;
  background: linear-gradient(var(--accent) 0 13px, var(--brand) 13px 20px);
}
[data-preset="workshop"] .hero__text { color: color-mix(in srgb, var(--on-ink) 82%, var(--ink)); }
[data-preset="workshop"] .plate { --plate-bg: var(--accent); --plate-fg: var(--on-accent); padding: 1.75rem 2rem 2rem; }
[data-preset="workshop"] .plate__value { font-stretch: 68%; --plate-fit: 17cqi; }
@media (min-width: 56rem) { [data-preset="workshop"] .hero__grid { align-items: end; } }
[data-preset="workshop"] .svc__title { font-size: 1.85rem; }
[data-preset="workshop"] .quote { padding: 1.5rem 0 0; background: none; border: 0; border-top: var(--rule); border-radius: 0; }

/* ---- presets/storefront.css ---- */
/* storefront: everything this look changes. The token block sets its typography
   and shape; the rules after it override the shared components. */

/* Shops, bakeries, cafés, salons: arched windows, serif sign */
[data-preset="storefront"] {
  --font-display: "Young Serif", Georgia, serif;
  --font-body: "Figtree", system-ui, sans-serif;
  --display-weight: 400;
  --display-tracking: -0.01em;
  --radius: 10px;
  --radius-lg: 20px;
  --hero-measure: 14ch;
  --plate-size: clamp(1.8rem, 1.1rem + 2.6vw, 2.6rem);
}
[data-preset="storefront"] .btn { border-radius: 999px; }
[data-preset="storefront"] .hero { background: var(--tint); }
[data-preset="storefront"] .hero__photo { border-radius: 999px 999px var(--radius-lg) var(--radius-lg); }
[data-preset="storefront"] .plate { text-align: center; }
[data-preset="storefront"] .plate__value { white-space: normal; }
[data-preset="storefront"] .hero--plain .plate {
  display: grid; align-content: center; min-height: 22rem; padding: 4rem 2rem 3rem;
  border-radius: 999px 999px var(--radius-lg) var(--radius-lg);
}
@media (min-width: 56rem) {
  [data-preset="storefront"] .hero--photo .plate {
    position: absolute; left: -2.5rem; bottom: 2.5rem; width: min(19rem, 85%);
    box-shadow: 0 18px 40px -18px color-mix(in srgb, var(--ink) 55%, transparent);
  }
}
[data-preset="storefront"] .about__photo { border-radius: 999px 999px var(--radius-lg) var(--radius-lg); aspect-ratio: 4 / 5; }

/* ---- presets/studio.css ---- */
/* studio: everything this look changes. The token block sets its typography
   and shape; the rules after it override the shared components. */

/* Professional services: quiet, editorial, lots of air */
[data-preset="studio"] {
  --font-display: "Newsreader", Georgia, serif;
  --font-body: "Public Sans", system-ui, sans-serif;
  --display-weight: 500;
  --display-tracking: -0.015em;
  --radius: 2px;
  --radius-lg: 2px;
  --hero-measure: 18ch;
  --plate-size: clamp(1.7rem, 1.1rem + 2.2vw, 2.4rem);
}
[data-preset="studio"] body { line-height: 1.65; }
[data-preset="studio"] .hero { border-bottom: 1px solid var(--line); }
[data-preset="studio"] .plate {
  --plate-bg: transparent; --plate-fg: var(--ink);
  border: 1px solid var(--line); border-left: 3px solid var(--brand);
}
[data-preset="studio"] .plate__label { color: var(--muted); font-weight: 500; }

/* ---- presets/wellness.css ---- */
/* wellness: everything this look changes. The token block sets its typography
   and shape; the rules after it override the shared components. */

/* Health, care and wellbeing: calm, rounded, unhurried */
[data-preset="wellness"] {
  --font-display: "Fraunces", Georgia, serif;
  --font-body: "Nunito Sans", system-ui, sans-serif;
  --display-weight: 600;
  --display-tracking: -0.02em;
  --radius: 14px;
  --radius-lg: 28px;
  --hero-size: clamp(2.4rem, 1.5rem + 3.8vw, 3.9rem);
  --hero-measure: 16ch;
  --plate-size: clamp(1.7rem, 1.1rem + 2.2vw, 2.4rem);
  --measure: 62ch;
}
[data-preset="wellness"] .hero { background: var(--tint); }
[data-preset="wellness"] .hero__photo { border-radius: var(--radius-lg); }
[data-preset="wellness"] .btn { border-radius: 999px; padding-inline: 1.6rem; }
[data-preset="wellness"] .plate {
  --plate-bg: var(--paper); --plate-fg: var(--ink);
  border: 1px solid color-mix(in srgb, var(--brand) 22%, transparent);
  padding: 1.75rem 2rem;
}
[data-preset="wellness"] .plate__label { color: var(--brand); }
[data-preset="wellness"] .svc { border-top: 0; padding-block: 0 2rem; }
[data-preset="wellness"] .svc__icon { width: 3.25rem; height: 3.25rem; border-radius: 999px; }
[data-preset="wellness"] .quote {
  border: 0; border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--brand) 7%, var(--paper));
}
[data-preset="wellness"] .s--tint .quote { background: var(--paper); }
[data-preset="wellness"] .checks { border-radius: var(--radius-lg); }
[data-preset="wellness"] .gallery img { border-radius: var(--radius-lg); }
[data-preset="wellness"] .faq__item summary { font-weight: 700; }

/* ---- presets/field.css ---- */
/* field: everything this look changes. The token block sets its typography
   and shape; the rules after it override the shared components. */

/* Outdoor and property work: sturdy slab, photography leads */
[data-preset="field"] {
  --font-display: "Zilla Slab", Georgia, serif;
  --font-body: "Source Sans 3", system-ui, sans-serif;
  --display-weight: 700;
  --display-tracking: -0.01em;
  --radius: 4px;
  --radius-lg: 8px;
  --rule: 2px solid var(--line);
  --hero-size: clamp(2.8rem, 1.6rem + 5vw, 4.8rem);
  --hero-measure: 14ch;
  --plate-size: clamp(2.2rem, 1.2rem + 4vw, 3.2rem);
}
[data-preset="field"] .hero { background: var(--tint); border-bottom: 4px solid var(--brand); }
[data-preset="field"] .hero__photo { aspect-ratio: 3 / 2; }
[data-preset="field"] .plate { --plate-bg: var(--brand); --plate-fg: var(--on-brand); }
[data-preset="field"] .svc {
  border-top: 0; border-left: 3px solid var(--brand);
  padding: 0.25rem 0 1.75rem 1.25rem; margin-bottom: 1.5rem;
}
[data-preset="field"] .svc__icon { background: transparent; width: auto; height: auto; margin-bottom: 0.6rem; }
[data-preset="field"] .svc__title { font-size: var(--step-1); }
[data-preset="field"] .areas li { border-bottom: 2px solid var(--line); }
[data-preset="field"] .gallery { gap: 0.5rem; }
[data-preset="field"] .quote { border-left: 3px solid var(--accent); border-radius: 0; }
@media (min-width: 56rem) {
  [data-preset="field"] .hero--photo .hero__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

/* ---- presets/table.css ---- */
/* table: everything this look changes. The token block sets its typography
   and shape; the rules after it override the shared components. */

/* Restaurants and food service: the menu is the page */
[data-preset="table"] {
  --font-display: "Playfair Display", Georgia, serif;
  --font-body: "Karla", system-ui, sans-serif;
  --display-weight: 600;
  --display-tracking: -0.015em;
  --radius: 3px;
  --radius-lg: 6px;
  --hero-size: clamp(2.7rem, 1.6rem + 4.6vw, 4.6rem);
  --hero-measure: 15ch;
  --plate-size: clamp(1.9rem, 1.2rem + 2.6vw, 2.7rem);
}
[data-preset="table"] .hero { background: var(--ink); color: var(--on-ink); --badge-icon: var(--accent); --focus: var(--accent); }
[data-preset="table"] .hero__text { color: color-mix(in srgb, var(--on-ink) 82%, var(--ink)); }
[data-preset="table"] .plate { --plate-bg: var(--accent); --plate-fg: var(--on-accent); text-align: center; }
[data-preset="table"] .svc-list { gap: 0 4rem; }
[data-preset="table"] .svc {
  display: grid; grid-template-columns: 1fr auto; gap: 0 1rem; align-items: baseline;
  padding-block: 1rem; border-top: 0;
  border-bottom: 1px dotted color-mix(in srgb, var(--ink) 35%, transparent);
}
[data-preset="table"] .svc__icon { display: none; }
[data-preset="table"] .svc__title { grid-column: 1; grid-row: 1; margin-bottom: 0; font-size: var(--step-1); }
[data-preset="table"] .svc .svc__price { grid-column: 2; grid-row: 1; margin-top: 0; font-family: var(--font-display); }
[data-preset="table"] .svc p { grid-column: 1 / -1; margin-top: 0.3rem; font-size: 0.98rem; }
[data-preset="table"] .s__head { margin-inline: auto; text-align: center; }
[data-preset="table"] .quote blockquote { font-style: italic; }

/* ---- presets/atelier.css ---- */
/* atelier: everything this look changes. The token block sets its typography
   and shape; the rules after it override the shared components. */

/* Creative and craft studios: editorial, the portfolio carries it */
[data-preset="atelier"] {
  --font-display: "Cormorant Garamond", Georgia, serif;
  --font-body: "Jost", system-ui, sans-serif;
  --display-weight: 500;
  --display-tracking: -0.02em;
  --radius: 0;
  --radius-lg: 0;
  --hero-size: clamp(3rem, 1.6rem + 6vw, 5.6rem);
  --hero-measure: 15ch;
  --plate-size: clamp(1.8rem, 1.1rem + 2.4vw, 2.5rem);
  --measure: 64ch;
}
[data-preset="atelier"] .site-header { border-bottom: 0; }
[data-preset="atelier"] .hero { padding-block: clamp(4rem, 3rem + 6vw, 8rem); }
/* Cormorant has long descenders; line-height 1 collides at hero size. */
[data-preset="atelier"] .hero__title { font-weight: 400; line-height: 1.06; }
[data-preset="atelier"] .s__head h2, [data-preset="atelier"] .simple h1 { line-height: 1.1; }
[data-preset="atelier"] .hero__photo { aspect-ratio: 1; }
[data-preset="atelier"] .plate {
  --plate-bg: transparent; --plate-fg: var(--ink);
  padding: 0; border-top: 1px solid var(--ink); padding-top: 1rem;
}
[data-preset="atelier"] .plate__label { color: var(--muted); font-weight: 400; }
[data-preset="atelier"] .btn { border-radius: 0; }
[data-preset="atelier"] .svc { border-top: 1px solid var(--ink); padding-block: 1.25rem 2rem; }
[data-preset="atelier"] .svc__icon { display: none; }
[data-preset="atelier"] .svc__title { font-size: var(--step-2); font-weight: 400; }
[data-preset="atelier"] .gallery { gap: 0.35rem; }
[data-preset="atelier"] .gallery img { aspect-ratio: 1; border-radius: 0; }
[data-preset="atelier"] .quote { border: 0; background: none; padding: 0; }
[data-preset="atelier"] .quote blockquote { font-family: var(--font-display); font-size: 1.5rem; line-height: 1.35; }
[data-preset="atelier"] .s__head h2 { font-weight: 400; }

/* ---- presets/lounge.css ---- */
/* lounge: everything this look changes. The token block sets its typography
   and shape; the rules after it override the shared components. */

/* Bars, lounges, nightlife: dark paper (from the noir palette), a serif with
   some drama, generous spacing, nothing rounded. The photographs carry it. */
[data-preset="lounge"] {
  --font-display: "DM Serif Display", Georgia, serif;
  --font-body: "DM Sans", system-ui, sans-serif;
  --display-weight: 400;
  --display-tracking: 0;
  --radius: 0;
  --radius-lg: 0;
  --hero-size: clamp(2.8rem, 1.5rem + 5.5vw, 5.2rem);
  --hero-measure: 14ch;
  --plate-size: clamp(2rem, 1.1rem + 3vw, 3rem);
  --measure: 62ch;
  --space-section: clamp(4.5rem, 3.5rem + 5vw, 8rem);
}
/* lounge: the whole page is dark, so the chrome steps back and the metal
   accent does the pointing */
[data-preset="lounge"] .site-header { border-bottom: 1px solid var(--line); }
[data-preset="lounge"] .hero { padding-block: clamp(4rem, 3rem + 7vw, 9rem); }
[data-preset="lounge"] .hero__title { line-height: 1.02; }
[data-preset="lounge"] .hero__photo { aspect-ratio: 4 / 5; filter: saturate(0.85); }
[data-preset="lounge"] .hero__badges { color: var(--brand); text-transform: none; letter-spacing: 0.02em; }
[data-preset="lounge"] .plate {
  --plate-bg: transparent; --plate-fg: var(--ink);
  padding: 1.25rem 0 0; border-top: 1px solid var(--brand);
}
[data-preset="lounge"] .plate__label { color: var(--brand); font-weight: 500; }
[data-preset="lounge"] .btn { border-radius: 0; letter-spacing: 0.04em; }
[data-preset="lounge"] .btn--ghost { border-color: var(--brand); color: var(--ink); }
[data-preset="lounge"] .s--tint { background: color-mix(in srgb, var(--brand) 5%, var(--paper)); }
[data-preset="lounge"] .svc { border-top: 1px solid var(--line); padding-block: 1.25rem 2rem; }
[data-preset="lounge"] .svc__icon { background: transparent; color: var(--brand); border: 1px solid var(--line); }
[data-preset="lounge"] .svc__title { font-size: var(--step-2); font-weight: 400; }
[data-preset="lounge"] .gallery img, [data-preset="lounge"] .carousel__slide img { border-radius: 0; filter: saturate(0.85); }
[data-preset="lounge"] .quote { background: transparent; border: 1px solid var(--line); }
[data-preset="lounge"] .quote blockquote { font-family: var(--font-display); font-size: 1.4rem; line-height: 1.35; }
/* the footer is normally an ink band; on dark paper that would be a cream
   slab at the bottom of a dark room, so it stays in the room */
[data-preset="lounge"] .site-footer {
  background: color-mix(in srgb, var(--brand) 6%, var(--paper));
  color: color-mix(in srgb, var(--ink) 80%, var(--paper)); border-top: 1px solid var(--brand);
}
[data-preset="lounge"] .site-footer a { color: var(--ink); }
/* The footer headings keep the shared on-ink, which on dark paper is black on black. */
[data-preset="lounge"] .footer__brand, [data-preset="lounge"] .footer__h { color: var(--ink); }

/* ---- presets/dispatch.css ---- */
/* dispatch: everything this look changes. The token block sets its typography
   and shape; the rules after it override the shared components. */

/* Emergency and 24-hour services: condensed heavy type, a high-visibility
   plate, everything sized for a thumb on a phone at a roadside. */
[data-preset="dispatch"] {
  --font-display: "Barlow Condensed", "Arial Narrow", system-ui, sans-serif;
  --font-body: "Barlow", system-ui, sans-serif;
  --display-weight: 800;
  --display-stretch: 100%;
  --display-tracking: -0.005em;
  --radius: 4px;
  --radius-lg: 8px;
  --hero-size: clamp(2.8rem, 1.4rem + 6vw, 5.4rem);
  --hero-measure: 14ch;
  --plate-size: clamp(2.6rem, 1.2rem + 6vw, 4.2rem);
  --measure: 62ch;
}
/* dispatch: brand-coloured hero, an accent plate that is the biggest thing on
   the page, and badges that read as promises rather than decoration */
[data-preset="dispatch"] .hero { background: var(--brand); color: var(--on-brand); }
[data-preset="dispatch"] .hero .s__intro, [data-preset="dispatch"] .hero__text { color: var(--on-brand); }
[data-preset="dispatch"] .hero__title { text-transform: uppercase; letter-spacing: 0.01em; }
[data-preset="dispatch"] .hero__badges { font-size: 1.05rem; --badge-icon: var(--accent); }
[data-preset="dispatch"] .hero .btn--ghost { border-color: var(--on-brand); color: var(--on-brand); }
[data-preset="dispatch"] .plate {
  --plate-bg: var(--accent); --plate-fg: var(--on-accent);
  padding: 1.75rem 2rem; box-shadow: 0 12px 30px -14px rgb(0 0 0 / 0.5);
}
[data-preset="dispatch"] .plate__label { text-transform: uppercase; letter-spacing: 0.06em; font-size: 0.85rem; }
[data-preset="dispatch"] .svc__icon { background: var(--brand); color: var(--on-brand); }
[data-preset="dispatch"] .svc__title { text-transform: uppercase; letter-spacing: 0.02em; }
[data-preset="dispatch"] .callbar { background: var(--accent); color: var(--on-accent); }
[data-preset="dispatch"] .s__head h2 { text-transform: uppercase; letter-spacing: 0.02em; }
