/* ==========================================================================
   Moonstone Dental Centre — base, layout and shared components
   ========================================================================== */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Belt and braces: body's overflow-x only propagates while html is visible,
     which still let intentional bleeds inflate scrollWidth. */
  overflow-x: clip;
}

/* AP-023 / AP-024 — REPRODUCTION of the original, not a redesign.
   The original's <body> rule (site.css:2141) is:
       color:#333; font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
       font-size:14px; line-height:20px
   and 42 of the 52 captured pages carry NO class on <body>, so their inherited
   text renders in that Arial stack. Only 10 pages carry a typeface class — /,
   /about-us (.body), /services (.body-3), /blogs (.body-4),
   /book-an-appointment (.body-6) and the 5 bio/reception pages (.body-8) — each
   of which sets `font-family: sweet sans pro, Arial, sans-serif`.
   The rebuild previously used Sweet Sans Pro on all 52. Measured at 1440, nav
   "Home" is 82.7px on the 42 Arial pages and 86.5px on the 10 Sweet Sans pages;
   the rebuild was 86.5 everywhere. This is not cosmetic: Sweet Sans wraps
   "Emergency Pediatric Dentistry" to two lines at 1920 where Arial fits one, so
   it changes line breaking and document height. Reproduced, not fixed, per
   AP-023; the inconsistency is flagged to the practice as a post-launch item. */
body {
  margin: 0;
  font-family: var(--font-body-default);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: var(--fw-regular);
  color: var(--color-body);
  background-color: var(--white);
  overflow-x: hidden;
}
/* The original's per-page body classes, reproduced under their original names
   so the mapping back to site.css stays greppable (2802 / 3069 / 3248 / 3425 /
   4073). Set in Base.astro via the `bodyClass` prop; every other page leaves
   <body> bare exactly as the original does. */
body.body,
body.body-3,
body.body-4,
body.body-6,
body.body-8 {
  font-family: var(--font-sans);
}
/* `.body` — and only `.body`, i.e. / and /about-us — also carries
   `background-color: #f8f9fa` (site.css:2801, the ONLY occurrence of that colour
   in the original's 212KB stylesheet). Found while reproducing the body scoping
   above, and it is not a small thing: screenshotting the captured original and
   counting exact pixel matches, #f8f9fa covers 47.24% of the homepage at 1440
   (7,938,304 of 16,803,360 px) and 43.40% of /about-us (3,901,832 of 8,991,360),
   and 41.23% / 32.34% respectively at 390. The rebuild painted ZERO pixels of it
   — those regions were #ffffff. Reproduced, not "improved". */
body.body {
  background-color: #f8f9fa;
}

img,
picture,
video,
svg { max-width: 100%; display: block; }

/* `vertical-align: middle` ADDED 2026-09-10, Round G ticket 7. It is verbatim
   from Webflow's own normalize (`img { max-width: 100%; vertical-align: middle;
   display: inline-block }`), which the original loads on all 52 pages, and the
   rebuild had it nowhere.

   It only matters where an inline-block image is the content of a block, and
   there it matters exactly: `.values-right-side` on the homepage measured
   672.672 against the original's 668.688 — the 3.984px descender of the 20px
   strut below an inline-block sitting on the BASELINE. With `middle` there is no
   strut contribution and the container is the image height, which is what the
   original measures.

   Measured before adding, across all 52 pages at 1440: docH moves on ZERO pages.
   `display` is deliberately NOT changed to Webflow's `inline-block`: the ORIGINAL
   is not uniformly inline-block either — 412 of its images compute `block` and
   186 `inline-block`, against the rebuild's 545 / 53 — so flipping the global
   would not converge on it, and that flip is also docH-neutral on all 52 pages,
   i.e. it would buy a computed-style string and nothing visible. Recorded rather
   than done. */
img { height: auto; vertical-align: middle; }

a { color: var(--color-accent); text-decoration: none; }
a:hover { text-decoration: underline; }

button,
input,
select,
textarea { font: inherit; color: inherit; }

ul, ol { margin: 0 0 var(--space-4); padding-left: 1.25rem; }

/* Visible focus for keyboard users only */
:focus-visible {
  outline: 3px solid var(--earls-green);
  outline-offset: 2px;
  border-radius: 4px;
}

.visually-hidden {
  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: -9999px;
  top: 0;
  z-index: 200;
  background: var(--earls-green);
  color: var(--white);
  padding: var(--space-3) var(--space-5);
  border-radius: 0 0 var(--radius-button) 0;
}
.skip-link:focus { left: 0; }

/* --------------------------------------------------------------------------
   Typography
   -------------------------------------------------------------------------- */
/* AP-034 (decided 2026-09-10) — margin-bottom 0, not 1rem.
   The original declares `margin-top: 0; margin-bottom: 0` EXPLICITLY on all
   seven of h1 h2 h3 h4 h5 h6 and p, at site.css:2147-2208, with no breakpoint
   override anywhere in its 212KB. That is a deliberate global value, not an
   omission, so it is reproduced rather than corrected. The rebuild shipped
   1rem on all seven, which cost exactly 16.000px of height per heading and per
   non-final paragraph on all 52 pages. */
h1, h2, h3, h4, h5, h6 {
  margin: 0;
  font-weight: var(--fw-bold);
  line-height: var(--lh-heading);
  color: var(--color-heading);
}

/* font-family is declared PER TAG, not on the group, because the original does
   exactly that and h4 is the exception: site.css declares
   `font-family: sweet sans pro, Arial, sans-serif` on h1 (2152), h2 (2162),
   h3 (2172), h5 (2188), h6 (2197) and p (2205) — and NOT on h4 (2178), which
   inherits. Before AP-023 the rebuild's headings inherited Sweet Sans Pro from
   <body> and so needed no declaration; now that <body> is Arial on 42 pages,
   omitting these would have turned every heading on those pages Arial too,
   which the original does not do. */
h1 { font-size: var(--fs-h1); color: var(--color-heading-alt); font-family: var(--font-sans); }
h2 { font-size: var(--fs-h2); font-family: var(--font-sans); }
/* CORRECTED 2026-09-10, Round G ticket 4. This was `color: var(--color-heading-alt)`
   — green. The original's global rule is
     `h3 { color: var(--black); margin: 0; font-family: sweet sans pro, Arial,
           sans-serif; font-size: 2.5rem; font-weight: 700; line-height: 120% }`
   with NO colour override at any breakpoint. h1 IS `var(--earls-green)` on the
   original, which is presumably where the green came from; h3 is not.

   Blast radius measured before changing, both directions, across all 52 pages:
   157 h3 elements in the rebuild, 152 pairable by text on the original. Exactly
   TEN computed green against the original's rgb(0, 0, 0) and are now fixed —
   3 testimonial names on `/`, `Dr. Ban Abdul Rahman` on /about-us, 5 on
   /emergency-dental, and `h3.heading-44` on /same-day-booking. FOUR more change
   (the `.faq__heading`s on `/`) and they are not regressions: the original's FAQ
   question is `p.faq-ques-1` at 24px/40px/700 rgb(51, 51, 51), so green was
   wrong there too, and Round G ticket 5 sets it explicitly. NOTHING that
   currently matches the original changes. */
h3 { font-size: var(--fs-h3); color: var(--black); font-family: var(--font-sans); }
/* h4 deliberately has NO font-family — see above. */
h4 { font-size: var(--fs-h4); }
h5 { font-size: var(--fs-h5); font-family: var(--font-sans); }
/* CORRECTED 2026-09-09: weight 700, not regular. The original's global rule is
   `h6 { font-weight: 700; line-height: 120% }` and its h6 elements COMPUTE 700 —
   measured on the reference, .university-name 19.2px/700 on /about-us and
   .technology-dental-title 25.6px/700 on /emergency-dental, against the
   rebuild's 400 in both. The boxes are full-width so no width delta showed; the
   text was simply lighter than the original's on every h6 on the site.
   NOTE: the original's h6 font-SIZE default is 1.8rem against the rebuild's
   1.1rem. Not changed here — --fs-h6 is also used as a token by .faq__question
   and .btn-phone__text, so moving it would alter unrelated components. Every h6
   in the rebuild declares its own size, so nothing currently depends on the
   default. Recorded in VISUAL_QA.md. */
h6 { font-size: var(--fs-h6); font-weight: var(--fw-bold); font-family: var(--font-sans); }

/* AP-025 — the original's global rule is a FIXED
   `p { font-family: sweet sans pro, Arial, sans-serif; font-size: 1rem;
        line-height: 140% }` (site.css:2203), i.e. 16px / 22.4px at EVERY width,
   with no breakpoint override. The rebuild inherited --fs-body instead, which
   made body copy 18px / 27px above 767px — 12.5% larger than the original on
   every page. font-family is declared here for the same reason as the headings
   above: after AP-023 the inherited family is Arial on 42 pages, but the
   original's paragraphs are Sweet Sans Pro on all 52.
   AP-034 (decided 2026-09-10): margin is now 0, matching site.css:2203-2208's
   explicit `margin-bottom: 0`. The `p:last-child { margin-bottom: 0 }` override
   that used to sit below this rule existed only to undo the 1rem and has been
   deleted with it. */
p {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 140%;
}

strong { font-weight: var(--fw-bold); }

/* Green highlight span used throughout the original */
.accent { color: var(--earls-green); }
.accent-lime { color: var(--limeade); }
.text-black { color: var(--black); }
.text-white { color: var(--white); }

/* --------------------------------------------------------------------------
   Layout
   -------------------------------------------------------------------------- */
/* No horizontal padding — the original's .main-container has none either.
   Measured, the rebuild sat exactly 16px further inset than the original at
   BOTH ends of the sweep: content began at x=48 against 32 at 1440, and at
   x=32 against 16 at 390. One 16px too many, at every width, on every page.
   The remaining inset comes from the section wrappers, as it does on the
   original. */
.container {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
}

.section {
  padding-block: var(--section-padding-y);
  padding-inline: var(--section-padding-x);
}

.section--tint-green { background-color: var(--tint-green); }
.section--tint-blue { background-color: var(--tint-blue); }
.section--green { background-color: var(--earls-green); color: var(--white); }
.section--green h2,
.section--green h3,
.section--green h4 { color: var(--white); }

.section-heading {
  text-align: center;
  margin-bottom: var(--space-7);
}

/* AP-041, decided: DO ALL FOUR PROPERLY IN ONE PASS, WITH THEIR CONTAINERS.
   -------------------------------------------------------------------------- */
