/**
 * Island Dental Studio — front end.
 *
 * Organised in labelled blocks rather than split into many files: WordPress has
 * no build step here, and one request beats ten. Every colour, size and measure
 * comes from the design tokens the Builder prints in <head> — nothing below
 * hardcodes a brand value.
 *
 *   01  Reset & base
 *   02  Typography
 *   03  Layout & containers
 *   04  Buttons
 *   05  Header
 *   06  Mobile navigation
 *   07  Footer
 *   08  Hero & section heads
 *   09  Utilities
 */

/* ═══════════════════════════════════════════════════════
   01  RESET & BASE
   ═══════════════════════════════════════════════════════ */

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

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
    /* Anchored sections clear the sticky header rather than hiding beneath it. */
    scroll-padding-top: var(--ids-sticky-offset);
}

body {
    margin: 0;
    background: var(--ids-white);
    color: var(--ids-body);
    font-family: var(--ids-font-body);
    font-size: var(--ids-body-size);
    line-height: var(--ids-body-lh);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    /* Nothing on this site is allowed to cause a sideways scrollbar.
       `clip` rather than `hidden` on purpose: `hidden` makes the body a scroll
       container, which silently breaks every `position: sticky` descendant. */
    overflow-x: clip;
}

img, picture, video, canvas, svg { display: block; max-width: 100%; }
img { height: auto; }
input, button, textarea, select { font: inherit; color: inherit; }
button { cursor: pointer; }

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

a { color: var(--ids-primary); text-decoration-thickness: 1px; text-underline-offset: 0.2em; }
a:hover { color: var(--ids-dark); }

hr { border: 0; border-top: 1px solid var(--ids-line); margin: 0; }

ul, ol { margin: 0 0 1em; padding-left: 1.25em; }
ul:last-child, ol:last-child { margin-bottom: 0; }

/* Focus: never removed, always designed. */
:focus-visible {
    outline: 2px solid var(--ids-primary);
    outline-offset: 3px;
    border-radius: 2px;
}
.ids-on-dark :focus-visible,
.ids-header :focus-visible,
.ids-footer :focus-visible,
.ids-mobile :focus-visible { outline-color: var(--ids-sage); }

.ids-skip {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 200;
    padding: 12px 20px;
    background: var(--ids-dark);
    color: #fff;
    border-radius: 0 0 var(--ids-radius-sm) 0;
    text-decoration: none;
}
.ids-skip:focus { left: 0; color: #fff; }

::selection { background: var(--ids-sage); color: var(--ids-dark); }

/* ═══════════════════════════════════════════════════════
   02  TYPOGRAPHY
   ═══════════════════════════════════════════════════════ */

h1, h2, h3, h4, h5, h6 {
    margin: 0 0 0.5em;
    font-family: var(--ids-font-heading);
    font-weight: 400;
    color: var(--ids-heading);
    /* Headings wrap at sensible points before they are ever allowed to shrink. */
    text-wrap: balance;
}
h1:last-child, h2:last-child, h3:last-child, h4:last-child { margin-bottom: 0; }

h1 { font-size: var(--ids-h1); line-height: var(--ids-lh-h1); letter-spacing: var(--ids-tracking-h1); }
h2 { font-size: var(--ids-h2); line-height: var(--ids-lh-h2); letter-spacing: var(--ids-tracking-h2); }
h3 { font-size: var(--ids-h3); line-height: var(--ids-lh-h3); letter-spacing: var(--ids-tracking-h3); }
h4 { font-size: var(--ids-h4); line-height: var(--ids-lh-h4); }
h5 { font-size: var(--ids-h5); line-height: 1.45; }
h6 { font-size: var(--ids-h6); line-height: 1.45; }

/**
 * The house heading treatment: the accented phrase is set in the display
 * italic. Editors pick the words in a separate field — never by typing markup.
 */
h1 em, h2 em, h3 em, h4 em,
.ids-heading em {
    font-style: italic;
    font-weight: inherit;
}

.ids-eyebrow {
    margin: 0 0 var(--ids-space-4);
    font-family: var(--ids-font-body);
    font-size: var(--ids-eyebrow-size);
    font-weight: 500;
    line-height: var(--ids-eyebrow-lh);
    letter-spacing: var(--ids-eyebrow-tracking);
    text-transform: uppercase;
    color: var(--ids-primary);
}
.ids-on-dark .ids-eyebrow { color: var(--ids-sage); }

.ids-lead { font-size: var(--ids-body-lg); line-height: 1.68; }
.ids-small { font-size: var(--ids-body-sm); line-height: var(--ids-body-sm-lh); }

/* Long-form editorial copy (rich-text fields, legal pages). */
.ids-prose h2 { margin-top: 1.4em; }
.ids-prose h3 { margin-top: 1.3em; }
.ids-prose ul, .ids-prose ol { padding-left: 1.15em; }
.ids-prose li { margin-bottom: 0.4em; }
.ids-prose li::marker { color: var(--ids-sage); }
.ids-prose strong { font-weight: 600; color: var(--ids-dark); }

/* On dark grounds body copy switches to the tone that stays legible there. */
.ids-on-dark { color: var(--ids-muted-on-dark); }
.ids-on-dark h1, .ids-on-dark h2, .ids-on-dark h3,
.ids-on-dark h4, .ids-on-dark h5, .ids-on-dark h6 { color: var(--ids-white); }
.ids-on-dark a { color: var(--ids-white); }

/* ═══════════════════════════════════════════════════════
   03  LAYOUT & CONTAINERS
   ═══════════════════════════════════════════════════════ */

.ids-container {
    width: 100%;
    max-width: calc(var(--ids-container) + (2 * var(--ids-gutter)));
    margin-inline: auto;
    padding-inline: var(--ids-gutter);
}
.ids-container--narrow { max-width: calc(var(--ids-container-narrow) + (2 * var(--ids-gutter))); }

/**
 * Full-bleed visual sections still stop at a sensible width so an ultrawide
 * monitor keeps the approved proportions instead of stretching the design.
 */
.ids-bleed {
    width: 100%;
    max-width: var(--ids-container-wide);
    margin-inline: auto;
}

.ids-section { padding-block: var(--ids-section-y); }
.ids-section--lg { padding-block: var(--ids-section-y-lg); }
/* The opener beneath a hero is drawn tighter — the hero already gives it air. */
.ids-section--sm { padding-block: clamp(28px, 3.06vw, 44px); }
/* The design does not use one global rhythm: some sections open large and
   close standard, or the reverse. These carry that intent. */
.ids-section--pt-lg { padding-top: var(--ids-section-y-lg); padding-bottom: var(--ids-section-y); }
.ids-section--pb-lg { padding-top: var(--ids-section-y); padding-bottom: var(--ids-section-y-lg); }
.ids-section--flush-top { padding-top: 0; }
.ids-section--flush-bottom { padding-bottom: 0; }
/* Reduced ends, for where two sections share a background and should read as
   one continuous stretch of the page — deliberate separation, not a full break. */
.ids-section--pt-sm { padding-top: clamp(32px, 3.33vw, 48px); }
.ids-section--pb-sm { padding-bottom: clamp(32px, 3.33vw, 48px); }
.ids-section--center { text-align: center; }
.ids-section--alt { background: var(--ids-offwhite); }
/* Stated explicitly rather than left to the body colour, so a section that must
   be white stays white wherever it is moved to. */
.ids-section--white   { background: var(--ids-white); }
/* The pale green surface token — the ground the design uses when a run of
   sections should sit on brand colour rather than on white. */
.ids-section--surface { background: var(--ids-surface); }
.ids-section--dark { background: var(--ids-dark); }
.ids-section--mid  { background: var(--ids-mid); }

.ids-btn-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ids-space-3);
    align-items: center;
}

