/* Dove Dental — site CSS
 * Moved out of Bricks > Theme Styles > CSS on 2026-09-04.
 *
 * WHY: the Bricks builder holds the theme style in memory and writes the
 * whole thing back on save, so edits made outside the builder were being
 * silently overwritten. An ASE snippet is outside that save path.
 *
 * LOAD ORDER: this file is enqueued AFTER bricks-frontend-inline-css, so
 * it now WINS ties against Bricks' generated rules instead of losing them.
 * The defensive doublings below (:root:root, .dove-marquee.dove-marquee)
 * are therefore belt-and-braces rather than load-bearing — they are kept
 * so the CSS still behaves if it is ever moved back inline.
 */
/* Dove Dental — theme style stylesheet.
   States and shapes that have no native theme-style control.
   Tokens only: no raw colour or spacing values below.

   SPECIFICITY NOTE — read before editing.
   Bricks emits its button theme-style rules AFTER this stylesheet, in the
   same <style> tag, prefixed with :root — specificity (0,4,0). Anything
   here that competes with them must reach (0,5,0) or higher or it is
   silently discarded. That is why the doubled :root / repeated modifier
   class appears below. Do not "tidy" them away. */



/* ── Pill modifier ─────────────────────────────────────────────
   The header CTA pair (phone + Book Now) — the site's signature
   component. In-content buttons keep --radius-md.
   Class repeated to clear the (0,4,0) baseline. */
:root:root .bricks-button.btn-pill.btn-pill {
  border-radius: var(--radius-pill);
}

/* ── Focus ring ────────────────────────────────────────────────
   The ring colour itself comes from the theme style's Focus outline
   control (orange-700). This only adds the offset it cannot set. */
:focus-visible {
  outline-offset: 2px;
}

/* ── Utilities ─────────────────────────────────────────────────*/
.measure { max-width: var(--measure); }
.surface-alt { background-color: var(--clr-surface-alt); }

/* ── Motion ───────────────────────────────────────────────────*/
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── Logo marquee ─────────────────────────────────────────────────
   Continuous linear ticker, matching the live site’s ~91px/s.
   The track holds two identical sets, so animating to -50% lands exactly
   on the start of the duplicate and loops with no visible seam. That only
   works if each half is the SAME width, which is why the trailing gap is a
   margin on each set rather than a flex gap between them.
   Layout lives here, not in element settings: Bricks’ numeric width control
   silently drops max-content and calc() values.
   Reduced motion is handled by the global guard above. */
@keyframes dove-marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
/* Doubled class = (0,2,0), so it beats Bricks’ own .brxe-block { width:100% },
   which is emitted after this stylesheet. Do not “tidy” the repetition away. */
.dove-marquee.dove-marquee {
  display: flex;
  /* The track is a flex item of its overflow wrapper, so without this it is
     shrunk back to the wrapper width and max-content never takes effect. */
  flex: 0 0 auto;
  /* min-width is the one that actually holds: as a flex item the track’s
     cross size is otherwise clamped to the wrapper and max-content is ignored. */
  width: max-content;
  min-width: max-content;
  animation: dove-marquee var(--marquee-duration, 26s) linear infinite;
  will-change: transform;
}
/* each half */
.dove-marquee.dove-marquee > * {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  width: max-content;
  min-width: max-content;
  gap: var(--marquee-gap, calc(var(--space-xl) + var(--space-sm)));
  margin-right: var(--marquee-gap, calc(var(--space-xl) + var(--space-sm)));
}
/* each logo cell */
.dove-marquee.dove-marquee > * > * {
  flex: 0 0 var(--marquee-item, calc(var(--space-xl) * 2));
  display: flex;
  align-items: center;
  justify-content: center;
}
.dove-marquee:hover,
.dove-marquee:focus-within { animation-play-state: paused; }


/* ── Inline SVG icons ──────────────────────────────────────────────
   Icons are inline SVG, not an icon font, so nothing external is loaded.
   An SVG ignores font-size, which is what Bricks’ icon Size control sets —
   mapping height to 1em keeps that control working exactly as before, and
   the paths use fill=currentColor so the colour control still applies. */
svg.brxe-icon,
.brxe-social-icons svg,
.accordion-title svg {
  width: auto;
  height: 1em;
  flex: 0 0 auto;
}