/* `.eyebrow` is DELETED. One filled `#e6ebd4` pill at 16px/22.4px/700 with
   `padding: 12px 24px` and a 24px bottom margin was standing in for FOUR
   different original components across six pages, TWO of them bordered rather
   than filled, plus two rebuild-only instances:

     original                       where                            rebuild's .eyebrow
     .section-top-title-wrapper._2  / hero        426.938 x 40 @(32,192)      428.781 x 40 @(32,192)
     .section-top-title-wrapper     / doctor      210.031 x 47.188 @(747.531,5263.453)  174.938 x 46.406 @(752,5337.906)
     .section-badge  (BORDERED)     / values      85 x 40 @(70,7202.109)      116.984 x 46.406 @(32,7351.813)
     .form-heading-logo (BORDERED)  / , /about-us, /same-day-booking
                                                  140 x 45 @(649.984,…)       130.813 x 46.406 @(654.578,…)
     .service-supporting-text       18 service pages  66.891 x 23.406 @(32,771.641)  66.906 x 23.406
     (nothing at all)               /emergency-dental doctor block — REMOVED

   Every one of the original's own classes is transcribed below or, for the
   .service-supporting-text case, in service.css. `--tint-eyebrow` (#e6ebd4) is
   kept as a token because `.meet-the-doctor-left` genuinely uses that colour. */

/* FILLED pill. The fill is `#b2c23333` — rgba(178, 194, 51, 0.2), a translucent
   lime over whatever is behind it — NOT the opaque #e6ebd4 the rebuild painted.
   `._1` and `._2` are the original's two variants and `._1` is white at 20%. */
.section-top-title-wrapper {
  display: flex;
  gap: 1rem;
  justify-content: flex-start;
  align-items: center;
  padding: 10px 20px;
  border-radius: 10rem;
  background-color: rgba(178, 194, 51, 0.2);
}
.section-top-title-wrapper._1 { background-color: rgba(255, 255, 255, 0.2); }
.section-top-title-wrapper._2 { background-color: rgba(178, 194, 51, 0.2); }
/* 16px/700 at the INHERITED line-height — 20px, not the 22.4px `.eyebrow` had,
   which is the whole of the 46.406-against-45 height difference. */
.section-top-title { color: var(--white); font-size: 1rem; font-weight: 700; }
.section-top-title._2 { color: var(--earls-green); }
@media screen and (max-width: 479px) { .section-top-title._2 { text-align: center; } }
/* The medal that belongs INSIDE the doctor pill. The rebuild had it as a
   separate `img.doctor__badge` sitting above the pill. */
.sparkles-icon { width: 100%; max-width: 2rem; height: auto; }
.sparkles-icon._1 { max-width: 1.7rem; }

/* BORDERED pill 1 — the VALUES / FAQ badge. `.section-badge` and `.badge-text`
   are declared with the FAQ block further down (Round G ticket 5) because that
   is where they were first needed; they are shared by both. */

/* BORDERED pill 2 — the CONTACT badge above the form on three pages. Fixed
   140 x 45, `align-self: center`, `flex: 0 auto` so it does not stretch. Its
   `color: var(--white)` is inherited by nothing visible: the inner
   `strong.bold-text-7` sets `var(--black)`. Transcribed as declared. */
.form-heading-logo {
  display: flex;
  flex: 0 auto;
  flex-flow: row;
  width: 140px;
  height: 45px;
  justify-content: center;
  align-self: center;
  align-items: center;
  text-align: center;
  color: var(--white);
  border: 2px solid var(--earls-green);
  border-radius: 30px;
}
/* `align-items: flex-end` is the original's, and it is what puts the cap-height
   of an 18px line where it sits inside the 45px pill. */
.text-block-14 {
  display: flex;
  justify-content: center;
  align-items: flex-end;
  /* --font-sans-bold, not --font-sans, AP-058 2026-09-11. site.css:3759 is
     `font-family: sweet sans bold` at 700 — the original's separate one-face
     family. --font-sans now has no 700, so leaving it here would have
     synthesised a bold over the Medium instead of using the real Bold face.
     8 elements, on /about-us, the four bios, /reception, /same-day-booking
     and `/`. */
  font-family: var(--font-sans-bold);
  font-size: 18px;
  font-weight: 700;
}
.bold-text-7 { color: var(--black); }

/* --------------------------------------------------------------------------
   .section-padding / .main-container — the original's two layout primitives
   --------------------------------------------------------------------------
   MOVED HERE from service.css 2026-09-09. They are used by /emergency-dental
   (AP-013) and /about-us (AP-014), and /about-us does not load service.css.
   Fourth instance of the same mistake on this project — breadcrumb,
   .service-cta, .for-mobile-view-item and now these. Anything shared across
   templates belongs in main.css.

   .section-padding is what places the container: 2rem of side padding is why
   .main-container measures 1376 at x=32 at 1440, 960 at x=32 at 1024 and 358 at
   x=16 at 390 on the reference, rather than its 1380 cap.
   -------------------------------------------------------------------------- */
.section-padding {
  display: flex;
  flex-flow: column;
  justify-content: center;
  align-items: center;
  padding: 5rem 2rem;
}
.main-container { width: 100%; max-width: 1380px; margin-inline: auto; }

/* Webflow's own clearfix on .w-container (site.css:699-707), which every
   .main-container on the original also carries:

     .w-container:before, .w-container:after { content: " "; display: table;
                                               grid-area: 1 / 1 / 2 / 2 }
     .w-container:after { clear: both }

   It is not decoration. `display: table` pseudo-elements at both edges STOP THE
   CHILD'S BLOCK MARGINS COLLAPSING OUT of the container, and .our-story-wrapper
   on /about-us has `margin: 60px 40px`. Without them those 120px escaped the
   container and the section, so `section.our-story` — which is the original's one
   white block on that page — measured 1440 x 473.328 against 1440 x 593.328 at
   1440: 120.0px of the white band missing, with every child still correctly
   placed. At 390 the original zeroes that margin (`.our-story-wrapper { margin:
   0 }` at <=479) and both sides already measured 727.328, which is why this only
   ever showed above 479. */
.main-container::before,
.main-container::after { content: " "; display: table; grid-area: 1 / 1 / 2 / 2; }
.main-container::after { clear: both; }
@media screen and (max-width: 991px) { .section-padding { padding: 4rem 1rem; } }
@media screen and (max-width: 767px) { .section-padding { padding-block: 3.5rem; } }
@media screen and (max-width: 479px) { .section-padding { padding-block: 3rem; } }

/* MOVED here from service.css 2026-09-10. Global on the original, and used by
   /about-us, which never loads service.css. Unchanged otherwise. */
.section-top-holder {
  z-index: 9;
  position: relative;
  display: flex;
  flex-flow: column;
  justify-content: center;
  align-items: center;
  gap: 1.5rem;
}
.section-top-holder h2 { margin: 0; }

/* site.css `.wrapper` — the column that separates a `.section-top-holder` from
   the block beneath it. 4rem at 1440, 3rem at <=991, 2rem at <=479. The
   `.appoinment-section .wrapper` rule in home.css is more specific and still
   wins on /same-day-booking, so that page is unaffected by adding this. */
.wrapper { display: flex; flex-flow: column; gap: 4rem; }
@media screen and (max-width: 991px) { .wrapper { gap: 3rem; } }
@media screen and (max-width: 479px) { .wrapper { gap: 2rem; } }

/* site.css: the green run inside a heading, e.g. "What We <span>Stand For</span>". */
.coloring-texts { color: var(--earls-green); }

/* site.css `.hide { display: none }`. ADDED Round F ticket 7 for the two
   zero-size sections that close /services on the original. Nothing else in the
   rebuild carries `class="hide"` — grepped before adding. */
.hide { display: none; }

/* ==========================================================================
   The photographic banner on /thank-you and /book-an-appointment
   ==========================================================================
   ADDED Round F, ticket 9, and IT CORRECTS AP-044's PREMISE. AP-044 says
   /thank-you's original "is a single heading plus the footer". It is not: both
   pages open with `.main-container-copy-copy-cu > .hero-wrapper-cu >
   .hero-text-copy-cu`, a 220-tall photographic band with a 30px radius, and the
   rebuild had neither page render anything above its own first section.

   Measured on the reference at 1440:
     .main-container-copy-copy-cu  1380 x 357 at (30, 0)
     .hero-wrapper-cu             1340 x 357 at (50, 0)   margin-x 20,
                                                          padding-bottom 20
     .hero-text-copy-cu           1340 x 220 at (50, 117) margin-top 117
     .heading-copy-cu             0 x 0, absolutely positioned and EMPTY
   357 = 117 + 220 + 20. At 1024 the same chain is 1024 / 984 x 357 at x=20.
   `.hero-text-copy-cu` is 220 tall only above 991; it is 120 at <=991 and
   <=767 and 100 at <=479, and the wrapper's margin-top steps 117 -> 120 -> 100
   -> 0 with a 100px margin back on the banner itself at <=479.

   `img-0072-edited.png` (5760 x 932, 2,738,005 bytes,
   `68349f9390a3b599378c0dc7_IMG_0072 Edited.png` per
   _forensics/image_map.json) was already on disk and referenced by ZERO pages —
   the sixth asset on this project with that signature. `.hero-text-copy-cu` is
   the only element in 52 captures that uses it, and only on these two pages.

   The class occurs on exactly 2 of the 52 captured pages, grepped. */
.main-container-copy-copy-cu { width: 100%; max-width: 1380px; margin-inline: auto; }
.main-container-copy-copy-cu::before,
.main-container-copy-copy-cu::after { content: " "; display: table; grid-area: 1 / 1 / 2 / 2; }
.main-container-copy-copy-cu::after { clear: both; }
.hero-wrapper-cu {
  display: flex;
  flex-flow: column;
  align-items: stretch;
  gap: 55px;
  margin-inline: 20px;
  padding-bottom: 20px;
}
.hero-text-copy-cu {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 220px;
  margin-top: 117px;
  border-radius: 30px;
  background-image: url('/images/office/img-0072-edited.png');
  background-position: 50%;
  background-repeat: no-repeat;
  background-size: cover;
}
/* Empty on the original, absolutely positioned, 0 x 0. Kept so the element
   sequence the rig pairs on matches. */