/* ═══════════════════════════════════════════════════════
   04  BUTTONS
   Every state below is taken from the Figma Button component
   (Style × Surface × State — twelve combinations).
   ═══════════════════════════════════════════════════════ */

.ids-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--ids-space-2);
    padding: var(--ids-btn-pad-y) var(--ids-btn-pad-x);
    border: 1px solid transparent;
    border-radius: var(--ids-radius-btn);
    font-family: var(--ids-font-body);
    font-size: var(--ids-btn-font-size);
    font-weight: var(--ids-btn-weight);
    line-height: var(--ids-btn-lh);
    text-align: center;
    text-decoration: none;
    transition:
        background-color var(--ids-dur-fast) var(--ids-ease),
        border-color var(--ids-dur-fast) var(--ids-ease),
        color var(--ids-dur-fast) var(--ids-ease);
}
.ids-btn__icon { flex: none; }

/* ── Primary · light surface ── */
.ids-btn--primary.ids-btn--on-light {
    background: var(--ids-primary);
    border-color: var(--ids-primary);
    color: var(--ids-white);
}
.ids-btn--primary.ids-btn--on-light:hover {
    background: var(--ids-accent-alt);
    border-color: var(--ids-accent-alt);
    color: var(--ids-dark);
}
.ids-btn--primary.ids-btn--on-light:active {
    background: var(--ids-dark);
    border-color: var(--ids-dark);
    color: var(--ids-white);
}

/* ── Primary · dark surface ── */
.ids-btn--primary.ids-btn--on-dark {
    background: var(--ids-sage);
    border-color: var(--ids-sage);
    color: var(--ids-dark);
}
.ids-btn--primary.ids-btn--on-dark:hover {
    background: var(--ids-accent-alt);
    border-color: var(--ids-accent-alt);
    color: var(--ids-dark);
}
.ids-btn--primary.ids-btn--on-dark:active {
    background: var(--ids-surface);
    border-color: var(--ids-surface);
    color: var(--ids-dark);
}

/* ── Secondary · light surface ── */
.ids-btn--secondary.ids-btn--on-light {
    background: transparent;
    border-color: var(--ids-sage);
    /* Sage is a surface tone, never a text tone on white — the label uses the
       primary green so it stays legible. */
    color: var(--ids-primary);
}
.ids-btn--secondary.ids-btn--on-light:hover {
    background: var(--ids-sage);
    border-color: var(--ids-sage);
    color: var(--ids-dark);
}
.ids-btn--secondary.ids-btn--on-light:active {
    background: var(--ids-sage);
    border-color: var(--ids-primary);
    color: var(--ids-dark);
}

/* ── Secondary · dark surface ── */
.ids-btn--secondary.ids-btn--on-dark {
    background: transparent;
    border-color: var(--ids-white);
    color: var(--ids-white);
}
.ids-btn--secondary.ids-btn--on-dark:hover {
    background: var(--ids-white);
    border-color: var(--ids-white);
    color: var(--ids-dark);
}
.ids-btn--secondary.ids-btn--on-dark:active {
    background: var(--ids-surface);
    border-color: var(--ids-white);
    color: var(--ids-dark);
}

/* ── Text link style ── */
.ids-btn--text {
    padding: 0;
    background: none;
    border-color: transparent;
    color: var(--ids-primary);
    text-decoration: underline;
    text-underline-offset: 0.25em;
}
.ids-btn--text.ids-btn--on-dark { color: var(--ids-white); }
.ids-btn--text:hover { color: var(--ids-dark); }
.ids-btn--text.ids-btn--on-dark:hover { color: var(--ids-accent); }

/* ── Compact size ──
   The same button at card scale, for a control that sits inside a component
   rather than closing a section. Style and surface modifiers apply unchanged. */
.ids-btn--sm {
    padding: 9px 18px;
    font-size: 14px;
}

/**
 * Focus handed back by script after pointer use.
 *
 * When a dialog closes, the browser returns focus to the control that opened it
 * and — because script moved it — draws the keyboard focus ring, even for
 * someone who has only used a mouse. The control that was opened by pointer is
 * flagged until focus next leaves it or a key is pressed, and stays quiet for
 * that moment only. Focus is still on it; a keyboard user never gets the flag
 * and always gets the ring.
 */
.ids-btn[data-ids-focus-quiet]:focus-visible { outline: none; }

.ids-btn[aria-disabled="true"],
.ids-btn:disabled {
    opacity: 0.5;
    pointer-events: none;
}

/* ═══════════════════════════════════════════════════════
   05  HEADER
   ═══════════════════════════════════════════════════════ */

/**
 * The bar is the full width of the viewport and the content inside it is not.
 *
 * The glass is painted on this element, which spans edge to edge; the inset
 * that lines the logo up with the hero card is *padding* on the same element,
 * so it sits inside the painted area rather than pulling the background away
 * from the viewport edges. That is the whole structural difference between the
 * two states — the inner content's position is identical in both, which is why
 * nothing shifts, reflows or jumps when the glass arrives.
 */
.ids-header {
    position: fixed;
    top: var(--ids-admin-bar);
    right: 0;
    left: 0;
    z-index: 100;
    /* Symmetrical, so the bar reads as a band with the content centred in it
       rather than content sitting on the band's bottom edge. In the default
       state this padding also carries --ids-header-drop, which is what holds
       the whole composition inside the hero card instead of on its rim. */
    padding-block: var(--ids-header-pad);
    padding-inline: var(--ids-hero-inset);
    /* Always present, only ever recoloured: a border that appeared on scroll
       would change the header's height by a pixel as it did so. */
    border-bottom: 1px solid transparent;
    pointer-events: none;
    /* Transitioned rather than toggled, so the glass fades in on scroll — and
       so the bar closes down to its slim state as one movement rather than
       snapping between two sizes. */
    transition:
        background-color var(--ids-dur) var(--ids-ease),
        border-color var(--ids-dur) var(--ids-ease),
        box-shadow var(--ids-dur) var(--ids-ease),
        backdrop-filter var(--ids-dur) var(--ids-ease),
        padding-block var(--ids-dur) var(--ids-ease);
}

/**
 * The WordPress toolbar.
 *
 * It is fixed over the top of the viewport, and `html { margin-top }` — which
 * is how WordPress makes room for it — moves the document but not anything
 * fixed, so the site header would sit underneath it. The class is put on <html>
 * rather than read from body.admin-bar on purpose: --ids-sticky-offset is a
 * calc() declared on :root, and a custom property inside another one resolves
 * in the scope it was *declared* in, so an override on <body> would never reach
 * it — and `scroll-padding-top` lives on <html> as well.
 *
 * Two heights, both WordPress's own. Below 600px WordPress makes the toolbar
 * absolute so that it scrolls away with the page; there the header only has to
 * clear it while it is still at the top, which is exactly the state it is in
 * before it sticks.
 */