/* ── Header ───────────────────────────────────────────────────────
   Mirrors the live header: a teal utility bar sitting above a nav bar
   that overlays the hero while transparent, then turns solid white
   once the page scrolls. Bricks toggles `.scrolling` on
   #brx-header.brx-sticky, so both states hang off that one class.
   Element settings stay token-only; these transitions live here
   because Bricks exposes no control for a scroll state. */

/* Live slides the utility bar out of view rather than collapsing it —
   on Divi the bar simply scrolls away while the nav row is fixed.
   Translating the whole sticky header by exactly the bar's height
   reproduces that: the bar leaves the viewport and the nav lands at 0.
   The height is derived from the same tokens that size the bar, so the
   two can never drift apart. */
#brx-header.brx-sticky {
  --dove-util-h: calc(var(--space-2xs) * 2 + var(--text-sm) * var(--leading-snug));
  transition: transform var(--duration-normal) var(--ease-out-expo);
}
#brx-header.brx-sticky.scrolling {
  transform: translateY(calc(-1 * var(--dove-util-h)));
}

/* Nav bar: a faint white veil over the hero at rest, solid white once
   stuck. The veil is the one value with no token — it is a translucent
   scrim, not a palette colour. */
.dove-nav-bar {
  background-color: rgb(255 255 255 / 0);
  transition: background-color var(--duration-normal) var(--ease-out-expo),
              padding-block var(--duration-normal) var(--ease-out-expo);
}
#brx-header.scrolling .dove-nav-bar {
  background-color: var(--clr-surface);
  border-bottom: 1px solid var(--clr-ink);
  padding-block: var(--space-3xs);
}

/* Logo shrinks on scroll — 156px at rest, 100px stuck, both expressed
   from the spacing scale so they stay on the grid. */
.dove-logo {
  --dove-logo-w: calc(var(--space-xl) * 2 + var(--space-sm) + var(--space-3xs));
}
.dove-logo img {
  width: var(--dove-logo-w);
  height: auto;
  transition: width var(--duration-normal) var(--ease-out-expo);
}
#brx-header.scrolling .dove-logo {
  --dove-logo-w: calc(var(--space-xl) + var(--space-md) + var(--space-3xs));
}

/* Bricks ships `.bricks-nav-menu > li { margin: 0 0 0 30px }` inside :where(),
   which carries zero specificity. Reset it so spacing comes from the element's
   own Gap control (primary nav) or the divider rule below (utility bar) —
   otherwise the two stack and every gap is 30px too wide. */
#brx-header .bricks-nav-menu > li { margin-left: 0; }

/* Utility bar: white rules between links, as on live. */
.dove-utility-bar .bricks-nav-menu > li:not(:last-child) {
  border-right: 1px solid var(--clr-surface);
  padding-right: var(--space-2xs);
  margin-right: var(--space-2xs);
}
.dove-utility-bar .bricks-nav-menu > li > a { padding: 0; }

/* Primary nav hover picks up the brand orange, matching the active item. */
.dove-nav-bar .bricks-nav-menu > li > a:hover,
.dove-nav-bar .bricks-nav-menu > li:hover > .brx-submenu-toggle > * {
  color: var(--clr-orange-500);
}

/* The header CTA pair must not wrap or shrink when the nav gets long. */
.dove-header-cta { flex: 0 0 auto; }
.dove-header-cta .bricks-button { white-space: nowrap; }

/* ── Header: responsive ───────────────────────────────────────────
   Live drops to a different header below 981px: the teal utility bar
   disappears, the row becomes burger | logo | two icon-only circles.
   Bricks has no breakpoint between its desktop base (1279) and
   tablet_portrait (991), so the mid-desktop tightening below has to be
   a hand-written query rather than a responsive element setting.

   SPECIFICITY — Bricks emits per-element CSS (#brxe-<id> ...) AFTER
   this stylesheet, so a plain class selector loses to it. The rules
   that compete with an element control are prefixed with #brx-header
   to reach (2,1,0). Do not "tidy" that away. */

/* Between ~992 and 1400 the full menu no longer fits beside the logo
   and the CTA pair, and wraps to a second line. Tighten instead. */
@media (max-width: 1400px) and (min-width: 992px) {
  #brx-header #brxe-hdnv04 .bricks-nav-menu { gap: var(--space-xs); }
  #brx-header #brxe-hdnv04 .bricks-nav-menu > li > a,
  #brx-header #brxe-hdnv04 .bricks-nav-menu > li > .brx-submenu-toggle > * {
    font-size: var(--text-sm);
  }
}