.heading-copy-cu {
  position: absolute;
  inset: auto auto 25%;
  z-index: 99;
  display: flex;
  flex-flow: column;
  gap: 10px;
  max-width: 600px;
  color: var(--black);
  font-size: 2rem;
}
@media screen and (max-width: 991px) {
  .hero-wrapper-cu { gap: 40px; margin-top: 120px; margin-inline: 20px; padding-bottom: 0; }
  .hero-text-copy-cu {
    flex-flow: column;
    justify-content: space-between;
    align-items: center;
    height: 120px;
    background-size: contain;
  }
  .heading-copy-cu {
    gap: 0;
    flex-flow: column;
    justify-content: center;
    align-items: center;
    max-width: 500px;
    margin-inline: auto;
    bottom: 16%;
  }
}
@media screen and (max-width: 767px) {
  .hero-wrapper-cu { gap: 40px; margin-top: 100px; }
  .hero-text-copy-cu {
    gap: 20px;
    text-align: center;
    border-radius: 20px;
    height: 120px;
    margin-top: 0;
  }
  .heading-copy-cu { margin-inline: auto; bottom: 10%; }
}
@media screen and (max-width: 479px) {
  .hero-wrapper-cu { gap: 30px; margin-top: 0; }
  .hero-text-copy-cu {
    gap: 15px;
    background-size: cover;
    border-radius: 10px;
    width: 100%;
    max-width: 500px;
    height: 100px;
    margin-top: 100px;
  }
  .heading-copy-cu { font-size: 14px; bottom: 30%; }
}

/* /thank-you's body: one wrapper, one 70%-wide inner column, one h1.
   Reference at 1440: section 1440 x 198.406 at (0, 357);
   .thank-you-wrapper 1376 x 38.406 at (32, 437), padding-inline 20;
   .thank-you-inner-wrapper 935.188 x 38.406 at (252.406, 437);
   h1.thank-you-text 553.453 x 38.406 at (443.266, 437), 32px/38.4, centred.
   The size ladder is the original's own and it goes UP as the viewport narrows:
   2rem, then 4rem at <=991, 3.5rem at <=767, 2.8rem at <=479. Reproduced, not
   normalised. */
.thank-you-wrapper { padding-inline: 20px; }
.thank-you-inner-wrapper {
  display: flex;
  flex-flow: column;
  justify-content: center;
  align-items: center;
  width: 70%;
  margin-inline: auto;
}
.thank-you-text { text-align: center; font-size: 2rem; }
@media screen and (max-width: 991px) {
  .thank-you-inner-wrapper { width: 100%; }
  .thank-you-text { font-size: 4rem; }
}
@media screen and (max-width: 767px) { .thank-you-text { font-size: 3.5rem; } }
@media screen and (max-width: 479px) { .thank-you-text { font-size: 2.8rem; } }

/* site.css `.supporting-text` — the centred lead under a section heading.
   18px / 150%, black, left-aligned at <=479. */
.supporting-text {
  margin: 0;
  color: var(--black);
  text-align: center;
  font-size: 1.125rem;
  line-height: 150%;
}
@media screen and (max-width: 479px) { .supporting-text { text-align: left; } }

.grid { display: grid; gap: var(--space-6); }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }

/* .grid--2 GOES SINGLE-COLUMN AT 991, NOT 767 — moved 2026-09-09.
   Both blocks that use .grid--2 are single-column on the original at 768 and the
   rebuild was holding two columns there, halving every text measure at exactly
   one width:
     /emergency-dental  service h3    original 656.0  rebuild 286.0  (-370.0)
     /same-day-booking  new-dentist h2 original 700.8  rebuild 352.0  (-348.8)
   The original's own transition is at 991: /emergency-dental's service text
   measures 414.0 wide at 1024 (two up) and 656.0 at 768 (stacked). After the
   move the same two elements measure 670.0 (+14.0) and 736.0 (+35.2); the
   residual is the card padding and the container gutter, not the breakpoint.
   /same-day-booking's docH at 768 goes -135 -> -75 and no other width on that
   page changes by a pixel. .grid--3 and .grid--4 keep their existing
   991 -> two-up, 767 -> one-up ladder, unchanged. */
@media screen and (max-width: 991px) {
  .grid--2 { grid-template-columns: 1fr; }
  .grid--3, .grid--4 { grid-template-columns: repeat(2, 1fr); }
}
@media screen and (max-width: 767px) {
  .grid--3, .grid--4 { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   Buttons — radii and colours measured from the original
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  font-size: var(--fs-link);
  font-weight: var(--fw-medium);
  line-height: 1;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  padding: 1rem 2.25rem;
  border-radius: var(--radius-button);
  border: 2px solid var(--earls-green);
  background-color: var(--earls-green);
  color: var(--white);
  transition: background-color var(--dur-base) var(--ease-in-out),
              color var(--dur-base) var(--ease-in-out),
              border-color var(--dur-base) var(--ease-in-out),
              transform var(--dur-base) var(--ease-in-out);
}
.btn:hover {
  background-color: transparent;
  color: var(--earls-green);
  text-decoration: none;
}

.btn--outline {
  background-color: transparent;
  color: var(--earls-green);
  border-color: var(--earls-green);
}
.btn--outline:hover {
  background-color: var(--earls-green);
  color: var(--white);
}

.btn--white {
  background-color: var(--white);
  border-color: var(--white);
  color: var(--earls-green);
}
.btn--white:hover {
  background-color: transparent;
  color: var(--white);
}

/* --------------------------------------------------------------------------
   .button-au — a THIRD button component in the original, distinct from both
   .btn and .button-4. `sweet sans bold` 18px/700 on a 33px line, padding
   10px 36px, radius 30, 2px --body-background border (site.css:2847).

   The comment that used to sit here said the Bold "is the same OTF this project
   registers as Sweet Sans Pro weight 700, so 700 here renders identical glyphs
   from one @font-face rather than two". The FILE claim was true and stays true —
   the CDN .otf and our .woff2 measure 0.000px apart on every string at every
   size. The FAMILY claim is gone with AP-058: merging the two families changed
   what `--font-sans` at 700 means everywhere else, so this rule now names the
   bold family directly. 14 elements — /about-us, /emergency-dental (`.button-au
   _2`) and twelve on /same-day-booking.

   In main.css, not team.css: /about-us uses `.button-au` and /emergency-dental
   uses `.button-au _2`, and the latter does not load team.css.
   -------------------------------------------------------------------------- */
.button-au {
  display: inline-block;
  border: 2px solid var(--body-background);
  background-color: var(--earls-green);
  color: var(--white);
  border-radius: 30px;
  margin-top: 20px;
  padding: 10px 36px;
  font-family: var(--font-sans-bold);
  font-size: 18px;
  font-weight: 700;
  line-height: 33px;
  text-decoration: none;
  transition: background-color 0.3s cubic-bezier(0.86, 0, 0.07, 1);
}
.button-au:hover {
  border-color: var(--earls-green);
  background-color: var(--white);
  color: var(--earls-green);
  text-decoration: none;
}
/* `.button-au._2` — 1px border in earls-green and no top margin. */
.button-au._2 { border-width: 1px; border-color: var(--earls-green); margin-top: 0; }

/* `.section-top-title-wrapper`, `.sparkles-icon`, `.section-top-title` and
   `.section-top-title._2` WERE DECLARED HERE and are DELETED as duplicates.
   Round G ticket 7 added the same four in the AP-041 block above, together with
   the `._1` / `._2` fill variants, `.sparkles-icon._1` and the 479 text-align —
   and two copies of the same selector at equal specificity is precisely the
   "later wins" trap: whichever block someone edits, the other may be the one in
   effect. One copy, above, with the variants. */

@media screen and (max-width: 767px) {
  .button-au { text-align: center; padding: 12px 32px; font-size: 16px; }
  .button-au._2 { padding-block: 10px; }
}
@media screen and (max-width: 479px) {
  .button-au { margin-top: 15px; line-height: 30px; }
  .section-top-title._2 { text-align: center; }
}

.btn--pill { border-radius: var(--radius-pill); }
/* `.form-button` (site.css:6219) over Webflow's `.w-button` (site.css:1849).
   TRANSCRIBED 2026-09-11, Maya review #6 T2. The original:
     background-color var(--earls-green); border-radius .75rem;
     font-size 16px; line-height 32px; border 0; padding 9px 15px; colour #fff
   which computes 32 + 18 = **50px** tall and, as a stretched flex item of
   `form.form`, the full form width — 1032.797 x 50 at 1440.
   Was `.btn`'s `line-height: 1` (16px) + `padding: 1.25rem 2.5rem` +
   `border: 2px`, i.e. 670.000 x 60. Used only by the two `form.form`s (`/` and
   /same-day-booking), both of which are `.form-button` on the original.
   NOT changed: `.btn:hover` still inverts to a transparent fill. The original's
   `.form-button` has no hover rule of any kind, so hovering it does nothing
   there. Hover is not a swept state (measurement-traps §10.4) and is not in
   this ticket — measured and recorded in VISUAL_QA.md rather than changed. */
.btn--form {
  border-radius: 0.75rem;
  padding: 9px 15px;
  border: 0;
  font-size: 16px;
  line-height: 32px;
  /* `.form-button` declares no weight, so it inherits the body's 400. `.btn`
     sets `var(--fw-medium)` = 500. Measured 400 -> 500 on the reference at all
     six widths; the button is full-width so it cost no geometry, only a heavier
     label. */
  font-weight: 400;
}
.btn--block { width: 100%; }

/* Phone CTA with icon, as used in the hero */
.btn-phone {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  background-color: var(--earls-green);
  border: 2px solid var(--earls-green);
  border-radius: var(--radius-pill);
  color: var(--white);
  padding: 0.75rem 1.5rem 0.75rem 0.75rem;
  font-weight: var(--fw-medium);
  transition: background-color var(--dur-base) var(--ease-in-out),
              color var(--dur-base) var(--ease-in-out);
}
.btn-phone:hover { background-color: transparent; color: var(--earls-green); text-decoration: none; }
/* The original has no circle behind the icon: the white glyph sits directly on
   the green pill (.phone-icon-wrapper { padding: 0 }). */
.btn-phone__icon {
  display: grid; place-items: center;
  flex: 0 0 auto;
}
.btn-phone__icon img { width: 24px; height: 24px; }
.btn-phone__text { font-size: var(--fs-h6); margin: 0; font-weight: var(--fw-regular); color: var(--white); }
.btn-phone:hover .btn-phone__text { color: var(--earls-green); }
/* White glyph needs inverting when the pill goes transparent on hover */
.btn-phone:hover .btn-phone__icon img { filter: invert(43%) sepia(31%) saturate(900%) hue-rotate(38deg) brightness(93%) contrast(88%); }

/* --------------------------------------------------------------------------
   Header / navigation
   -------------------------------------------------------------------------- */
/* CORRECTED 2026-09-04 against measurements of the original at 1440.
   The header measured 155.9 tall against the original's 133, and every nav item
   was displaced: Home began at x=390.5 against 415.6, About Us at 469.0 against
   509.3, Services at 573.6 against 626.1, Blogs at 674.0 against 738.5. The
   links themselves measured 23px tall against 56.
   Root cause was not one rule but four: no padding on the links, the wrong menu
   gap, the wrong logo size, and align-items:center where the original stretches. */
/* .navbar-about-us on the original: `position: fixed; inset: 0 0 auto; z-index: 999`.
   Fixed, not sticky — it is OUT of flow, so the hero begins at y=0 and the nav
   floats over it. Sticky keeps the header in flow, which pushed every service
   hero down by 133px and shortened it from 540 to 340. */
.site-header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 999;
  padding: 0;
  background: transparent;
}

