/* src/styles/tokens.css */
/* Token primitives, pushed as a code asset by push-site.mjs.
   These CANNOT live in the style registry: happy-dom drops --custom-property
   declarations during conversion, silently. Edit site-src/css/ and re-push. */

/* Fluid root font-size — webzite-house-v1.
   Same curve as the Dr. Nahlah build (site-src/css/00-fluid-root.css) so the two
   Instatic sites share one rem basis. Client-First is a rem system: every size
   token below is a rem, and this is the only rule allowed to touch the root. */
:root {
  --font-from: 18;
  --font-to: 20;
  --vw-from: calc(1920 / 100);
  --vw-to: calc(2400 / 100);
  --coefficient: calc((var(--font-to) - var(--font-from)) / (var(--vw-to) - var(--vw-from)));
  --base: calc((var(--font-from) - var(--vw-from) * var(--coefficient)) / 16);
}

html {
  font-size: calc(var(--base) * 1rem + var(--coefficient) * 1vw);
}

@media screen and (max-width: 1920px) {
  :root {
    --font-from: 16;
    --font-to: 18;
    --vw-from: calc(1440 / 100);
    --vw-to: calc(1920 / 100);
  }
}

@media screen and (max-width: 1440px) {
  :root {
    --font-from: 16;
    --font-to: 16;
    --vw-from: calc(479 / 100);
    --vw-to: calc(1440 / 100);
  }
}

@media screen and (max-width: 479px) {
  :root {
    --font-from: 14;
    --font-to: 16;
    --vw-from: calc(320 / 100);
    --vw-to: calc(479 / 100);
  }
}

/* ===========================================================================
   SCULPTED IVORY — the design system Dr. Mona picked (Asana 1217846850268874,
   board "Stone Surgical Arts Website Redesign / 01 — Sculpted Ivory").

   The board publishes five colours and two typefaces. Those are reproduced here
   exactly, and everything else is derived from them.

     Ivory    #F6F4EF     Stone  #D8D3CA     Charcoal #272727
     Green    #8FBC46     White  #FFFFFF
     Cormorant Garamond (display) + Inter (body)

   THE ONE DELIBERATE DEVIATION — read before "fixing" it.

   Brand green is a light yellow-green. Measured against the palette's own
   grounds it gives:

     white text on #8FBC46 ............. 2.22:1   fails AA at every size
     #8FBC46 text on ivory ............. 2.02:1   fails AA at every size

   The board's button mock is white uppercase on green, which is the failing
   combination, at the smallest type on the page. This is a surgical practice
   whose previous site carried an /ada page, so the build does not ship it. Two
   named tokens carry the fix, and both keep the brand hue:

     --green-ink  #55731F   green taken dark enough to CLEAR AA as text
                            4.95:1 on ivory, 5.44:1 on white
     --btn-ink    charcoal  the label colour on a brand-green fill
                            6.72:1 on #8FBC46

   Buttons therefore stay brand green; their labels are charcoal, not white.
   Brand green is still used at full strength for fills, rules, icons and
   display-sized numerals, where contrast rules do not apply. If the client
   insists on white-on-green, change --btn-ink here — one line, whole site.
   =========================================================================== */