@media (max-width: 991px) {
  /* Live hides the utility bar entirely below 981px. */
  .dove-utility-bar { display: none; }

  /* burger | logo | actions — the nav element is third in the DOM so
     that the desktop order reads logo, nav, actions. */
  #brx-header #brxe-hdnv04 { order: -1; }
  .dove-nav-bar > .brxe-block { flex-wrap: nowrap; }

  /* The pills collapse to icon-only circles. The label is still in the
     accessibility tree — font-size:0 only removes it visually — so the
     buttons keep their names for screen readers without an aria-label.
     The icon needs an explicit size because the global rule maps SVG
     height to 1em, which font-size:0 would otherwise zero out. */
  #brx-header .dove-header-cta .bricks-button {
    font-size: 0;
    padding: var(--space-xs);
    border-radius: var(--radius-pill);
  }
  #brx-header .dove-header-cta .bricks-button svg {
    height: var(--space-s);
    width: var(--space-s);
  }
  .dove-logo { --dove-logo-w: calc(var(--space-xl) + var(--space-lg)); }
}

@media (max-width: 478px) {
  .dove-logo { --dove-logo-w: calc(var(--space-xl) + var(--space-md)); }
  #brx-header .dove-nav-bar { padding-inline: var(--space-s); }
}

/* ── Header: dropdown panel ───────────────────────────────────────
   Live's dropdown is a plain white card, 240px wide, soft shadow,
   with tight 28px rows. Bricks ships the panel as a DARK block with
   `line-height: 60px`, and the element's Sub-menu > Background control
   only reaches `.sub-menu .menu-item` — never the panel itself — so
   the container colour, rhythm and shadow all have to be set here.
   Prefixed with #brx-header to outrank the per-element CSS Bricks
   emits after this stylesheet. */
#brx-header .dove-nav-bar .bricks-nav-menu .sub-menu {
  background-color: var(--clr-surface);
  line-height: var(--leading-normal);
  min-width: calc(var(--space-xl) * 3 + var(--space-lg));
  padding-block: var(--space-s);
  box-shadow: 0 2px 5px rgb(0 0 0 / 0.1);
  border-radius: var(--radius-sm);
}
#brx-header .dove-nav-bar .bricks-nav-menu .sub-menu .menu-item > a:hover {
  color: var(--clr-orange-500);
}

/* ── Header: mobile menu depth ────────────────────────────────────
   Bricks styles the mobile menu as if it were two levels deep. Its
   Sub-menu > Padding control targets
     .bricks-mobile-menu .sub-menu > .menu-item > a
   which matches EVERY nested level equally, so level 3 lands on the
   same indent as level 2 and the hierarchy reads flat. This menu goes
   four deep (Treatments > Cosmetic Dentistry > Dental Veneers >
   Porcelain Veneers), so levels 3 and 4 are stepped in explicitly.

   Only the <a> is indented, never the toggle's <button> — the chevron
   is pushed to the right edge by the Icon margin control (margin-left:
   auto) and extra left padding on the button would fight it.

   Prefixed with #brx-header to outrank the per-element CSS Bricks
   emits after this stylesheet. */
#brx-header .bricks-mobile-menu .sub-menu .sub-menu > .menu-item > a,
#brx-header .bricks-mobile-menu .sub-menu .sub-menu > .menu-item > .brx-submenu-toggle > a {
  padding-left: calc(var(--space-lg) + var(--space-xs));
}
#brx-header .bricks-mobile-menu .sub-menu .sub-menu .sub-menu > .menu-item > a,
#brx-header .bricks-mobile-menu .sub-menu .sub-menu .sub-menu > .menu-item > .brx-submenu-toggle > a {
  padding-left: calc(var(--space-xl) + var(--space-xs));
}

/* The panel opens at viewport top, so its first row would sit under the
   fixed close button. Clear it. */
#brx-header .bricks-mobile-menu-wrapper .bricks-mobile-menu {
  padding-top: var(--space-xl);
}

/* ── Header: nav link colour when stuck ───────────────────────────
   At rest the nav floats over the hero, so its links are white. Once
   the header sticks, the bar turns white too and white-on-white
   disappears — switch the labels and chevrons to ink.

   Bricks drives these colours from the element's Typography controls
   as `#brxe-<id> .bricks-nav-menu > li > a`, so the override has to
   out-specify that. It does, without naming the element id, because it
   carries three classes to Bricks' one.

   The two :not() guards matter: they stop this rule matching a hovered
   or current item, so the element's own Hover and Active colours still
   win and stay editable in the builder. `[class*="current-menu"]`
   covers current-menu-item, -ancestor and -parent in one. */