/* .main-container-about-us-nav w-container — the level between the fixed header
   and the pill. max-width 1280 centred; 728 at <=991; 20px of padding at <=767
   and 10px at <=479. Measured container boxes on the reference:
     1440  1280 at x=80      768  728 at x=20 (padding 0)
     1024  1024 at x=0       390  390 at x=0, padding 0 10px
   REPLACED `max-width:1200; margin:auto` on .nav, which cannot express
   "min(viewport,1280) - 80" and so was 80px too wide at 1024 and 20px too wide
   at 390. */
.nav__container { max-width: var(--container-nav); margin-inline: auto; }

/* .navbar-wrapper-about-us: margin 20px 40px inside a 1280 container, so the
   wrapper is 1200 wide at x=120 and its top edge sits at y=20. */
.nav {
  margin: 20px 40px;
  background: var(--white);
  border: 2px solid var(--earls-green);
  /* 50px, NOT --radius-pill. The original declares border-radius: 50px on
     .navbar-wrapper-about-us and never overrides it, at any width. 10rem
     (=160px) looks identical on the 93px-tall desktop pill but the mobile pill
     is 59px tall, where 50px and 160px differ visibly. Measured: 50px at 1440,
     768 and 390 on the reference. */
  border-radius: 50px;
  box-shadow: var(--shadow-nav);
  display: flex;
  align-items: stretch;      /* NOT center — the original stretches */
  justify-content: space-between;
  gap: 10px;
  padding-inline: 20px;
}

/* .brand-about-us { align-self: flex-start }, logo 98x89 not 88x80.
   `display: block` and `flex: 0 1 auto`, NOT flex/0 0 auto. Both matter, and only
   between 992 and ~1210px: there the 944-wide pill cannot hold logo + 94px margin
   + 622.6 menu + 232.4 CTA, and the original resolves the overflow by SHRINKING
   THE LOGO. Measured at 1024 on the live site AND on the reference, identically:
   brand 24.03 x 89 (natural 392 wide), menu 598 at x=190, CTA 164 at x=798 — all
   inside the pill. At 1100 the logo is 73.6; at 1280 it is back to 98.
   With `display:flex` the <img> becomes a flex item with `min-width:auto` and
   cannot shrink, so the rebuild held the logo at 98 and pushed the CTA to x=871.9
   +164 = 1035.9 — 74px outside the pill and past the 1024 viewport edge.
   This reproduces the original. Whether the squashed logo should be FIXED is a
   judgement call, raised for the CEO rather than decided here. */
.nav__brand { display: block; align-self: flex-start; flex: 0 1 auto; }
/* The logo SCALES DOWN with the viewport on the original. Pinning it at 98x89
   at every width held the whole fixed header at 183px below 991 — against the
   original's 94 / 79 / 74 — and that extra height is what buried the breadcrumb
   on the post and bio pages at 390. The mobile menu collapse was working the
   whole time; the logo was the cause. Measured on the original. */
.nav__brand img { width: 98px; height: 89px; }
@media screen and (max-width: 991px) { .nav__brand img { width: 98px; height: 70px; } }
@media screen and (max-width: 767px) { .nav__brand img { width: 80px; height: 60px; } }
@media screen and (max-width: 479px) { .nav__brand img { width: 70px; height: 55px; } }

/* .nav-menu-about-us — the 94px left margin is what places Home at x=415.6. */
.nav__menu {
  display: flex;
  align-items: stretch;
  align-self: center;
  gap: 11px;
  /* margin: 0 0 0 94px — the SHORTHAND matters. The base `ul` rule sets
     margin-bottom: 1rem, and inheriting it made the fixed header 16px taller
     than the original at every collapsed width: 90 against 74 at 390, 110
     against 94 at 768. */
  margin: 0 0 0 94px;
  font-weight: 700;
  list-style: none;
  padding: 0;
}
.nav__menu > li { display: flex; }

/* .nav-link-about-us plus Webflow's .w-nav-link padding. 16px text on a 100%
   line-height with 20px of padding is what makes each link 56px tall; without
   the padding they collapsed to 23 and the whole menu shifted left. */
/* weight 500 and #797979, taken from the COMPUTED style of the original, not
   from its stylesheet. site.css carries a `.nav-link-about-us` rule declaring
   limeade + weight 700, but that rule is scoped to the current-page state and
   never applies to an ordinary link. Reading it produced 700/green links that
   measured 86.4 / 112.9 / 108.4 / 86.3 / 184.6 wide against the original's
   82.7 / 105.8 / 101.4 / 80.0 / 171.6 — every one too wide, because synthetic
   weight widens the glyphs. */
.nav__link {
  display: flex;
  align-items: center;
  color: #797979;
  font-size: 16px;
  font-weight: 500;
  line-height: 100%;
  padding: 20px;
  text-decoration: none;
  /* NO `white-space: nowrap`. The original has none, and between 992 and 1279
     the 944-wide pill genuinely squeezes the nav: at 1024 the reference wraps
     "About Us" onto two lines (menu 598 x 72) and "Book an appointment" onto two
     (CTA 164 x 84). nowrap held the rebuild at 622.5 x 56 / 232.4 x 64 there.
     "Emergency&nbsp;Dental" carries a non-breaking space on the original and so
     never wraps internally — reproduced in Header.astro. */
  transition: color var(--dur-base) var(--ease-in-out);
}
/* Hover and current both go LIMEADE (#899a00), not earls-green (#678428).
   Measured on the original: hover rgb(137,154,0); the rebuild was rgb(103,132,40).
   CORRECTED 2026-09-09 (AP-022): the current-page WEIGHT is 500, not 700. The
   earlier comment here claimed 700 was "the w--current state"; site.css:2267 is
   `.nav-link-about-us.w--current { color:#899a00; font-weight:500 }`. 700 only
   appears on the :hover variants (2263 / 2273), which are a separate family
   (`sweet sans bold`). The reference computes 500 on the open mobile menu too. */
/* ADDED Round E ticket 6: the WEIGHT. The comment above has said since AP-022
   that 700 appears on the :hover variants (site.css:2263 / 2273) — the rule
   never implemented it. Hovering "About Us" on the original at 1440 measures
   font-weight 500 -> 700 and width 112.641 -> 112.906; the rebuild held 500 and
   112.641.
   The clause that used to end this paragraph — "`sweet sans bold` is the same
   file this project registers as Sweet Sans Pro 700, so the weight alone
   reproduces both the face and the metrics" — was retired by AP-058. Same
   FILE, different FAMILY, and --font-sans no longer has a 700 to reach. */
/* ADDED Round F ticket 10: the FAMILY. `.nav-link-about-us:hover` declares
   `font-family: sweet sans bold` as well as the weight, and on the 42 pages
   whose <body> carries no typeface class (AP-023) the link is ARIAL at rest, so
   hovering it changes family, not just weight. Measured on
   /services/veneers at 1440: the original goes 82.688 -> 86.359 on hover; the
   rebuild went 82.688 -> 84.453, i.e. it bolded Arial instead of switching to
   Sweet Sans. On the 10 Sweet-Sans-bodied pages the two are indistinguishable,
   which is why a homepage-only check missed it.
   CHANGED 2026-09-11 (AP-058) to --font-sans-bold. 275 links across 55 pages. */
.nav__link:hover {
  color: var(--limeade);
  text-decoration: none;
  font-weight: var(--fw-bold);
  font-family: var(--font-sans-bold);
}
.nav__link[aria-current="page"] { color: var(--limeade); font-weight: 500; text-decoration: none; }
/* site.css:2273 `.nav-link-about-us.w--current:hover` — the CURRENT-page link
   bolds on hover too. This rule and `.nav__link:hover` have equal specificity
   and the attribute rule comes later in source, so the current link was
   swallowing the hover weight entirely: measured, the original went 500 -> 700
   and 86.453 -> 86.359 while the rebuild changed NOTHING. */
.nav__link[aria-current="page"]:hover { font-weight: var(--fw-bold); font-family: var(--font-sans-bold); }
/* The nav's brand anchor has no link styling on the original and nothing
   happens when you hover it. In the rebuild the global `a:hover
   { text-decoration: underline }` (main.css:76) reached it, because unlike
   `.nav__link` it had no override — measured `none -> underline` on the logo
   link. This is the "nav link hover underline" from review #5; the element is
   the brand anchor, not the menu links, which were already clean. */
a.nav__brand:hover { text-decoration: none; }

/* .appointment-button-about-us — measured 215.2 x 64 at (1082.8, 34.5), green
   fill with white text. Note the CSS file declares a white-fill variant later
   in source; the COMPUTED value is the green one, which is why this was taken
   from the measurement and not from reading the stylesheet. */
.nav__cta {
  /* 0 1 auto, not 0 0 auto — Webflow's .w-button carries no flex declaration, so
     the original's CTA shrinks and wraps at 1024. */
  flex: 0 1 auto;
  align-self: center;
  padding: 20px 30px;
  font-size: 16px;
  font-weight: 500;
  line-height: 20px;
  /* CORRECTED Round F ticket 10. site.css `.appointment-button-about-us` is
     `border: 2px solid var(--nav-background)` — #e2e2e2 — at REST, and only
     goes green on :hover. The rebuild had the HOVER border at rest, so the
     button lost its visible 2px grey ring against the green fill. Measured on
     the reference: borderTopColor rgb(226,226,226) at rest, rgb(103,132,40) on
     hover; the rebuild was rgb(103,132,40) in both states. */
  border: 2px solid var(--nav-background);
  border-radius: 30px;
  background: var(--earls-green);
  color: var(--white);
}
/* Hover INVERTS to a white fill with green text. This is the second
   `.appointment-button-about-us` rule in site.css — reading it as the default
   is what made the button look wrong; it is the hover state. The rebuild was
   fading to transparent instead. */