html.ids-admin-bar { --ids-admin-bar: 32px; }
@media screen and (max-width: 782px) {
    html.ids-admin-bar { --ids-admin-bar: 46px; }
}
@media screen and (max-width: 600px) {
    html.ids-admin-bar { --ids-admin-bar: 0px; }
    html.ids-admin-bar .ids-header:not(.is-stuck) { top: 46px; }
    /* The drawer opens from the top of the viewport here (the toolbar is no
       longer fixed), so its own clearance has to allow for the header sitting
       those 46px lower while the page is still at the top. */
    html.ids-admin-bar .ids-mobile__panel { padding-top: calc(46px + var(--ids-header-pad) + var(--ids-nav-height) + 8px); }
}
.ids-header > * { pointer-events: auto; }

.ids-header__inner {
    max-width: var(--ids-container-wide);
    margin-inline: auto;
    /* Matches the hero card's own horizontal padding (Figma: 40px). Together
       with the header's inset this is what holds the navigation to the site's
       measure while the bar behind it runs the full width of an ultrawide
       display. */
    padding-inline: clamp(16px, 2.78vw, 40px);
}

.ids-header__bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ids-space-5);
    height: var(--ids-nav-height);
    transition: height var(--ids-dur) var(--ids-ease);
}

/**
 * The stuck state, and the same state on pages with no hero to sit over.
 *
 * The glass arrives and the bar closes down at the same time: the vertical
 * inset drops from 24px to 8px, the bar itself from 72px to 56px, and the
 * oversized lockup returns to its drawn size. Everything stays centred on the
 * bar's own axis, so the compaction reads as one gesture rather than as three
 * elements each finding a new home. Nothing recolours — the logo and links are
 * already light.
 */
.ids-header.is-stuck,
body:not(.ids-has-hero) .ids-header {
    padding-block: var(--ids-header-pad-stuck);
    background: var(--ids-sticky-bg);
    border-bottom-color: var(--ids-sticky-border);
    box-shadow: var(--ids-sticky-shadow), var(--ids-sticky-highlight);
    -webkit-backdrop-filter: var(--ids-sticky-blur);
    backdrop-filter: var(--ids-sticky-blur);
    /* Now a solid surface from edge to edge, it has to catch its own clicks
       instead of letting them fall through to the page beneath. */
    pointer-events: auto;
}
.ids-header.is-stuck .ids-header__bar,
body:not(.ids-has-hero) .ids-header__bar { height: var(--ids-nav-height-stuck); }

/* The slim bar gives the nav and the button a little less room, so they give a
   little back — enough to stay comfortably off the glass edges, not enough to
   read as a different component. */
.ids-header.is-stuck :is(.ids-nav__link, .ids-nav__toggle),
body:not(.ids-has-hero) :is(.ids-nav__link, .ids-nav__toggle) { padding-block: 7px; }
.ids-header.is-stuck .ids-header__cta,
body:not(.ids-has-hero) .ids-header__cta { padding-block: 10px; }

body:not(.ids-has-hero) .ids-main { padding-top: calc(var(--ids-nav-height-stuck) + (var(--ids-header-pad-stuck) * 2) + 1px); }

/* ── Logo ── */
/**
 * Larger over the hero, drawn size once stuck.
 *
 * The enlargement is a transform on the anchor: a transform takes no part in
 * layout, so the bar's height is untouched and the lockup can shrink back on
 * stick without anything else moving. But a transform also claims no room, and
 * that is how the grown lockup came to run underneath the first link — the bar
 * laid out a 222px item while 345px of logo were painted over it. So the anchor
 * now reserves the room its grown self needs (a right margin equal to the
 * growth), and holds that reservation at the same size in both states: the
 * lockup shrinks inside it when the bar sticks, and the navigation, the phone
 * number and Book Online do not move by a pixel.
 *
 * Scaled from the left edge, so the lockup's left margin stays locked to the
 * hero copy below it. How far it can grow depends on how hard the navigation
 * is pressing, so --ids-logo-grow steps down at the widths where the bar
 * starts to fill. The steps are measured (qa-header.txt, header-refinement
 * evidence), each leaving at least 24px of clear bar beside the grown lockup.
 */
.ids-header__logo {
    --ids-logo-w: clamp(150px, 15.4vw, 222px);
    --ids-logo-grow: 1;
    --ids-logo-scale: var(--ids-logo-grow);
    display: block;
    flex: none;
    position: relative;
    width: var(--ids-logo-w);
    margin-right: calc(var(--ids-logo-w) * (var(--ids-logo-grow) - 1));
    line-height: 0;
    text-decoration: none;
    transform: scale(var(--ids-logo-scale));
    transform-origin: left center;
    transition: transform var(--ids-dur) var(--ids-ease);
}
@media (min-width: 1601px) { .ids-header__logo { --ids-logo-grow: 1.55; } }
@media (min-width: 1441px) and (max-width: 1600px) { .ids-header__logo { --ids-logo-grow: 1.45; } }
@media (min-width: 1281px) and (max-width: 1440px) { .ids-header__logo { --ids-logo-grow: 1.3; } }
@media (min-width: 1025px) and (max-width: 1280px) { .ids-header__logo { --ids-logo-grow: 1.15; } }
/* Once the links fold into the burger the bar empties out again. */
@media (min-width: 601px) and (max-width: 1024px) { .ids-header__logo { --ids-logo-grow: 1.45; } }
/* Below 600 the button and burger have it back. Drawn size. */

/* Back to the drawn size the moment the bar becomes the slim sticky band. The
   reserved room stays, so nothing beside the lockup shifts. */
.ids-header.is-stuck .ids-header__logo,
body:not(.ids-has-hero) .ids-header__logo { --ids-logo-scale: 1; }

.ids-header__logo-img {
    width: 100%;
    height: auto;
    transition: opacity var(--ids-dur) var(--ids-ease);
}
.ids-header__logo-img--dark {
    position: absolute;
    inset: 0;
    opacity: 0;
}
/* The light lockup is correct in both states of the dark-green glass header, so
   the dark lockup only appears when the light sticky variant is selected. */
.ids-sticky--light .ids-header.is-stuck .ids-header__logo-img--light,
body.ids-sticky--light:not(.ids-has-hero) .ids-header__logo-img--light { opacity: 0; }
.ids-sticky--light .ids-header.is-stuck .ids-header__logo-img--dark,
body.ids-sticky--light:not(.ids-has-hero) .ids-header__logo-img--dark { opacity: 1; }

.ids-header__wordmark {
    font-family: var(--ids-font-heading);
    font-size: 20px;
    color: var(--ids-sticky-text);
}

/* ── Navigation ── */
.ids-header__nav { flex: 0 1 auto; min-width: 0; }