#brx-header.scrolling .dove-nav-bar .bricks-nav-menu > li:not(:hover):not([class*="current-menu"]) > a,
#brx-header.scrolling .dove-nav-bar .bricks-nav-menu > li:not(:hover):not([class*="current-menu"]) > .brx-submenu-toggle,
#brx-header.scrolling .dove-nav-bar .bricks-nav-menu > li:not(:hover):not([class*="current-menu"]) > .brx-submenu-toggle > a,
#brx-header.scrolling .dove-nav-bar .bricks-nav-menu > li:not(:hover):not([class*="current-menu"]) > .brx-submenu-toggle > button {
  color: var(--clr-ink);
}

/* Fade with the background rather than snapping. */
.dove-nav-bar .bricks-nav-menu > li > a,
.dove-nav-bar .bricks-nav-menu > li > .brx-submenu-toggle,
.dove-nav-bar .bricks-nav-menu > li > .brx-submenu-toggle > a,
.dove-nav-bar .bricks-nav-menu > li > .brx-submenu-toggle > button {
  transition: color var(--duration-normal) var(--ease-out-expo);
}

/* ── Rich Text prose rhythm: lists ────────────────────────────────
   Bricks' contextual spacing strips default margins from h1-h6, p and
   ul, then hands the spacing back only to headings and paragraphs:

     .brxe-text * + :is(h1,…,h6) { margin-block-start: var(--space-md) }
     .brxe-text * + p            { margin-block-start: var(--space-md) }

   A list is left at margin 0, so a <ul> following a heading or a
   paragraph butts straight into it. Give lists the same rhythm as
   everything else, using the same token Bricks uses. */
.brxe-text * + :is(ul, ol),
.brxe-post-content:not([data-source="bricks"]) * + :is(ul, ol) {
  margin-block-start: var(--space-md);
}

/* ── Mobile menu: chevron hard right at every depth ───────────────
   Bricks applies its mobile-menu padding to `.brx-submenu-toggle > *`,
   so the rule that indents a row's LABEL also pads that row's toggle
   BUTTON. Sub-menu padding is larger than top-level padding (45px vs
   30px), so the deeper the item, the further its arrow sits from the
   panel edge — level 1 landed at 343, levels 2-3 at 328.

   The button box itself is already flush to the panel edge, so zeroing
   its inherited horizontal padding and giving it one fixed gutter puts
   every arrow in the same column, whatever the nesting depth. */
#brx-header .bricks-mobile-menu .brx-submenu-toggle > button {
  padding-inline-start: 0;
  padding-inline-end: var(--space-sm);
}

/* ── Mobile menu: the list must fill its panel ────────────────────
   The teal background sits on nav.bricks-mobile-menu-wrapper, which is
   a flex column. With align-items:flex-start the ul.bricks-mobile-menu
   inside it shrinks to its content — 205px inside a 415px overlay — so
   every row ends early and the chevrons (correctly right-aligned within
   that ul) appear stranded mid-panel.

   Stretch the list to the panel it is painted on, so "right" means the
   edge you can actually see. */
#brx-header .bricks-mobile-menu-wrapper { align-items: stretch; }
#brx-header .bricks-mobile-menu { width: 100%; }


/* ── Timeline connector ───────────────────────────────────────────
   One Divider per step, running from that step's own marker centre down
   to the NEXT step's marker centre. The last step carries no segment, so
   the line stops dead at the final number instead of running past it.

   The markers sit at the TOP of each step and are var(--space-xl) tall,
   so a marker's centre is half that from the step's top edge. A segment
   therefore starts at var(--space-xl)/2 and is
       own height + the row gap
   tall, which lands exactly on the next marker's centre whatever the
   card content does to the step's height. No fixed heights anywhere.

   Bricks draws a vertical divider with border-right on .line; that is
   swapped for a background here so the fill can be a gradient. */
.dove-timeline__line {
  --line-track: var(--clr-teal-200);
  --line-fill: var(--clr-orange-500);
  position: absolute;
  top: calc(var(--space-xl) / 2);
  left: calc(var(--space-xl) / 2);
  height: calc(100% + var(--space-md));
  width: 1px;
  gap: 0;
  pointer-events: none;
}
.dove-timeline__line .line {
  border: 0;
  width: 2px;
  height: 100%;
  background-color: var(--line-track);
  background-image: linear-gradient(var(--line-fill), var(--line-fill));
  background-repeat: no-repeat;
  background-size: 100% 0%;
}