.nav__cta:hover {
  background: var(--white);
  color: var(--earls-green);
  border-color: var(--earls-green);
  /* ADDED Round F ticket 10. `.appointment-button-about-us:hover` also declares
     `font-family: sweet sans bold`, which is the 700 face, so the label bolds.
     Measured on the reference at 1440: 232.391 -> 232.984 on a Sweet-Sans page
     and 215.219 -> 232.984 on an Arial one; the rebuild's width did not move at
     all in either case.
     CORRECTED 2026-09-11 (AP-058). site.css:2295 declares the FAMILY ONLY — no
     font-weight — so the original's computed weight stays 500 through the hover
     (the base rule, site.css:2288) and still renders Bold, because
     `sweet sans bold` has no face but the 700. Round F could only reach that
     face by asking --font-sans for 700, which made the rebuild compute 700 on
     hover where the original computes 500. Naming the one-face family drops the
     weight override and matches both the face and the computed value. */
  font-family: var(--font-sans-bold);
}

/* The in-menu CTA is mobile-only, exactly as in the original. The LI is hidden,
   not the anchor — see the note in Header.astro: hiding only the anchor left a
   zero-width flex item behind, which still ate an 11px gap.
   Written as a CHILD selector so it outranks `.nav__menu > li { display:flex }`
   (0,1,1) above; a bare `.nav__menu-cta` (0,1,0) loses to it and the CTA showed
   up in the desktop menu, taking it from 622.6 to 811.8 wide. */
.nav__menu > .nav__menu-cta { display: none; }

/* .menu-button-2 — padding 18px above 991 (where it is display:none anyway),
   10px at <=991, which with the 45x35 .hamburger-button gives the measured
   65x55 button. */
.nav__toggle {
  display: none;
  background: none;
  border: 0;
  cursor: pointer;
  padding: 18px;
}
/* .hamburger-button — 45x35, column, space-between, bars flush left */
.nav__toggle-bars {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: flex-start;
  width: 45px;
  height: 35px;
}
/* .line1-2 / .line2 / .line-4 — BLACK, square, 80%/100%/80% wide and 4px tall.
   The rebuild had 2px green rounded bars at 100% width. Measured on the
   reference at 390: 31.5x3, 45x3, 31.5x3 at y=17/33/49, background rgb(0,0,0). */
.nav__toggle-bars > span {
  display: block;
  width: 80%;
  height: 4px;
  background: var(--black);
  border-radius: 0;
  transition: transform var(--dur-base) var(--ease-in-out),
              opacity var(--dur-base) var(--ease-in-out),
              background-color var(--dur-base) var(--ease-in-out);
}
.nav__toggle-bars > span:nth-child(2) { width: 100%; }
/* OPEN STATE (T4, 2026-09-11). The original's close "X" is BRAND GREEN, not
   black. site.css declares only `background-color:#000` on `.line1-2/.line2/
   .line-4` and has NO `w--open` rule for them — the colour is applied by
   Webflow's IX2 interaction at runtime, which is why a stylesheet-only reading
   missed it and why the rig (which never opens the menu — measurement-traps
   §10.4) could not see it either. Measured on the LIVE site, menu opened:

     @390  .line1-2 / .line-4  bg rgb(103,132,40), AABB 24.395 x 24.395
           .line2              bg rgb(0,0,0), opacity 0   <- stays black
     @768  .line1-2 / .line-4  bg rgb(103,132,40), AABB 28.284 x 28.284
           .line2              bg rgb(0,0,0), opacity 0

   Bar 2 is deliberately left black: it is opacity 0 in both, and the original
   does not recolour it. Transform is translateY(15px), not 15.5 — the original's
   open matrix is matrix(0.707107, 0.707107, -0.707107, 0.707107, 0, 15) at both
   widths, which puts the AABB top at y=21.302 (@390) against 21.802 for 15.5. */
.nav__toggle[aria-expanded="true"] .nav__toggle-bars > span:nth-child(1) {
  transform: translateY(15px) rotate(45deg);
  background: var(--earls-green);
}
.nav__toggle[aria-expanded="true"] .nav__toggle-bars > span:nth-child(2) { opacity: 0; }
.nav__toggle[aria-expanded="true"] .nav__toggle-bars > span:nth-child(3) {
  transform: translateY(-15px) rotate(-45deg);
  background: var(--earls-green);
}

/* --------------------------------------------------------------------------
   Mobile navigation — collapses at 991px, matching the original
   --------------------------------------------------------------------------
   REBUILT 2026-09-09 (AP-009). The previous version rendered a 260x346 panel
   INSIDE the header pill with right-aligned links: it kept the menu as a
   wrapped flex line of .nav, so the panel could never be wider than the pill.
   The original moves the menu out of the pill entirely — Webflow relocates
   .w-nav-menu into .w-nav-overlay, which is absolutely positioned at
   `top:100%` of the fixed nav — and the menu is then a plain BLOCK box
   (`[data-nav-menu-open] { display:block !important }` beats the stylesheet's
   flex), 100% wide and 100vh tall, filled --glacier.

   Measured on the reference at 390, menu opened (identical to the CEO's live
   figures in _ceo-checks/CEO_DECISIONS.md §E):
     .w-nav-menu   390 x 844 at (0,74)  bg rgb(132,181,195)  padding 10px 0 0
     links         390 x 56, x=0, y = 84/140/196/252/308  (56px pitch)
                   16px/500/lh 16px, centred, padding 20px, #fff
                   current page rgb(137,154,0)
     CTA           250 x 54 at (70,384)  margin 20px 70px 0  padding 15px 0
                   bg rgb(103,132,40)  radius 25px  14px/700/lh 20px

   DEVIATION, geometry-neutral: the rebuild leaves the <ul> in the DOM and makes
   it `position:absolute; top:100%` against the fixed .site-header instead of
   moving the node into an overlay div. The original's menu computes
   `position:static` inside an absolute overlay; the rebuild's computes
   `absolute`. Same containing block, same rendered box (0,74,390,844), no
   overlay div to keyboard-trap, and no DOM surgery on every toggle. */
@media screen and (max-width: 991px) {
  .nav__container { max-width: 728px; }

  /* .navbar-wrapper-about-us at <=991: align-items switches to CENTER and the
     vertical margin halves to 10px. No VERTICAL padding — the original declares
     only padding-left/right, so the header height is the tallest child plus
     border plus margin. */
  .nav {
    padding: 0 20px;
    align-items: center;
    margin: 10px 20px;
  }
  /* .w-nav-button measures 65x55 on the original */
  .nav__toggle { display: block; order: 3; padding: 10px; }
  .nav__cta { display: none; }

  .nav__menu {
    /* Out of the pill's flex flow entirely. .site-header is the fixed,
       positioned ancestor, so top:100% lands on the header's own bottom edge:
       74 at 390, 94 at 768 — the same y as the original's overlay. */
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    display: none;
    height: 100vh;
    margin: 0;
    padding: 10px 0 0;
    background-color: var(--glacier);
    text-align: center;
    overflow: hidden;   /* .w-nav-overlay { overflow: hidden } */
  }
  .nav__menu.is-open { display: block; }
  .nav__menu > li { display: block; border-top: 0; }

  /* .nav-link-about-us at <=991: white, centred, full-width row, 20px padding */
  .nav__link {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 20px;
    color: var(--white);
    text-align: center;
  }
  /* hover is deliberately NOT neutralised here: the original's
     `.nav-link-about-us:hover` is (0,2,0) and still wins over the <=991 `#fff`
     rule, so a hovered mobile link goes limeade on the original too. */
  .nav__link[aria-current="page"] { color: var(--limeade); }

  /* .appointment-button-mobile-about-us — 300 wide at <=991, 250 at <=479.
     Note the GLACIER border, not green: measured 2px solid rgb(132,181,195). */
  .nav__menu > .nav__menu-cta { display: block; }
  .nav__menu-cta .btn {
    display: block;
    width: 300px;
    margin: 20px auto 0;
    padding: 15px 0;
    border: 2px solid var(--glacier);
    border-radius: 25px;
    background-color: var(--earls-green);
    color: var(--white);
    font-size: 16px;
    font-weight: 700;
    line-height: 20px;
    text-align: center;
  }
  .nav__menu-cta .btn:hover {
    border-color: var(--earls-green);
    background-color: var(--white);
    color: var(--earls-green);
  }
}

/* Continuing the original's own steps, declared descending after the 991 block
   so the later rule wins at equal specificity. */
@media screen and (max-width: 767px) {
  .nav__container { padding-inline: 20px; }
  .nav { margin-top: 5px; }
  .nav__menu-cta .btn { font-size: 14px; line-height: 25px; }
}
@media screen and (max-width: 479px) {
  .nav__container { padding-inline: 10px; }
  .nav { gap: 0; padding-inline: 0; }
  /* .brand-about-us gains 10px of left padding at <=479 — measured brand image
     x=42 against a wrapper content edge of x=32. */
  .nav__brand { padding-left: 10px; }
  .nav__toggle-bars > span { width: 70%; height: 3px; }
  .nav__toggle-bars > span:nth-child(2) { width: 100%; }
  /* 15px, not 16. The original's open matrix is
     `matrix(0.707107, 0.707107, -0.707107, 0.707107, 0, 15)` at 390 exactly as
     it is at 768 — it does NOT retune the offset for the shorter 3px bars, so
     its X is 1px asymmetric: the two strokes land at y 21.302 and 23.302, not
     on top of each other. 16px centred them perfectly at 22.302/22.302, which
     is tidier and is not what the practice approved. Measured against the LIVE
     site at 390 (the open menu is not a swept state). */
  .nav__toggle[aria-expanded="true"] .nav__toggle-bars > span:nth-child(1) { transform: translateY(15px) rotate(45deg); }
  .nav__toggle[aria-expanded="true"] .nav__toggle-bars > span:nth-child(3) { transform: translateY(-15px) rotate(-45deg); }
  .nav__menu-cta .btn { width: 250px; padding-inline: 0; font-size: 14px; line-height: 20px; }
}