.ids-nav {
    display: flex;
    align-items: center;
    gap: var(--ids-nav-gap);
    margin: 0;
    padding: 0;
    list-style: none;
}
.ids-nav > li { flex: none; }
/**
 * Each item is a rectangle, not a pill.
 *
 * The padding is part of the item at rest as well as on hover, so revealing the
 * background changes one property — its colour — and can never resize the item
 * or nudge the bar. The gap between items was reduced by the same amount the
 * padding adds, so the drawn rhythm between two labels is unchanged.
 *
 * A link and a group heading (About, Patients — buttons that open a panel)
 * share the one shape, so a heading reads as a peer of the links beside it
 * rather than as a control of another kind; the heading's chevron is the only
 * difference, and it turns when the panel is open.
 *
 * Every state below sets its own colour. The base stylesheet gives any
 * hovered link the dark text colour (a:hover), and that rule outranks a
 * single class, so without an explicit colour the label went dark on its
 * backing the moment the pointer reached it. The same goes for the social
 * marks, whose strokes follow currentColor.
 */
.ids-nav__link,
.ids-nav__toggle {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin: 0;
    padding: var(--ids-nav-item-pad-y) var(--ids-nav-item-pad-x);
    border: 0;
    border-radius: var(--ids-nav-item-radius);
    background: transparent;
    color: var(--ids-sticky-text);
    font: inherit;
    font-size: var(--ids-ui-sm);
    line-height: 20px;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color var(--ids-dur-fast) var(--ids-ease),
                color var(--ids-dur-fast) var(--ids-ease);
}
.ids-nav__chevron {
    flex: none;
    margin-right: -3px;
    opacity: 0.85;
    transition: transform var(--ids-dur-fast) var(--ids-ease);
}
.ids-nav__item--has-sub.is-open > .ids-nav__toggle .ids-nav__chevron { transform: rotate(180deg); }

.ids-nav__link:hover,
.ids-nav__link:focus-visible,
.ids-nav__toggle:hover,
.ids-nav__toggle:focus-visible,
.ids-nav__item--has-sub.is-open > .ids-nav__toggle { background: var(--ids-nav-item-hover); color: var(--ids-sticky-text); }

/* The page you are on keeps the stronger tint even while it is hovered, so the
   rectangle stays a statement of where you are rather than of where the pointer
   is. A child page marks its group: Our Team and Fees light About; New Patients
   and Patient Testimonials light Patients. */
.ids-nav > .current-menu-item > .ids-nav__link,
.ids-nav > .current_page_item > .ids-nav__link,
.ids-nav > .current-menu-item > .ids-nav__toggle,
.ids-nav > .current-menu-ancestor > .ids-nav__toggle,
.ids-nav > .current-menu-parent > .ids-nav__toggle,
.ids-nav > .current_page_ancestor > .ids-nav__toggle,
.ids-nav > .current_page_parent > .ids-nav__toggle { background: var(--ids-nav-item-active); color: var(--ids-sticky-text); }

/* ── Dropdown panels ── */
/**
 * The panel hangs from its heading, in the dark green of the stuck header's
 * glass made near-opaque: a translucent panel over a white page would lift the
 * page's text through it, and a backdrop blur inside an already-blurred header
 * cannot reach the page at all. The links inside are the bar's own rectangles.
 *
 * Closed, the panel is hidden to pointer and keyboard alike (visibility), and
 * the short rise on opening is a transform, so the bar's layout never changes.
 * It is positioned by its own item, so it travels with the header when the
 * bar sticks and compacts while it is open.
 */
.ids-nav__item--has-sub { position: relative; }
.ids-nav__sub {
    --ids-menu-bg: rgba(27, 53, 48, 0.94);
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    z-index: 1;
    min-width: 232px;
    margin: 0;
    padding: 8px;
    list-style: none;
    background: var(--ids-menu-bg);
    border: 1px solid var(--ids-sticky-border);
    border-radius: var(--ids-radius-md);
    box-shadow: var(--ids-sticky-shadow), var(--ids-sticky-highlight);
    -webkit-backdrop-filter: var(--ids-sticky-blur);
    backdrop-filter: var(--ids-sticky-blur);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-6px);
    transition:
        opacity var(--ids-dur-fast) var(--ids-ease),
        transform var(--ids-dur-fast) var(--ids-ease),
        visibility 0s linear var(--ids-dur-fast);
}
/* Bridges the 6px between the heading and the panel, so a pointer crossing it
   never counts as having left the item. */
.ids-nav__sub::before { content: ''; position: absolute; right: 0; bottom: 100%; left: 0; height: 8px; }
/* Open by the script; or, if the script never ran, by hover and keyboard focus
   so the pages inside are never out of reach. */
.ids-nav__item--has-sub.is-open > .ids-nav__sub,
.ids-header__nav:not([data-ids-nav-ready]) .ids-nav__item--has-sub:is(:hover, :focus-within) > .ids-nav__sub {
    opacity: 1;
    visibility: visible;
    transform: none;
    transition-delay: 0s;
}
.ids-nav__sub-link {
    display: block;
    padding: 10px 14px;
    border-radius: var(--ids-nav-item-radius);
    color: var(--ids-sticky-text);
    font-size: var(--ids-ui-sm);
    line-height: 20px;
    text-decoration: none;
    white-space: nowrap;
    transition: background-color var(--ids-dur-fast) var(--ids-ease),
                color var(--ids-dur-fast) var(--ids-ease);
}
/* Sage-toned tints here: the panel is already the dark green the bar's own
   tint is made of, so that tint would vanish against it. */
.ids-nav__sub-link:hover,
.ids-nav__sub-link:focus-visible { background: var(--ids-menu-item-hover); color: var(--ids-sticky-text); }
.ids-nav__sub .current-menu-item > .ids-nav__sub-link { background: var(--ids-menu-item-active); color: var(--ids-sticky-text); }
@media (prefers-reduced-motion: reduce) {
    .ids-nav__sub { transform: none; transition: none; }
    .ids-nav__chevron { transition: none; }
}

/* The light sticky variant: a white wash on a white bar shows nothing, so the
   stuck state swaps to the dark tints and the panel to white. Over the hero the
   bar is still dark and the white tints above are correct. */
.ids-sticky--light .ids-header.is-stuck :is(.ids-nav__link, .ids-nav__toggle, .ids-nav__sub-link):hover,
.ids-sticky--light .ids-header.is-stuck :is(.ids-nav__link, .ids-nav__toggle, .ids-nav__sub-link):focus-visible,
.ids-sticky--light .ids-header.is-stuck .ids-nav__item--has-sub.is-open > .ids-nav__toggle,
body.ids-sticky--light:not(.ids-has-hero) :is(.ids-nav__link, .ids-nav__toggle, .ids-nav__sub-link):hover,
body.ids-sticky--light:not(.ids-has-hero) :is(.ids-nav__link, .ids-nav__toggle, .ids-nav__sub-link):focus-visible,
body.ids-sticky--light:not(.ids-has-hero) .ids-nav__item--has-sub.is-open > .ids-nav__toggle { background: var(--ids-nav-item-hover-alt); color: var(--ids-sticky-text); }
.ids-sticky--light .ids-header.is-stuck .ids-nav :is(.current-menu-item, .current_page_item, .current-menu-ancestor, .current-menu-parent, .current_page_ancestor) > :is(.ids-nav__link, .ids-nav__toggle, .ids-nav__sub-link),
body.ids-sticky--light:not(.ids-has-hero) .ids-nav :is(.current-menu-item, .current_page_item, .current-menu-ancestor, .current-menu-parent, .current_page_ancestor) > :is(.ids-nav__link, .ids-nav__toggle, .ids-nav__sub-link) { background: var(--ids-nav-item-active-alt); color: var(--ids-sticky-text); }
.ids-sticky--light .ids-header.is-stuck .ids-nav__sub,
body.ids-sticky--light:not(.ids-has-hero) .ids-nav__sub { --ids-menu-bg: rgba(255, 255, 255, 0.97); }