/* Scroll-driven fill: each segment colours in as it passes through the
   viewport, so the line reads as progress down the process. Native CSS
   scroll timelines, so there is no JS and no scroll listener. Browsers
   without support simply get the fully drawn track. */
@supports (animation-timeline: view()) {
  @keyframes dove-timeline-fill {
    to { background-size: 100% 100%; }
  }
  .dove-timeline__line .line {
    animation: dove-timeline-fill linear both;
    animation-timeline: view();
    animation-range: cover 12% cover 55%;
  }
}

/* Reduced motion: show the line already filled rather than animating. */
@media (prefers-reduced-motion: reduce) {
  .dove-timeline__line .line {
    animation: none;
    background-size: 100% 100%;
  }
}

/* ── Header: only the current page is highlighted ─────────────────
   Bricks applies its Active typography to SIX selectors — the current
   item plus `.current-menu-parent` and `.current-menu-ancestor`:

     .bricks-nav-menu .current-menu-item > a
     .bricks-nav-menu > .current-menu-parent > a
     .bricks-nav-menu > .current-menu-ancestor > a      (+ toggle variants)

   So opening any child page lights up its top-level parent too, and
   TREATMENTS reads as "active" while you are on a service page. Reset
   the parent and ancestor cases back to the ordinary link colour and
   leave the highlight to the item you are actually on.

   :not(:hover) so the element's Hover colour still wins, and enough
   classes to out-specify the `#brxe-<id> …` rules Bricks emits. */
#brx-header .dove-nav-bar .bricks-nav-menu > :is(.current-menu-parent, .current-menu-ancestor):not(.current-menu-item):not(:hover) > a,
#brx-header .dove-nav-bar .bricks-nav-menu > :is(.current-menu-parent, .current-menu-ancestor):not(.current-menu-item):not(:hover) > .brx-submenu-toggle > * {
  color: var(--clr-surface);
}
#brx-header.scrolling .dove-nav-bar .bricks-nav-menu > :is(.current-menu-parent, .current-menu-ancestor):not(.current-menu-item):not(:hover) > a,
#brx-header.scrolling .dove-nav-bar .bricks-nav-menu > :is(.current-menu-parent, .current-menu-ancestor):not(.current-menu-item):not(:hover) > .brx-submenu-toggle > * {
  color: var(--clr-ink);
}

/* Same story one level down: Bricks' Sub-menu > Active typography targets
     .bricks-nav-menu .sub-menu > .current-menu-ancestor > a
   as well as the current item, so IMPLANTS lights up while you are on
   Full-Arch-On-Implants. Reset it to the ordinary sub-menu colour. */
#brx-header .dove-nav-bar .bricks-nav-menu .sub-menu > .current-menu-ancestor:not(.current-menu-item):not(:hover) > a,
#brx-header .dove-nav-bar .bricks-nav-menu .sub-menu > .current-menu-ancestor:not(.current-menu-item):not(:hover) > .brx-submenu-toggle > * {
  color: var(--clr-ink);
}

/* The "Proud members of" marquee carries professional-body and university logos,
   which are wider than the health-fund marks below it. Live sizes this track's
   cells at ~160px against the funds' ~137px, so it gets its own item width.
   Set here rather than on the element: the cells are sized by flex-basis above,
   which an element width cannot override. */
#brxe-0a40ae { --marquee-item: calc(var(--space-xl) * 2.5); }


/* Before/after tiles carry BEFORE and AFTER labels burnt into the picture, so any
   caption inside the frame collides with one of them — pinned to the bottom edge
   Bricks drops it onto AFTER, and floated to the middle it straddles the seam.
   It reads as small print underneath instead.

   Two knock-on fixes. The figure becomes a column so the gap does the spacing
   rather than a margin on the caption; and Bricks' overflow:hidden has to come off
   so the caption is not clipped, which means the rounded corners move from the
   figure onto the img, where they were always doing the visible work. */
.dd-ba-gallery .brxe-image.caption {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  overflow: visible;
}
.dd-ba-gallery .brxe-image.caption img {
  border-radius: var(--radius-xl);
}
.dd-ba-gallery figcaption {
  position: static;
  inset: auto;
  transform: none;
  background: none;
  padding: 0;
  color: var(--clr-ink);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
  text-align: center;
  pointer-events: auto;
}


/* Index cards show the picture, not the attachment caption — the case-note
   featured images carry before/after timeframes meant for the gallery. */
.dd-index-grid figcaption { display: none; }