/* --------------------------------------------------------------------------
   Breadcrumb  (an approved addition; the original has none)
   --------------------------------------------------------------------------
   MOVED HERE FROM service.css 2026-09-04.

   These base rules lived in service.css, which only service pages load. The
   post template ships `breadcrumb breadcrumb--dark` and the bio template ships
   `breadcrumb breadcrumb--light`, and blog.css / team.css define ONLY those
   modifiers. So on 22 posts and 5 bios the modifier applied and the reset did
   not: the <ol> kept `list-style: decimal` and `display: block` and rendered as

       1. Home
       2. Blogs
       3. <the entire post title>

   ...for 27 pages. A component is only as portable as the stylesheet its base
   rules sit in. Anything shared across templates belongs here.
   -------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------
   Green CTA band
   --------------------------------------------------------------------------
   MOVED HERE FROM service.css 2026-09-04, for exactly the reason the breadcrumb
   moved: the component is used by pages that do not load service.css.

   `[bio].astro` renders `.service-cta` but loads only team.css, so the band had
   no background — and `.btn--white` inside it computed
   `background rgb(255,255,255)` on a `rgb(255,255,255)` section. Zero contrast:
   the button read as bare text on /dr-ban-bio and /reception.

   Second instance of the same mistake in one session. Anything shared across
   templates belongs in main.css.
   -------------------------------------------------------------------------- */
/* AP-051, 2026-09-11: `color: var(--white)` REMOVED. The original's rule is
   `.service-cta { background-color: var(--earls-green) }` and nothing else
   (site.css:7399) — the section computes `color: rgb(51, 51, 51)` there, the
   body default, and every visible string inside gets its colour from its own
   class: `h2.white-2` #fff, `p.contact-subtitle` #d6d6d6,
   `a.button-4-copy-services` white. The rest of the band is in service.css.
   Grepped before removing: `section.service-cta` is on the 18 service detail
   pages and nowhere else in the rebuild. */
.service-cta { background-color: var(--earls-green); }
/* `.service-cta__inner` is NOT used by the service template any more (AP-051).
   It is kept, unchanged, because /same-day-booking's offer block uses it. */
.service-cta__inner { text-align: center; max-width: 48rem; margin-inline: auto; }
.service-cta__inner h2 { color: var(--white); }
.service-cta__inner p { margin-bottom: var(--space-6); }

.breadcrumb { margin-bottom: var(--space-4); }
.breadcrumb ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2);
  font-size: var(--fs-small);
  color: rgba(255, 255, 255, 0.85);
}
.breadcrumb li + li::before { content: '/'; margin-right: var(--space-2); opacity: 0.6; }
.breadcrumb a { color: rgba(255, 255, 255, 0.9); }
.breadcrumb a:hover { color: var(--white); }
.breadcrumb [aria-current='page'] { color: var(--white); font-weight: var(--fw-medium); }

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */
/* Rebuilt 2026-09-04 to reproduce the original. Every value below was measured
   off the live site, not chosen. See the header comment in Footer.astro.

   Media-query blocks are declared 991 -> 767 -> 479, DESCENDING, matching the
   original's own source order. At equal specificity the later block wins, so
   ascending order here would silently hand the 479 rules to a 900px viewport. */

.site-footer {
  /* The original's footer background is an IMAGE, not the solid green the
     previous rebuild used. 1440x735, cover. */
  color: var(--white);
  background-image: url("/images/ui/testi.png");
  background-position: 0 0;
  background-size: cover;
  font-size: 14px;
  line-height: 20px;
}
.site-footer a { color: var(--white); text-decoration: none; }
/* `.site-footer a:hover { text-decoration: underline }` REMOVED Round E ticket 6.
   Rebuild-only. Hovering `.footer-links a` on the original at 1440 changes
   NOTHING — `text-decoration-line` reads `none` before and after, colour stays
   rgb(216,216,216), box stays 140.141 x 30. The rebuild went `none -> underline`
   on every footer link on all 52 pages. */

/* .main-container-copy on the original: 1380 max-width, centred. */
.footer__container { max-width: 1380px; margin-inline: auto; }

.footer__wrapper {
  display: flex;
  flex-direction: column;
  gap: 56px;
  margin-inline: 40px;
  padding-block: 40px;
}

.footer__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  place-items: center stretch;
}

/* inline-block, not block, and that is load-bearing in a way neither obvious
   choice gets right on its own:
     inline   — margin-bottom does not affect layout at all
     block    — margin-bottom COLLAPSES with .footer__location's margin-top,
                so 10 + 20 becomes 20 and the column measures 469 not 479
   Webflow's normalize makes images inline-block, so the original's margins do
   not collapse and the measured gap is exactly 30px. */
.footer__logo {
  display: inline-block;
  vertical-align: top;
  width: 98px;
  height: 89px;
  margin-bottom: 10px;
}

.footer__location { margin-top: 20px; }
/* 16:9 responsive box, capped at 450px as the original's inline <style> does. */
.footer__map { position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%; }
.footer__map iframe {
  position: absolute; inset: 0; border: 0;
  width: 100%; height: 100%; max-width: 450px;
}

.footer__links {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 80px;
  place-items: center;
  padding-left: 0;
}

/* `place-self: start center` is the Webflow node rule `#w-node-a6d6c366-…-aef`
   and it is NOT decoration. Without it the column inherits `place-items: center`
   from `.footer__links` and centres VERTICALLY in the 319px row: measured
   136.969 x 230 at y 1374.828 against the original's y 1360.859 — the column sat
   44.5px low on all 55 pages, at every width, with every child correctly placed
   inside it. That is blind spot 1 in `measurement-traps.md` §10, which is why it
   survived four rounds. */
.footer__col {
  display: flex;
  flex-direction: column;
  gap: 20px;
  justify-content: center;
  align-items: flex-start;
  place-self: start center;
}

/* .text-block-7 on the original — the "Services" heading, a plain div whose ONLY
   declarations are `font-size: 18px; line-height: 30px`.
   CORRECTED Round G: `font-weight: 700` was here and the original computes 400.
   Measured 69.031 wide against the rebuild's 74.078 — dw +5.047 on all 55 pages,
   at every width. The comment above already said "a plain div"; the rule did not
   match its own comment. */
.footer__heading { font-size: 18px; line-height: 30px; margin: 0; font-weight: 400; color: var(--white); }

/* .link-2 on the original — note the 30px line-height and the grey, neither of
   which matches the site's body link style.

   CORRECTED Round F ticket 10 — the grey was DEAD. `#d8d8d8` has been declared
   here since Round D with a comment saying so, but `.site-footer a { color:
   var(--white) }` above is (0,1,1) against this rule's (0,1,0), so every footer
   service link rendered rgb(255,255,255) on all 55 pages. Measured on the
   reference: rgb(216,216,216) at rest, unchanged on hover. Scoped to
   `.site-footer` so it outranks the sheet's own `a` colour instead of relying on
   source order. */