/* ── Actions ── */
.ids-header__actions {
    display: flex;
    align-items: center;
    gap: 22px;
    flex: none;
}
.ids-header__phone {
    display: inline-flex;
    align-items: center;
    gap: var(--ids-space-2);
    color: var(--ids-sticky-muted);
    font-size: var(--ids-ui-sm);
    text-decoration: none;
    white-space: nowrap;
    transition: color var(--ids-dur-fast) var(--ids-ease);
}
.ids-header:not(.is-stuck) .ids-header__phone { color: var(--ids-white); }
/* Hovered, the number brightens to the bar's text colour rather than to the
   accent: the accent on the stuck glass measured 3.75:1, short of AA. */
.ids-header__phone:hover { color: var(--ids-sticky-text); }

/* The header CTA is the Primary/Dark button at the nav's tighter padding. */
.ids-header__cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 13px 24px;
    border-radius: var(--ids-radius-btn);
    background: var(--ids-sage);
    color: var(--ids-dark);
    font-size: var(--ids-body-sm);
    font-weight: 500;
    line-height: 20px;
    text-decoration: none;
    white-space: nowrap;
    transition: background-color var(--ids-dur-fast) var(--ids-ease), color var(--ids-dur-fast) var(--ids-ease);
}
.ids-header__cta:hover { background: var(--ids-accent-alt); color: var(--ids-dark); }
.ids-header__cta:active { background: var(--ids-surface); }
.ids-sticky--light .ids-header.is-stuck .ids-header__cta { background: var(--ids-primary); color: var(--ids-white); }
.ids-sticky--light .ids-header.is-stuck .ids-header__cta:hover { background: var(--ids-accent-alt); color: var(--ids-dark); }

/* ── Social ── */
/**
 * Facebook and Instagram, immediately right of Book Online, in both states of
 * the bar. Each is a 40px round target around an 18px mark in the links' own
 * colour, with a navigation item's hover tint — and the colour restated on
 * hover and focus, because the mark's strokes follow currentColor and the base
 * a:hover rule would otherwise turn them dark on the tint. The addresses come from the one
 * shared setting (Theme Settings → Social) that the drawer, the footer and the
 * Contact page also read — never a second copy.
 */
.ids-header__social {
    display: flex;
    align-items: center;
    gap: 2px;
    margin: 0 0 0 -10px;
    padding: 0;
    list-style: none;
}
.ids-header__social-link {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    border-radius: 999px;
    color: var(--ids-sticky-text);
    transition: background-color var(--ids-dur-fast) var(--ids-ease), color var(--ids-dur-fast) var(--ids-ease);
}
.ids-header__social-link:hover,
.ids-header__social-link:focus-visible { background: var(--ids-nav-item-hover); color: var(--ids-sticky-text); }
.ids-header__social-link .ids-icon { display: block; flex: none; }
.ids-sticky--light .ids-header.is-stuck .ids-header__social-link:hover,
.ids-sticky--light .ids-header.is-stuck .ids-header__social-link:focus-visible,
body.ids-sticky--light:not(.ids-has-hero) .ids-header__social-link:hover,
body.ids-sticky--light:not(.ids-has-hero) .ids-header__social-link:focus-visible { background: var(--ids-nav-item-hover-alt); color: var(--ids-sticky-text); }

/* ── Burger ── */
.ids-burger {
    display: none;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    margin-right: -10px;
    padding: 0;
    background: none;
    border: 0;
    color: var(--ids-sticky-text);
}
.ids-burger__box { display: block; width: 22px; height: 14px; position: relative; }
.ids-burger__line {
    position: absolute;
    left: 0;
    width: 100%;
    height: 1.5px;
    background: currentColor;
    border-radius: 2px;
    transition: transform var(--ids-dur) var(--ids-ease), opacity var(--ids-dur-fast) var(--ids-ease);
}
.ids-burger__line:nth-child(1) { top: 0; }
.ids-burger__line:nth-child(2) { bottom: 0; }
.ids-burger[aria-expanded="true"] .ids-burger__line:nth-child(1) { transform: translateY(6.25px) rotate(45deg); }
.ids-burger[aria-expanded="true"] .ids-burger__line:nth-child(2) { transform: translateY(-6.25px) rotate(-45deg); }

/**
 * Header responsiveness.
 *
 * The bar collapses in stages rather than at one device width, and each step
 * sits where the bar's own contents start to crowd — measured, not nominal
 * (qa-header.txt, header-refinement evidence): the lockup at its grown size,
 * the five items, the phone number, Book Online and the two social marks laid
 * end to end, with at least 24px to spare beside the lockup and beside the
 * button at every width.
 *
 *   ≥ 1200   everything in the bar (34px either side of the links at 1200).
 *   < 1200   the phone number goes first — it is in the drawer and the footer.
 *   ≤ 1024   the links fold into the burger (36px either side at 1025); the
 *            lockup grows into the room.
 *   ≤ 600    the social marks move to the drawer: the bar is lockup, button, burger.
 *
 * --ids-nav-compact is the burger breakpoint as a value the scripts can read
 * (the dropdowns and the drawer close across it); keep it in step with the
 * media query beneath.
 */
:root { --ids-nav-compact: 1024px; }
@media (max-width: 1199px) {
    .ids-header__phone { display: none; }
}
@media (max-width: 1024px) {
    .ids-header__nav { display: none; }
    .ids-burger { display: inline-flex; }
    .ids-header__actions { gap: var(--ids-space-3); }
    .ids-header__social { margin-left: 0; }
}
@media (max-width: 600px) {
    .ids-header__social { display: none; }
}
@media (max-width: 420px) {
    .ids-header__cta { padding: 11px 16px; font-size: 14px; }
}
/**
 * Under 400px the bar is narrower than the lockup, the button and the burger
 * laid end to end, and with every item refusing to shrink the burger was
 * carried past the right-hand edge (off-screen entirely at 320px). The lockup
 * is the one item that can give: it keeps its drawn width wherever there is
 * room and closes down to 112px only when there is not, while the gaps and the
 * button's padding tighten to buy it the rest.
 */
@media (max-width: 400px) {
    .ids-header__inner { padding-inline: 12px; }
    .ids-header__bar { gap: var(--ids-space-4); }
    .ids-header__logo { flex: 0 1 auto; min-width: 112px; }
    .ids-header__actions { gap: 10px; }
    .ids-header__cta { padding: 10px 12px; font-size: 13px; }
}

/* ═══════════════════════════════════════════════════════
   06  MOBILE NAVIGATION
   ═══════════════════════════════════════════════════════ */