:root {
  /* --wide scales every text column and heading cap (`max-width` in rem or
     ch, written as calc(... * var(--wide))). 1 up to 1700px; 59-wide.css
     raises it for 2K and 4K so the columns keep their share of the screen
     instead of shrinking with it. Client, 2026-09-04: "these containers
     around text shrink too much on larger screens above 2K." */
  --wide: 1;
  /* --- the board's five, verbatim --- */
  --ivory: #f6f4ef;
  --stone: #d8d3ca;
  --charcoal: #272727;
  --green: #8fbc46;
  --white: #ffffff;

  /* --- derived --- */
  --ivory-deep: #efece4; /* the alternate band, half a step down from ivory */
  --stone-soft: #e7e3dc; /* hairlines and card edges on ivory */
  --green-ink: #55731f; /* text-sized green — clears AA, see above */
  --green-deep: #6f9433; /* hover on a green fill */
  --green-wash: #f0f5e5; /* the faintest green ground, for callouts */
  --charcoal-soft: #4a4a4a; /* body copy — softer than headings, still 8:1+ */
  --charcoal-mute: #6a6862; /* meta, captions, disabled */

  /* --- semantic layer. Sections paint from these names, never from a hex. --- */
  --bg: var(--ivory);
  --bg-alt: var(--ivory-deep);
  --bg-card: var(--white);
  --bg-deep: var(--charcoal);
  --fg: var(--charcoal);
  --fg-body: var(--charcoal-soft);
  --fg-mute: var(--charcoal-mute);
  --accent: var(--green-ink); /* accent AS TEXT */
  --accent-flat: var(--green); /* accent as a FILL or a RULE */
  --btn-ink: var(--charcoal); /* label on a brand-green fill */
  --line: var(--stone-soft);
  --line-strong: var(--stone);
  --focus: var(--green-ink);
  /* Scrim over photography so display type reads on any image. */
  --scrim: linear-gradient(180deg, rgba(39, 39, 39, 0.42) 0%, rgba(39, 39, 39, 0.12) 38%, rgba(39, 39, 39, 0.72) 100%);
  --scrim-side: linear-gradient(100deg, rgba(39, 39, 39, 0.66) 0%, rgba(39, 39, 39, 0.34) 42%, rgba(39, 39, 39, 0) 72%);

  /* --- type --- */
  --font-display: "Cormorant Garamond", "Cormorant", Georgia, "Times New Roman", serif;
  --font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;

  /* Type steps. Unitless multipliers stepped at Webflow's own breakpoints
     (1279 / 991 / 767 / 478) so the scale maps one-to-one onto Designer
     breakpoints, and onto Instatic's, at conversion time. Same technique as
     the Nahlah build — rem type, px media queries, one fluid root. */
  --t-display: 1;
  --t-heading: 1;
  --t-sub: 1;
  --t-text: 1;

  --size-h1: calc(4.75rem * var(--t-display));
  --size-h2: calc(3.25rem * var(--t-heading));
  --size-h3: calc(2.25rem * var(--t-heading));
  --size-h4: calc(1.625rem * var(--t-sub));
  --size-h5: calc(1.25rem * var(--t-sub));
  --size-h6: calc(1.0625rem * var(--t-sub));
  --size-text-large: calc(1.25rem * var(--t-text));
  --size-text-medium: calc(1.125rem * var(--t-text));
  --size-text-regular: calc(1rem * var(--t-text));
  --size-text-small: calc(0.875rem * var(--t-text));
  --size-text-tiny: calc(0.75rem * var(--t-text));

  /* --- Client-First spacing scale --- */
  --space-0: 0rem;
  --space-tiny: 0.125rem;
  --space-xxsmall: 0.25rem;
  --space-xsmall: 0.5rem;
  --space-small: 1rem;
  --space-medium: 2rem;
  --space-large: 3rem;
  --space-xlarge: 4rem;
  --space-xxlarge: 5rem;
  --space-huge: 6rem;
  --space-xhuge: 8rem;
  --space-xxhuge: 12rem;

  --radius: 2px; /* the board's cards are barely rounded, and squared at the top */
  --radius-card: 4px;
  --shadow-card: 0 1px 2px rgba(39, 39, 39, 0.04), 0 8px 24px rgba(39, 39, 39, 0.06);
  --shadow-card-hover: 0 2px 4px rgba(39, 39, 39, 0.06), 0 18px 44px rgba(39, 39, 39, 0.1);
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

@media (max-width: 1279px) {
  :root {
    --t-display: 0.82;
    --t-heading: 0.85;
    --t-sub: 0.92;
  }
}
@media (max-width: 991px) {
  :root {
    --t-display: 0.7;
    --t-heading: 0.76;
    --t-sub: 0.88;
  }
}
@media (max-width: 767px) {
  :root {
    --t-display: 0.56;
    --t-heading: 0.66;
    --t-sub: 0.84;
  }
}
/* Below 479 the root itself shrinks (16px at 479 -> 14px at 320). Display type
   wants that; body copy does not, so --t-text is raised to hold it above 16px. */
@media (max-width: 478px) {
  :root {
    --t-heading: 0.6;
    --t-sub: 0.82;
    --t-text: 1.1;
  }
}

/* The dark band — the invitation strip and the footer opt in with this, so a
   section can be flipped by the scope it sits in rather than by rewriting it. */
[data-theme="dark"] {
  --bg: var(--charcoal);
  --bg-alt: #1e1e1e;
  --bg-card: #333230;
  --fg: var(--white);
  --fg-body: rgba(255, 255, 255, 0.8);
  --fg-mute: rgba(255, 255, 255, 0.62);
  --accent: var(--green); /* on charcoal the brand green is 6.72:1 — fine as text */
  --accent-flat: var(--green);
  --line: rgba(255, 255, 255, 0.14);
  --line-strong: rgba(255, 255, 255, 0.28);
  --focus: var(--green);
  background-color: var(--bg);
  color: var(--fg-body);
}

/* ===== :root harvested from 50-journey.css ===== */
:root {
   
  --size-display: calc(6.9rem * var(--t-display));
  --size-display-sm: calc(4.75rem * var(--t-display));
  --size-numeral: calc(5.5rem * var(--t-display));
   
  --size-h3-j: calc(1.85rem * var(--t-heading));

   
  --gutter: max(clamp(1.25rem, 4vw, 4.5rem), calc((100vw - 97.5rem) / 2));
  --section: clamp(4rem, 7vw, 8.5rem);
  --section-sm: clamp(2.5rem, 4.5vw, 5rem);
  --pad-panel: clamp(1.75rem, 3.4vw, 4rem);
}

@media (max-width: 478px) {:root {
    --size-h3-j: calc(1.85rem * var(--t-sub));
  }}

/* ===== :root harvested from 51-dossier.css ===== */
:root {
   
  --spec-w: 20rem;
  --spec-top: 6.5rem;
}

@media (max-width: 1279px) {:root {
    --spec-w: 17rem;
  }}

/* ===== :root harvested from 58-breathe.css ===== */
:root {
  --section: clamp(4.75rem, 8.25vw, 10.5rem);
  --section-sm: clamp(3rem, 5.25vw, 6rem);
  --pad-panel: clamp(2rem, 3.8vw, 4.5rem);
}

:root {
  --ease-settle: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-cine: cubic-bezier(0.77, 0, 0.175, 1);
}

/* ===== :root harvested from 59-wide.css ===== */
@media (min-width: 1700px) {:root {
    --wide: 1.15;
  }}

@media (min-width: 2400px) {:root {
    --wide: 1.3;
  }}

/* from the deleted 35-gallery.css — dormant, see push-site.mjs */
.compare_component { --pos: 50%; }

/* ===== the cascade of every clamp()/min()/max() pair, from 21-drawer.css, see push-site.mjs ===== */
.drawer_panel { width: min(24rem, 88vw); }

/* ===== the cascade of every clamp()/min()/max() pair, from 38-cta.css, see push-site.mjs ===== */
.cta_media { height: min(60vh, 34rem); }
@media (max-width: 991px) { .cta_media { height: auto; } }

/* ===== the cascade of every clamp()/min()/max() pair, from 50-journey.css, see push-site.mjs ===== */
.arrival_component { min-height: clamp(32rem, 84vh, 54rem); }
@media (max-width: 991px) { .arrival_component { min-height: 0; } }
@media (max-width: 991px) { .arrival_media { width: min(28rem, 74%); } }
@media (max-width: 600px) { .arrival_media { width: 100%; } }
.path_panel { width: min(40rem, 86vw); }
.path_media { height: clamp(9rem, 27vh, 17rem); }
.ask_media { height: min(calc(100vh - 10rem), 34rem); }
@media (max-width: 991px) { .ask_media { height: auto; } }

/* ===== the cascade of every clamp()/min()/max() pair, from 51-dossier.css, see push-site.mjs ===== */
.dhero_component { min-height: clamp(30rem, 86vh, 50rem); }
@media (max-width: 767px) { .dhero_component { min-height: 0; } }

/* ===== the cascade of every clamp()/min()/max() pair, from 52-elevate.css, see push-site.mjs ===== */
.arrival_component { min-height: clamp(34rem, 92vh, 60rem); }
.ghost_word { font-size: clamp(6rem, 21vw, 22rem); }
.catalogue_media { height: min(calc(100vh - 9rem), 44rem); }
@media (max-width: 991px) { .catalogue_media { height: auto; } }
.strip_tile { height: clamp(13rem, 30vh, 21rem); }
.strip_tile.is-tall { height: clamp(16rem, 38vh, 26rem); }
.surgeon_frames { height: min(calc(100vh - 9rem), 46rem); }
@media (max-width: 991px) { .surgeon_frames { height: auto; } }
.concern_row { padding: clamp(1rem, 2vw, 1.6rem) 0; }
.concern_float { width: clamp(12rem, 20vw, 18rem); }
.proof_quotemark { font-size: clamp(8rem, 16vw, 15rem); }
.neon_component { height: clamp(22rem, 62vh, 42rem); }

/* ===== the cascade of every clamp()/min()/max() pair, from 53-hub.css, see push-site.mjs ===== */
.catx_band { min-height: clamp(26rem, 70vh, 40rem); }
.catx_word { font-size: clamp(3.5rem, 8vw, 8rem); }
.still_component { height: clamp(14rem, 38vh, 24rem); }
.hubfaq_media { height: min(calc(100vh - 12rem), 36rem); }
@media (max-width: 991px) { .catx_band { min-height: 0; } }
@media (max-width: 991px) { .hubfaq_media { height: auto; } }

/* ===== the cascade of every clamp()/min()/max() pair, from 54-profile.css, see push-site.mjs ===== */
.prof_hero { min-height: clamp(38rem, 96vh, 60rem); }
.prof_name { font-size: clamp(4.5rem, 19vw, 18rem); }
.prof_portrait { width: clamp(16rem, 32vw, 30rem); }
.why_component { min-height: clamp(24rem, 70vh, 40rem); }
.lead_component { height: clamp(22rem, 62vh, 40rem); }
@media (max-width: 991px) { .prof_hero { min-height: 0; } }
@media (max-width: 991px) { .prof_name { font-size: clamp(3.4rem, 15vw, 7rem); } }
@media (max-width: 991px) { .prof_portrait { width: min(22rem, 78%); } }

/* ===== the cascade of every clamp()/min()/max() pair, from 55-about.css, see push-site.mjs ===== */
.place_hero { min-height: clamp(30rem, 88vh, 52rem); }
.gallery_grid { grid-auto-rows: clamp(9rem, 18vw, 16rem); }
@media (max-width: 991px) { .gallery_grid { grid-auto-rows: clamp(9rem, 32vw, 14rem); } }

/* ===== the cascade of every clamp()/min()/max() pair, from 56-offers.css, see push-site.mjs ===== */
.consent_component { min-height: clamp(28rem, 80vh, 46rem); }

/* ===== the cascade of every clamp()/min()/max() pair, from 58-breathe.css, see push-site.mjs ===== */
.strip_tile { height: clamp(14rem, 34vh, 24rem); }
.strip_tile.is-tall { height: clamp(18rem, 44vh, 30rem); }
.path_media { height: clamp(11rem, 32vh, 20rem); }
.still_component { height: clamp(16rem, 44vh, 28rem); }
.prof_portrait { width: clamp(18rem, 34vw, 32rem); }

/* ===== the cascade of every clamp()/min()/max() pair, from 59-wide.css, see push-site.mjs ===== */
@media (min-width: 1700px) { .still_component { height: clamp(14rem, 26vw, 34rem); } }
@media (min-width: 1700px) { .neon_component { height: clamp(14rem, 26vw, 34rem); } }
@media (min-width: 1700px) { .lead_component { height: clamp(14rem, 26vw, 34rem); } }
@media (min-width: 1700px) { .concern_float { width: clamp(12rem, 14vw, 20rem); } }
@media (min-width: 1700px) { .dhero_component { min-height: clamp(30rem, 86vh, 56rem); } }