.site-footer .footer__link { color: #d8d8d8; font-size: 14px; font-weight: 400; line-height: 30px; }

/* .right-side-footer / .form-text-blocks-footer / .heading-35-copy
   `place-self: start center` is the node rule `#w-node-_8c9979ab-…-740`. It is
   what makes this column SHRINK TO CONTENT and centre in its track below 992
   instead of filling it — 253.75 at x439.125 at 768 against a stretched 269.859
   at x431.063. */
.footer__hours { padding: 0 20px 20px; place-self: start center; }
.footer__hours-inner { margin-bottom: 10px; border-radius: 25px; color: var(--white); }
.footer__hours-heading {
  color: #eee;               /* var(--gallery) on the original */
  margin-top: 0;
  margin-bottom: 0;
}
.footer__hours-heading strong { font-size: 18px; line-height: 30px; font-weight: 700; }
/* .text-block-4-* — 18px on a 36px line, with 5px of lead. */
.footer__hour { color: var(--white); padding-top: 5px; font-size: 18px; line-height: 36px; }

.footer__contact {
  display: flex;
  flex-direction: row;
  gap: 25px;
  justify-content: center;
  align-items: flex-start;
  padding: 0 20px;
}
/* Each item: 35px icon, 15px gap, 10px of padding top and bottom — which is
   what makes the bar 55px tall rather than the 24px it measured before. */
.footer__contact-item {
  display: flex;
  flex-flow: row;
  justify-content: flex-start;
  align-items: center;
  gap: 15px;
  padding-block: 10px;
  border-radius: 15px;
  font-size: 18px;
}
/* `width: 35px` and NOTHING else — that is the whole of the original's rule
 * (`.image-39-footer, .image-36-copy-copy-footer, .icon-phone-copy-copy-footer
 * { width: 35px }`). Height comes from the 256x256 intrinsic ratio.
 *
 * `height: 35px; flex: none` was here and had to go. At 1024 the bar overflows
 * its 904px of content box by 91.234px and every item shrinks. flex-shrink 0 on
 * the icon raises the email item's automatic minimum size to 274.406, so it
 * refused to shrink at all and the deficit fell on the other two: measured
 * 274.406 / 167.297 / 412.297 against the original's 247.922 / 174.938 /
 * 431.141. With the original's shrinkable icon the deficit distributes
 * proportionally, which is what the original does. */
.footer__contact-item img { width: 35px; }
/* The original gives email and phone `order: 9999`, pushing the ADDRESS to the
   front of the row even though it is last in the DOM. Measured original x:
   address 180.7, email 723.3, phone 1046.4. */
.footer__contact-item--last { order: 9999; }
/* The three items are NOT one component on the original — they are three
 * separate classes with three separate gap histories, and collapsing them into
 * one rule is what cost 105px of footer height on all 55 pages. The original:
 *
 *   base            .email-cu-footer            gap 15
 *                   .phone-number-footer        gap 15
 *                   .address-ba-footer          gap 15
 *   max-width: 991  all three                   gap 10
 *   max-width: 767  .phone-number-footer ONLY   gap 15   <- email/address stay 10
 *   max-width: 479  .phone-number-footer ONLY   gap 15
 *
 * So --phone exists purely to carry that one restore. See the 767 block. */
/* `text-decoration: underline` ADDED Round F ticket 10. `.link-7` on the
   original is underlined AT REST and does not change on hover; the rebuild
   rendered `none`, so the footer's email and phone had no link affordance on any
   of the 55 pages. Recorded as measured-but-unactioned since Round E; the box is
   248.125 x 20 at x=773.297 on both sides before and after, so this costs
   nothing in layout. Same class as AP-039's ruling on the SEO block. */
.footer__contact-item a { color: #f9f9f9; font-size: 18px; text-decoration: underline; }
.footer__contact-item > div { color: var(--white); font-size: 18px; line-height: 28px; }

.footer__divider { background-color: #797979; height: 1px; }
.footer__note { text-align: center; font-size: 14px; line-height: 20px; }

@media screen and (max-width: 991px) {
  .footer__wrapper { gap: 40px; margin-inline: 20px; }
  .footer__grid { display: flex; flex-direction: column; gap: 55px; place-items: stretch stretch; }
  .footer__links { gap: 0; justify-content: start; align-items: start; width: 100%; }
  /* The node rule `#w-node-a6d6c366-…-aef { justify-self: start }`. Note that
     `.footer__links`'s own `justify-content: start` above does NOT do this — that
     aligns the TRACKS, not the items within them — so without this the column
     stayed centred at x=133.516 against the original's x=20 at 768. */
  .footer__col { justify-self: start; }
  /* `.right-side-footer { padding-left: 10px; padding-right: 10px }` at <=991 was
     missing; the base 20px was still applying, which made this column 269.859
     wide against the original's 253.75. */
  .footer__hours { padding-inline: 10px; }
  .footer__contact { flex-wrap: wrap; padding-inline: 10px; }
  .footer__contact-item { gap: 10px; }
  .footer__hours-inner { padding: 0 10px 10px; }
  .footer__hour { font-size: 14px; }
  /* ONLY the address text shrinks to 14px here.
   *
   * The anchors must NOT: `.link-7` on the original is a flat
   * `font-size: 18px` with no media override at any width, while
   * `.text-block-9-footer` (the address, a div) IS overridden to 14px at 991
   * and again at 479. This rule used to read
   * `.footer__contact-item a, .footer__contact-item > div`, which shrank the
   * anchors too — and that single extra selector was the whole of the footer's
   * -105.000px on all 55 pages.
   *
   * Mechanism, because it is not obvious from the font size alone: at 390 the
   * bar is `flex-wrap: wrap` in 350px. At the original's 18px the email item is
   * 224.406 wide and the phone 143.625, so 224.406 + 25 + 143.625 = 393.031
   * cannot share a row and each item wraps to its own. At 14px they measure
   * 174.547 and 111.703 — 311.250 with the gap — so they FIT on one row and the
   * bar lost a whole 85px row plus its 25px gap. */
  .footer__contact-item > div { font-size: 14px; }
  .footer__location { display: block; justify-content: center; align-items: center; }
  .footer__map iframe { max-width: 100%; }
}

@media screen and (max-width: 767px) {
  .footer__wrapper { margin-inline: 20px; }
  .footer__links { gap: 35px; align-self: center; place-items: stretch stretch; }
  /* `#w-node-a6d6c366-…-aef { justify-self: start }` again at 767 — the original
     repeats it, because `place-items: stretch stretch` on the line above would
     otherwise stretch the column across its whole 346.5px track. */
  .footer__col { justify-self: start; }
  .footer__contact { padding-bottom: 20px; padding-right: 10px; }
  /* PHONE ONLY — the original restores 15px here for `.phone-number-footer`
   * alone. Applying it to all three added 5px to the address item (126 against
   * the original's 121) on every page below 768. */
  .footer__contact-item--phone { gap: 15px; }
  .footer__hours { padding-bottom: 10px; padding-left: 10px; }
}

@media screen and (max-width: 479px) {
  .footer__wrapper { margin-inline: 20px; }
  .footer__links { gap: 40px; grid-template-columns: 1fr; }
  .footer__contact { justify-content: flex-start; align-items: center; padding-bottom: 0; }
  .footer__contact-item { flex-flow: column; justify-content: center; align-items: flex-start; }
  /* `#w-node-_8c9979ab-…-740 { place-self: start }` — at 479 the hours column
     stops centring and shrinks to content at the left edge: 274.281 at x=20
     against a stretched 350. */
  .footer__hours { padding-left: 0; place-self: start; }
  .footer__hours-inner { padding-top: 0; }
  .footer__hour { font-size: 16px; }
}

/* --------------------------------------------------------------------------
   Sticky mobile booking bar — .for-mobile-view-item              (AP-018)
   --------------------------------------------------------------------------
   In main.css, not home.css, because BOTH pages that carry it must load it and
   /emergency-dental does not load home.css by the same route as /. Anything
   shared across templates belongs here — third time this project has been bitten
   by that (breadcrumb, .service-cta, now this).

   Hidden above 767 exactly as the original hides it, so it cannot appear on
   desktop. Measured on the reference at 390: container 390 x 41.6 at (0,782.4),
   button 200.8 x 39.2 at (61.8,783.6), phone pill 41.6 x 41.6 at (286.6,782.4).
   -------------------------------------------------------------------------- */
.for-mobile-view-item {
  display: none;
  position: relative;
  bottom: 0;
  right: 0;
}
.mobile-view-button-wrapper-2 {
  display: none;
  flex-flow: row;
  justify-content: center;
  align-items: center;
  gap: 1.5rem;
}
.for-mobile-view-booking-button {
  color: var(--white);
  font-family: var(--font-lato);
  font-size: 1.125rem;
  /* `line-height: 20px` REMOVED 2026-09-09 (AP-024). It was a local patch for a
     global cause: the rebuild's <body> computed 16px/24px where the original's
     computes 14px/20px, so the leading inherited here came out 27px and the
     label 24 tall against the reference's 20, making the bar 43.2 instead of
     41.6. The body metrics are now the original's, so this label inherits 20px
     exactly as the original's does, with nothing declared. */
  text-decoration: none;
  padding: 0.6rem;
}
.for-mobile-view-booking-button:hover { color: var(--white); text-decoration: none; }
.number-link-wrapper-2 {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  gap: 1rem;
  border-radius: 25rem;
  padding: 0.8rem;
  text-decoration: none;
}
.phone-icon-wrapper {
  display: flex;
  flex-flow: column;
  justify-content: center;
  align-items: center;
  border-radius: 20rem;
  padding-right: 15px;
}
.phone-icon-2 { width: 100%; max-width: 1.4rem; height: auto; }

/* The bar only exists at <=767 on the original. Note the base rules above use
   #4bc9ff (Webflow's placeholder blue) and are never seen, because the base
   state is display:none — the green is declared here, in the <=767 block, which
   is the only state that renders. Reproduced as declared rather than tidied. */
@media screen and (max-width: 767px) {
  .for-mobile-view-item {
    z-index: 99999;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    position: fixed;
    bottom: 20px;
  }
  .mobile-view-button-wrapper-2 { display: flex; }
  .for-mobile-view-booking-button {
    background-color: var(--earls-green);
    color: var(--white);
    padding: 0.6rem 1rem;
  }
  .number-link-wrapper-2 { background-color: var(--earls-green); padding: 0.6rem; }
  .phone-icon-wrapper { padding: 0; }
}
@media screen and (max-width: 479px) {
  .mobile-view-button-wrapper-2 { display: flex; }
  .text-block-18 { font-size: 1rem; }
  .number-link-wrapper-2 { padding: 0.6rem; }
}

/* --------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */
/* `.form` is the original's `form.form` (site.css:6178) on BOTH pages that use
   it — `/` (section 03) and `/same-day-booking` — and its fields are the
   original's `.input` / `.w-input` (site.css:6186 and 1795). Transcribed
   2026-09-11, Maya review #6 T2:

     site.css:6178  .form      flex, flex-flow column, width 100%, gap 1.5rem
     site.css:6186  .input     height 45px, colour var(--boulder) #797979,
                               background #fafafa00 = rgba(250,250,250,0),
                               border 2px solid #97979729 = rgba(151,151,151,.16),
                               border-radius .4rem, margin-bottom 0
     site.css:6195  .input::placeholder, .input.select  colour var(--black)
     site.css:6209  .input.full.text-area   height 100px
     site.css:1795  .w-input   width 100%, padding 8px 12px, font-size 14px,
                               line-height 1.42857
     site.css:10284 (<=767)    .input width 50%, .input.full and .input._2 100%
     site.css:11754 (<=479)    .input width 100%, .input-flex flex-flow wrap

   Was: gap 16px (1rem), padding 1rem 1.25rem, 1px solid var(--nav-background)
   = rgb(226,226,226), background var(--white) = rgb(255,255,255), font-size
   16px, no height, textarea min-height 140px. That is the whole of the
   "Input rest state" ticket.

   `:focus` is deliberately LEFT as the rebuild's green ring: the original has
   no `.input:focus` rule at all, so it falls to Webflow's `.w-input:focus
   { border-color: #3898ec; outline: 0 }` — an unbranded blue. That is the
   site-wide focus-ring question settled as KEEP + DECLARE under AP-008, and it
   is declared in VISUAL_QA.md. Maya's ticket scopes itself to the REST state. */
.form { display: flex; flex-flow: column; width: 100%; gap: 1.5rem; }
.form__row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; }
/* 479, not 767: the original stacks Email/Phone when `.input-flex` gains
   `flex-flow: wrap` at <=479 (site.css:11758), and at 768 its two fields are
   still side by side. Both configured sweep widths either side (768 and 390)
   already agreed, so this changes nothing measured — it changes 480-767, which
   is not swept. */
@media screen and (max-width: 479px) { .form__row { grid-template-columns: 1fr; } }

.form label { font-weight: var(--fw-medium); font-size: var(--fs-small); }

.form input,
.form select,
.form textarea {
  /* `display: block` is the original's (site.css:1795, `.w-input, .w-select`)
     and it is not cosmetic. Left at the UA's `inline-block`, each field sat on
     the line BASELINE inside its label wrapper and the wrapper picked up the
     20px strut's descender: the textarea's wrapper measured 104.000 against the
     original's 100.000, and everything after it — the submit button — sat
     4.000px low at all six widths. */
  display: block;
  width: 100%;
  height: 45px;
  margin-bottom: 0;
  padding: 8px 12px;
  border: 2px solid rgba(151, 151, 151, 0.16);
  border-radius: 0.4rem;
  background: rgba(250, 250, 250, 0);
  color: var(--boulder);
  font-size: 14px;
  line-height: 1.42857;
  transition: border-color var(--dur-base) var(--ease-in-out),
              box-shadow var(--dur-base) var(--ease-in-out);
}
.form input::placeholder,
.form textarea::placeholder,
.form select { color: var(--black); }
.form input:focus,
.form select:focus,
.form textarea:focus {
  outline: none;
  border-color: var(--earls-green);
  box-shadow: 0 0 0 3px rgba(103, 132, 40, 0.15);
}
.form textarea { height: 100px; min-height: 0; resize: vertical; }

.form__status { font-size: var(--fs-small); border-radius: var(--radius-input); padding: var(--space-4); }
.form__status[hidden] { display: none; }
.form__status--ok { background: var(--tint-green); color: var(--earls-green); border: 1px solid var(--accent-lime-border); }
.form__status--error { background: #fdecec; color: #b3261e; border: 1px solid #f5c2c0; }

.field-error { color: #b3261e; font-size: var(--fs-small); }

/* --------------------------------------------------------------------------
   Cards
   --------------------------------------------------------------------------
   MOVED OUT 2026-09-11, AP-049.

   `.card`, `.card:hover`, `.card__media`, `.card__media img`, `.card__body`,
   `.card__title` and `.card__link` all lived here as GLOBAL rules. They had
   exactly one user — /services — verified by grepping the built HTML for
   `class="card"`, which matches .vercel/output/static/services/index.html and
   nothing else.

   They are gone rather than rewritten because AP-049 replaced the component
   they described. The original's card is not a white bordered panel with a
   28px title and a text link; it is a shadowed, 11.2px-radius ANCHOR wrapping
   an unpainted column, with an 18px h4 and a green pill. Keeping a global rule
   that describes the old design and overriding it per-page is the "modifier
   applied, reset did not" trap, so the whole component now lives in
   service.css scoped under `.all-services`, next to the original's markup it
   transcribes.

   The Round G ticket 3(a) correction that used to be documented here — the
   photographs are INTRINSICALLY sized, never cropped to a 3/2 box — is carried
   over verbatim into that rule and is still measured at 0.000 on w and x for
   all 18 at all six widths.

   `.card-link` (about-us), `.age-card` (/), `.service-card` (home.css,
   /same-day-booking) and `.blog-card` (blog.css) are different components and
   are untouched. */

/* --------------------------------------------------------------------------
   FAQ accordion — Round G ticket 5, transcribed from the original
   --------------------------------------------------------------------------
   `.faq`, `.faq__item`, `.faq__question`, `.faq__icon` and `.faq__answer` are
   DELETED. They described a single centred column of 10px-radius, 1px-bordered
   panels with the question at 17.6px/500 green; the original is a two-column
   grid of 30px-radius panels with a 2px earls-green border and the question at
   24px/40px/700 rgb(51, 51, 51).

   Measured original at 1440:
     section.faq        1440 x 1051.094 @ y9717.047   (the SEO embed is INSIDE it)
     .faq-wrapper       1300 x 416      @ x70   cols 481.5px 802.5px, gap 16,
                        margin 0 40px 140px
       .faq-text        480  x 376      @ x70   justify-self start, mt 40, gap 13
         .section-badge  85  x 40   2px solid rgb(103,132,40), radius 30, no fill
           .badge-text  34.625 x 20   16px / 20px / 700 / rgb(51,51,51)
         h2.heading-32  480 x 48       40px / 48px / 700 / rgb(0,0,0)
         p.paragraph-13 480 x 52       16px / 26px, margin-top 20
       .faq-items       802.5 x 376     @ x567.5   margin-top 40
         .faq-item      802.5 x 74      2px solid rgb(103,132,40), radius 30,
                                        margin-bottom 20
           .faq-question-2  798.5 x 70  flex, space-between, padding 20px 40px 10px
             .faq-ques-1    533.578 x 40  24px / 40px / 700 / rgb(51,51,51)
             img.faq-image  24 x 25
           .faq-answer      0 tall when closed

   `section.faq` has NO background on the original — the `#f6f8fb` band belongs
   only to the SEO embed nested inside it. `.faq-section { background:
   var(--tint-blue) }` painted rgb(246, 248, 251) across the whole FAQ band where
   the original shows the body's rgb(248, 249, 250); that rule is deleted too.
   -------------------------------------------------------------------------- */
.faq-wrapper {
  display: grid;
  grid-template-columns: .75fr 1.25fr;
  grid-template-rows: auto;
  gap: 16px;
  margin: 0 40px 140px;
}
/* `justify-self: start` is what makes the left column 480 wide rather than
   filling its 481.5px track — it comes from the Webflow node rule
   `#w-node-_966c4a2c-…-125404a2`, and the 480 itself is `.faq-para-text`'s
   fixed width. Without it the paragraph column is 1.5px wider. */
.faq-text {
  display: flex;
  flex-flow: column;
  gap: 13px;
  margin-top: 40px;
  justify-self: start;
}
.section-badge {
  display: flex;
  width: 85px;
  height: 40px;
  justify-content: center;
  align-items: center;
  align-self: flex-start;
  text-align: center;
  border: 2px solid var(--earls-green);
  border-radius: 30px;
}
.badge-text {
  display: flex;
  justify-content: center;
  align-items: center;
  /* site.css:4098 `font-family: sweet sans bold` at 700 — the one-face family,
     not --font-sans at 700. Switched 2026-09-11 (AP-058). 3 elements: two on
     `/`, one on /emergency-dental. */
  font-family: var(--font-sans-bold);
  font-size: 16px;
  font-weight: 700;
}
.heading-32 { font-size: 40px; }
.faq-para-text { width: 480px; }
.paragraph-13 { margin-top: 20px; font-size: 16px; line-height: 26px; }
.faq-items { margin-top: 40px; }
.faq-item {
  border: 2px solid var(--earls-green);
  border-radius: 30px;
  margin-bottom: 20px;
}
/* A <button>, not the original's bare div — see the deviation note in
   index.astro. `appearance: none` and the type resets are what stop the UA
   button styling; everything else is the original's `.faq-question-2`. */
.faq-question-2 {
  appearance: none;
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px 40px 10px;
  background: none;
  border: 0;
  color: inherit;
  /* `inherit`, not a fixed value. A <button>'s UA default is `center` so it must
     be overridden, but the original's plain div INHERITS: `start` above 992 and
     `left` at <=991, where `.faq-wrapper { text-align: left }` applies. Writing
     either literal produced a computed-style difference at one end of the sweep
     or the other on boxes that were otherwise exact. */
  text-align: inherit;
  cursor: pointer;
  font-family: inherit;
  font-size: 26px;
  line-height: 25px;
  transition: transform .3s cubic-bezier(.77, 0, .175, 1);
}
.faq-ques-1 { font-size: 24px; font-weight: 700; line-height: 40px; color: var(--color-body); }
.faq-image { flex: 0 0 auto; width: 24px; height: 25px; transition: transform var(--dur-base) var(--ease-in-out); }
.faq-question-2[aria-expanded="true"] .faq-image { transform: rotate(180deg); }
/* The original's closed state is an inline `display: none` set by Webflow's IX2.
   A `0fr` grid row collapses to the same 0 height and keeps the open/close
   animation. The original's `.faq-answer { padding: 10px 40px 20px }` moves to
   the paragraph, because padding on the collapsing box would still paint. */
.faq-answer {
  display: grid;
  grid-template-rows: 0fr;
  overflow: hidden;
  transition: grid-template-rows var(--dur-base) var(--ease-in-out);
}
.faq-answer > div { overflow: hidden; }
.faq-item.is-open .faq-answer { grid-template-rows: 1fr; }
.faq-ans-1 { margin: 0; padding: 10px 40px 20px; font-size: 18px; line-height: 30px; }

@media screen and (max-width: 991px) {
  .faq-wrapper { grid-template-columns: 1fr; grid-template-rows: auto auto; text-align: left; }
  .faq-text { margin-top: 0; margin-left: 20px; text-align: left; }
  .faq-item { padding-bottom: 20px; }
  .faq-ques-1 { margin-bottom: 0; }
  .faq-ans-1 { padding-right: 120px; font-size: 16px; line-height: 20px; }
}

@media screen and (max-width: 767px) {
  .faq-wrapper { margin-top: 40px; }
  .faq-text { margin-left: 0; }
  /* The badge goes to `display: block` at 90px wide and the text inside picks up
     a 10px top margin — that is how the original re-centres it. */
  .section-badge {
    display: block;
    flex: 0 auto;
    width: 90px;
    justify-content: flex-start;
    align-self: center;
    align-items: center;
    flex-flow: row;
  }
  .badge-text {
    display: block;
    flex: 0 auto;
    flex-flow: column;
    justify-content: center;
    align-items: center;
    margin-top: 10px;
    margin-bottom: auto;
    line-height: 100%;
  }
  .faq-items { margin-top: 20px; }
  .faq-item { margin-bottom: 40px; }
  .faq-question-2 { padding-left: 20px; padding-right: 20px; }
  .faq-ques-1 { padding-right: 40px; font-size: 22px; line-height: 38px; }
  .faq-ans-1 { padding: 10px 40px 0 20px; font-size: 16px; line-height: 24px; }
}

@media screen and (max-width: 479px) {
  .faq-wrapper {
    grid-auto-flow: column;
    place-items: center;
    height: auto;
    margin-bottom: 0;
    margin-inline: 0;
  }
  .faq-text { gap: 0; margin-left: 0; place-self: center; }
  .section-badge { align-self: center; }
  .badge-text { margin-top: 8px; }
  .faq-heading-text { width: 100%; text-align: center; }
  .heading-32 { margin-inline: auto; }
  .faq-para-text { width: auto; }
  .paragraph-13 { text-align: center; }
  .faq-items { margin-left: 0; padding-inline: 20px; }
  .faq-question-2 { padding: 20px 20px 5px; }
  .faq-ques-1 { padding-right: 20px; font-size: 20px; line-height: 32px; }
  .faq-ans-1 { padding: 10px 20px 0; font-size: 14px; font-weight: 400; }
}

/* --------------------------------------------------------------------------
   Scroll reveal — reproduces the original's dominant animation
   (291 scroll-into-view triggers, ~500ms slide+fade)
   -------------------------------------------------------------------------- */
.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity var(--dur-slow) var(--ease-out-quart),
              transform var(--dur-slow) var(--ease-out-quart);
}
.reveal.is-visible { opacity: 1; transform: none; }

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