.ids-mobile {
    position: fixed;
    /* Below the toolbar where that is fixed, so the panel never opens beneath
       it. Where WordPress lets the toolbar scroll away the value is 0 and the
       panel's own top padding — which clears the header — already puts every
       link well clear of it. */
    inset: var(--ids-admin-bar) 0 0;
    z-index: 95;
    background: rgba(9, 47, 39, 0.45);
    opacity: 0;
    transition: opacity var(--ids-dur) var(--ids-ease);
}
.ids-mobile[hidden] { display: none; }
.ids-mobile.is-open { opacity: 1; }

/**
 * The panel is the viewport: full width, flush to both edges, no card. Only its
 * *contents* are inset, and by the page's own gutter — so the menu lines up with
 * the copy on the page behind it rather than with an arbitrary panel padding.
 */
.ids-mobile__panel {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    width: 100%;
    background: var(--ids-dark);
    color: var(--ids-white);
    /* Clears the header so the close button stays reachable. Measured from the
       default bar, which is the taller of the two, so it clears either. */
    padding-top: calc(var(--ids-header-pad) + var(--ids-nav-height) + 8px);
    transform: translateX(100%);
    transition: transform var(--ids-dur) var(--ids-ease);
}
.ids-mobile.is-open .ids-mobile__panel { transform: translateX(0); }

/* The panel scrolls internally; the page behind it does not move. */
.ids-mobile__scroll {
    flex: 1;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    padding: var(--ids-space-6) var(--ids-gutter) var(--ids-space-7);
}

.ids-mobile__nav, .ids-mobile__sub, .ids-mobile__subnav { margin: 0; padding: 0; list-style: none; }
.ids-mobile__nav > li { border-bottom: 1px solid rgba(255, 255, 255, 0.1); }
/* A top-level row is a page link or a group heading; the two share one voice.
   The heading is a button the full width of the row, with its chevron at the
   right-hand edge where a thumb expects the affordance. */
.ids-mobile__link,
.ids-mobile__toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ids-space-3);
    width: 100%;
    margin: 0;
    padding: 15px 0;
    border: 0;
    background: none;
    color: var(--ids-white);
    font-family: var(--ids-font-heading);
    font-size: 22px;
    line-height: 1.3;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}
.ids-mobile__link:hover,
.ids-mobile__toggle:hover { color: var(--ids-accent); }
.ids-mobile__nav > .current-menu-item > .ids-mobile__link,
.ids-mobile__nav > .current-menu-item > .ids-mobile__toggle,
.ids-mobile__nav > .current-menu-ancestor > .ids-mobile__toggle { color: var(--ids-sage); }
.ids-mobile__toggle-icon {
    flex: none;
    color: var(--ids-muted-on-dark);
    transition: transform var(--ids-dur) var(--ids-ease);
}
.ids-mobile__item.is-open > .ids-mobile__toggle .ids-mobile__toggle-icon { transform: rotate(180deg); }

/* The group's pages. The wrapper is a one-row grid whose row grows from
   nothing to its content, which is what lets the height animate without being
   measured; closed, it is also hidden from keyboard and assistive technology. */
.ids-mobile__sub-wrap {
    display: grid;
    grid-template-rows: 0fr;
    visibility: hidden;
    transition: grid-template-rows var(--ids-dur) var(--ids-ease), visibility 0s linear var(--ids-dur);
}
.ids-mobile__sub-wrap > .ids-mobile__subnav { min-height: 0; overflow: hidden; }
.ids-mobile__item.is-open > .ids-mobile__sub-wrap { grid-template-rows: 1fr; visibility: visible; transition-delay: 0s; }
.ids-mobile__subnav > li:last-child { padding-bottom: 10px; }
.ids-mobile__sub-link {
    display: block;
    padding: 10px 0 10px 18px;
    color: var(--ids-muted-on-dark);
    font-size: 17px;
    line-height: 1.4;
    text-decoration: none;
}
.ids-mobile__sub-link:hover { color: var(--ids-white); }
.ids-mobile__subnav .current-menu-item > .ids-mobile__sub-link { color: var(--ids-sage); }
@media (prefers-reduced-motion: reduce) {
    .ids-mobile__sub-wrap, .ids-mobile__toggle-icon { transition: none; }
}

.ids-mobile__group { margin-top: var(--ids-space-7); }
.ids-mobile__heading {
    margin: 0 0 var(--ids-space-4);
    font-family: var(--ids-font-body);
    font-size: var(--ids-eyebrow-size);
    font-weight: 500;
    letter-spacing: var(--ids-eyebrow-tracking);
    text-transform: uppercase;
    color: var(--ids-sage);
}
.ids-mobile__sub a {
    display: block;
    padding: 9px 0;
    color: var(--ids-muted-on-dark);
    font-size: var(--ids-ui-sm);
    text-decoration: none;
}
.ids-mobile__sub a:hover { color: var(--ids-white); }

/* Pinned where a thumb reaches, and clear of the iOS home indicator. */
.ids-mobile__foot {
    flex: none;
    display: flex;
    flex-direction: column;
    gap: var(--ids-space-3);
    padding: var(--ids-space-5) var(--ids-gutter) calc(var(--ids-space-6) + env(safe-area-inset-bottom));
    border-top: 1px solid rgba(255, 255, 255, 0.12);
    background: rgba(0, 0, 0, 0.12);
}
.ids-mobile__utility {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ids-space-3);
}
.ids-mobile__phone {
    display: inline-flex;
    align-items: center;
    gap: var(--ids-space-2);
    color: var(--ids-white);
    font-size: 17px;
    text-decoration: none;
}
/* The same two accounts as the header, at a thumb's size. */
.ids-mobile__social {
    display: flex;
    gap: 4px;
    margin: 0 -12px 0 auto;
    padding: 0;
    list-style: none;
}
.ids-mobile__social a {
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    border-radius: 999px;
    color: var(--ids-white);
    transition: background-color var(--ids-dur-fast) var(--ids-ease);
}
.ids-mobile__social a:hover,
.ids-mobile__social a:focus-visible { background: rgba(255, 255, 255, 0.12); }
.ids-mobile__cta { width: 100%; }

body.ids-nav-open,
body.ids-profile-open { overflow: hidden; }

/* ═══════════════════════════════════════════════════════
   07  FOOTER
   ═══════════════════════════════════════════════════════ */

.ids-footer {
    background: var(--ids-dark);
    color: var(--ids-muted-on-dark);
    font-size: 14px;
}
.ids-footer__inner {
    max-width: calc(var(--ids-container) + (2 * var(--ids-gutter)));
    margin-inline: auto;
    padding: 80px var(--ids-gutter) 56px;
}

.ids-footer__top {
    display: grid;
    /* Four editorial columns that fold to two, then one — driven by the column's
       own comfortable width rather than a device breakpoint. */
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: var(--ids-space-8) var(--ids-space-8);
}

.ids-footer__logo { display: block; width: 243px; max-width: 100%; margin-bottom: 22px; }
.ids-footer__wordmark {
    margin: 0 0 22px;
    font-family: var(--ids-font-heading);
    font-size: 24px;
    color: var(--ids-white);
}

.ids-footer__address {
    display: flex;
    flex-direction: column;
    margin-bottom: 22px;
    font-style: normal;
    line-height: 24px;
}
.ids-footer__contact { display: flex; flex-direction: column; align-items: flex-start; line-height: 24px; }
.ids-footer__contact a { color: var(--ids-muted-on-dark); text-decoration: none; }
.ids-footer__contact a:hover { color: var(--ids-white); }

.ids-footer__heading {
    margin: 0 0 18px;
    font-family: var(--ids-font-body);
    font-size: var(--ids-eyebrow-size);
    font-weight: 500;
    line-height: 16px;
    letter-spacing: var(--ids-eyebrow-tracking);
    text-transform: uppercase;
    color: var(--ids-white);
}

.ids-footer__links {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin: 0;
    padding: 0;
    list-style: none;
}
.ids-footer__links a {
    color: var(--ids-muted-on-dark);
    font-size: 14px;
    line-height: 20px;
    text-decoration: none;
    transition: color var(--ids-dur-fast) var(--ids-ease);
}
.ids-footer__links a:hover { color: var(--ids-white); }

.ids-footer__hours { margin: 0; }
.ids-footer__hours-row { display: flex; justify-content: space-between; gap: var(--ids-space-4); line-height: 28px; }
.ids-footer__hours dt { color: var(--ids-muted-on-dark); }
.ids-footer__hours dd { margin: 0; color: var(--ids-white); text-align: right; }

.ids-footer__strapline {
    margin: var(--ids-space-8) 0 var(--ids-space-4);
    font-size: 11px;
    font-weight: 500;
    line-height: 16px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ids-sage);
}

.ids-footer__divider { border-top-color: var(--ids-mid); margin-bottom: var(--ids-space-4); }

.ids-footer__legal {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--ids-space-4) var(--ids-space-6);
}
.ids-footer__legal-text { margin: 0; font-size: 13px; line-height: 20px; }
.ids-footer__legal-text a { color: var(--ids-muted-on-dark); text-decoration: none; }
.ids-footer__legal-text a:hover { color: var(--ids-white); text-decoration: underline; }
.ids-footer__sep { padding-inline: 6px; opacity: 0.6; }

/**
 * The studio name inside the credit line.
 *
 * It keeps the credit's own type and colour — this is a byline, not a call to
 * action, and a bright underlined link in the corner of a footer reads as
 * unstyled markup. A faint rule underneath is enough to say it can be followed;
 * hovering brings both it and the words up to white.
 */
.ids-footer__credit-link {
    color: inherit;
    text-decoration: none;
    border-bottom: 1px solid rgba(255, 255, 255, 0.28);
    transition: color var(--ids-dur-fast) var(--ids-ease),
                border-color var(--ids-dur-fast) var(--ids-ease);
}
.ids-footer__credit-link:hover,
.ids-footer__credit-link:focus-visible {
    color: var(--ids-white);
    border-bottom-color: currentColor;
}

/**
 * Social accounts as pills.
 *
 * Icon and label sit on one line inside a single rounded target, and the target
 * is the whole anchor — there is no inner element to miss. At rest it is a
 * hairline on the dark ground; on hover or keyboard focus it fills with sage
 * and the label darkens to the brand green, which is the same figure/ground
 * swap the secondary button makes.
 *
 * The pending variant is the same pill for an account whose address has not
 * been entered yet. It is deliberately not a link and never fills: it shows the
 * client where the account will appear without shipping a dead one.
 */
.ids-footer__social {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ids-space-3);
    margin: 0;
    padding: 0;
    list-style: none;
}
.ids-footer__social a,
.ids-footer__social-pending {
    display: inline-flex;
    align-items: center;
    gap: var(--ids-space-2);
    padding: 8px 16px;
    border: 1px solid var(--ids-line-on-dark);
    border-radius: 999px;
    color: var(--ids-muted-on-dark);
    font-size: 13px;
    line-height: 20px;
    text-decoration: none;
    white-space: nowrap;
    transition:
        background-color var(--ids-dur-fast) var(--ids-ease),
        border-color var(--ids-dur-fast) var(--ids-ease),
        color var(--ids-dur-fast) var(--ids-ease);
}
/* The global `svg { display: block }` would otherwise let the icon and the
   label stack; as a flex item it is a row, and it must not be squeezed. */
.ids-footer__social .ids-icon { flex: none; }

.ids-footer__social a:hover,
.ids-footer__social a:focus-visible {
    background: var(--ids-sage);
    border-color: var(--ids-sage);
    color: var(--ids-dark);
}
.ids-footer__social-pending { opacity: 0.55; }

/* "Follow us" — the label sits on the pills' centre line, in the footer's
   small-caps voice, and wraps above them when the row runs out of room. */
.ids-footer__follow {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--ids-space-3) var(--ids-space-4);
}
.ids-footer__follow-label {
    margin: 0;
    font-size: var(--ids-eyebrow-size);
    font-weight: 500;
    line-height: 16px;
    letter-spacing: var(--ids-eyebrow-tracking);
    text-transform: uppercase;
    color: var(--ids-white);
}

/* The qualifier after the mobile number ("Mobile & WhatsApp"). */
.ids-footer__contact-note { font-size: 12px; opacity: 0.75; }
/* The WhatsApp line carries its mark: icon, number and note on one row. */
.ids-footer__whatsapp { display: inline-flex; align-items: center; gap: 6px; }
.ids-footer__contact-icon { flex: none; }

/* The accordion icon belongs to the one-column layout only. */
.ids-footer__toggle-icon { display: none; }

@media (max-width: 600px) {
    .ids-footer__inner { padding-top: 56px; padding-bottom: 40px; }
    /* One column from here down, stated outright: left to auto-fit the footer
       stayed two-up until about 530px, and the accordion below has to switch
       at exactly the width the columns do. */
    .ids-footer__top { grid-template-columns: minmax(0, 1fr); gap: var(--ids-space-7); }
    .ids-footer__legal { flex-direction: column; align-items: flex-start; }

    /* The brand block is centred as one piece — logo, address and contact —
       and the logo is sized against the column rather than held at its
       desktop width. Height stays automatic, so the lockup keeps its ratio. */
    .ids-footer__col--contact { text-align: center; }
    .ids-footer__logo { width: min(200px, 62%); margin-inline: auto; margin-bottom: var(--ids-space-5); }
    .ids-footer__address,
    .ids-footer__contact { align-items: center; }
}

/**
 * Link categories as accordions.
 *
 * `.is-accordion` is set by the footer-nav module, and only while the footer
 * is one column — so every rule here is scoped to that state rather than to a
 * media query, and a page without the script keeps its lists open.
 *
 * The panel is a one-row grid whose row runs from 0fr to 1fr. The browser works
 * out the height, so nothing is measured, nothing jumps when the text wraps
 * differently, and the content is clipped only while it is travelling. A closed
 * panel is also `visibility: hidden`, which is what takes its links out of the
 * tab order; the delay on that property holds it visible until the row has
 * finished closing.
 */
.ids-footer__group.is-accordion {
    border-top: 1px solid var(--ids-mid);
    border-bottom: 1px solid var(--ids-mid);
}
/* Consecutive categories share one rule and close up the grid's own gap. */
.ids-footer__group.is-accordion + .ids-footer__group.is-accordion {
    margin-top: calc(-1 * var(--ids-space-7));
    border-top: 0;
}
.ids-footer__group.is-accordion .ids-footer__heading { margin: 0; }

.ids-footer__toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ids-space-4);
    width: 100%;
    /* 16px type line + 2 × 18px: a 52px target. */
    padding: 18px 0;
    background: none;
    border: 0;
    color: inherit;
    font: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    text-align: left;
}
.ids-footer__group.is-accordion .ids-footer__toggle-icon {
    flex: none;
    display: grid;
    place-items: center;
    color: var(--ids-sage);
}
.ids-footer__toggle-plus,
.ids-footer__toggle-minus {
    grid-area: 1 / 1;
    transition: opacity var(--ids-dur-fast) var(--ids-ease);
}
.ids-footer__toggle-minus { opacity: 0; }
.ids-footer__group.is-open .ids-footer__toggle-plus { opacity: 0; }
.ids-footer__group.is-open .ids-footer__toggle-minus { opacity: 1; }

.ids-footer__group.is-accordion .ids-footer__panel {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows var(--ids-dur) var(--ids-ease);
}
.ids-footer__group.is-accordion.is-open .ids-footer__panel { grid-template-rows: 1fr; }
.ids-footer__group.is-accordion .ids-footer__panel-inner {
    min-height: 0;
    overflow: hidden;
    visibility: hidden;
    /* Room for a link's focus ring, which the clip would otherwise cut. */
    margin-inline: -6px;
    padding-inline: 6px;
    transition: visibility 0s linear var(--ids-dur);
}
.ids-footer__group.is-accordion.is-open .ids-footer__panel-inner {
    visibility: visible;
    transition-delay: 0s;
}
.ids-footer__group.is-accordion .ids-footer__links { padding: 6px 0 22px; }


/* ═══════════════════════════════════════════════════════
   08  HERO
   ═══════════════════════════════════════════════════════ */

.ids-hero {
    max-width: var(--ids-container-wide);
    margin-inline: auto;
    padding: var(--ids-hero-inset);
}

.ids-hero__frame {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    overflow: hidden;
    border-radius: var(--ids-radius-lg);
    background: var(--ids-dark);
    /* Heights interpolate with the viewport rather than stepping, so the banner
       keeps its proportions at every intermediate width. */
    min-height: clamp(440px, 38.9vw, 560px);
}
.ids-hero--tall     .ids-hero__frame { min-height: clamp(560px, 54.2vw, 780px); }
.ids-hero--medium   .ids-hero__frame { min-height: clamp(480px, 43.1vw, 620px); }
.ids-hero--short    .ids-hero__frame { min-height: clamp(380px, 33.3vw, 480px); }

.ids-hero__media { position: absolute; inset: 0; }
.ids-hero__img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
/* Which part of the photograph survives the crop on narrower screens. */
.ids-hero__img--center { object-position: 50% 50%; }
.ids-hero__img--top    { object-position: 50% 15%; }
.ids-hero__img--bottom { object-position: 50% 85%; }
.ids-hero__img--left   { object-position: 20% 50%; }
.ids-hero__img--right  { object-position: 80% 50%; }

/**
 * Two deliberate gradients, exactly as drawn: a short scrim at the top for the
 * navigation, and a diagonal one from the bottom-left behind the copy. This
 * keeps the brighter, more open half of each photograph visible instead of
 * flattening the whole image under one wash.
 */
.ids-hero__scrim {
    position: absolute;
    inset: 0;
    background: var(--ids-hero-scrim-top), var(--ids-hero-scrim-copy);
}

.ids-hero__content {
    position: relative;
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--ids-space-6);
    /* Top padding clears the overlaid header — including the drop that holds
       it inside the card — and the sides match the Figma card. */
    padding: calc(var(--ids-nav-height) + var(--ids-header-drop) + 15px) clamp(20px, 2.78vw, 40px) clamp(28px, 2.7vw, 39px);
    width: 100%;
}

.ids-hero__copy {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--ids-space-6);
    max-width: 940px;
}
.ids-hero__eyebrow { margin: 0; color: var(--ids-sage); }
/**
 * Hero heading measure.
 *
 * Different heroes need different measures — "Advanced minimally invasive and
 * aesthetic dentistry" wants a wide line, "Every price, published up front"
 * wants to break after the comma. That is a presentation decision, so it is set
 * per page as a width (Builder → Hero → "Heading width") and never by typing a
 * line break into the heading itself. Unset, the heading fills the copy column.
 */
.ids-hero__title {
    margin: 0;
    color: var(--ids-white);
    max-width: var(--ids-hero-title-measure, none);
}
.ids-hero__text {
    margin: 0;
    max-width: 620px;
    font-size: var(--ids-body-lg);
    line-height: 1.68;
    color: var(--ids-white);
}

/* Glass offer badge (Figma "Hero Offer Badge"). */
.ids-hero__badge {
    padding: 16px 22px;
    border: 1px solid var(--ids-glass-border);
    border-radius: var(--ids-radius-badge);
    background: var(--ids-glass-bg);
    -webkit-backdrop-filter: blur(var(--ids-glass-blur));
    backdrop-filter: blur(var(--ids-glass-blur));
}
.ids-hero__badge-value {
    margin: 0 0 2px;
    font-size: 24px;
    font-weight: 500;
    line-height: 30px;
    letter-spacing: -0.005em;
    color: var(--ids-accent);
}
.ids-hero__badge-text {
    margin: 0;
    max-width: 340px;
    font-size: 13px;
    line-height: 18px;
    color: var(--ids-surface);
    opacity: 0.72;
}

.ids-hero__action { flex: none; }

/**
 * Hero responsiveness. The copy and the action share a row on desktop; once
 * that would squeeze the heading, the button drops beneath the copy rather than
 * the heading being made smaller.
 */
@media (max-width: 900px) {
    .ids-hero__content {
        flex-direction: column;
        align-items: flex-start;
        gap: var(--ids-space-5);
    }
    .ids-hero__action { width: 100%; }
    .ids-hero__action .ids-btn { width: 100%; }
}
@media (max-width: 600px) {
    .ids-hero__copy { gap: var(--ids-space-5); }
    .ids-hero__badge { width: 100%; }
    .ids-hero__badge-text { max-width: none; }
}

/* Editor-only note for a section that has no renderer yet. */
.ids-build-note {
    padding: var(--ids-space-4);
    border: 1px dashed var(--ids-sage);
    border-radius: var(--ids-radius-sm);
    background: var(--ids-offwhite);
    font-size: var(--ids-ui-sm);
    color: var(--ids-body);
}

/* Shared section heading block. */
.ids-section-head { margin-bottom: var(--ids-space-7); }
.ids-section-head:last-child { margin-bottom: 0; }
.ids-section-head__title { margin: 0; }
.ids-section-head__intro {
    margin: var(--ids-space-4) 0 0;
    max-width: 720px;
}


/* ═══════════════════════════════════════════════════════
   09  UTILITIES
   ═══════════════════════════════════════════════════════ */

.ids-visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/**
 * Motion preferences are honoured globally: transitions collapse to
 * near-instant, and anything that moves on scroll simply stops moving.
 */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}
