/* =========================================================================
   MILLWAY DENTAL — v8 DESIGN SYSTEM
   White-first. The greens come from the logo and carry structure, not surface.

   Single source of truth. Nothing downstream hardcodes a colour, size,
   duration or easing.
   ========================================================================= */

@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@200;300;400;500;600;700;800&display=swap');

:root {
  /* =======================================================================
     1. COLOUR

     Every pair below was measured before it was used. The three brand
     colours behave very differently on white and the system encodes that:

       sage      #A0C078   2.04:1  — fails even large text. GRAPHIC ONLY.
       sage-deep #7D9B47   3.16:1  — large display accents only.
       deep      #0A2328  16.36:1  — the workhorse ink.
       leaf      #4A6B2A   6.13:1  — derived, so links and small accent
                                     text have a green that is legal.

     White on sage is 2.04:1, so a sage button with white text is
     unreadable. Primary buttons are deep green. Sage never sits behind
     type — it draws rules, nodes, fills and shapes.
     ======================================================================= */
  --white:      #FFFFFF;   /* the ground, and the point of the design */
  --deep:       #0A2328;   /* ink, dark surfaces, primary fill        */
  --deep-soft:  #17322F;
  --sage:       #A0C078;   /* logo green — graphics only              */
  --sage-deep:  #7D9B47;   /* large display accents only              */
  --leaf:       #4A6B2A;   /* the only green allowed to carry text    */

  /* Neutrals, tinted green so nothing on the page is a dead grey */
  --n-05: #F6F8F5;
  --n-10: #EEF1EC;
  --n-20: #DFE4DC;
  --n-40: #B3BBB1;   /* graphic only — 1.97:1, never carries text */
  /* The quietest tier that still carries text. It has to clear 4.5:1 on the
     tinted surface as well as on white, not just on white — at #6B7770 it
     measured 4.67:1 on white but only 4.37:1 on --surface-quiet, and the
     first tinted fold on the page failed the moment it existed.
     5.21:1 on white, 4.88:1 on --surface-quiet. */
  --n-50: #656F69;
  --n-60: #5F6A64;   /* 5.63:1 */
  --n-80: #3A4642;

  /* --- semantic ------------------------------------------------------- */
  --surface:       var(--white);
  --surface-quiet: var(--n-05);
  --surface-deep:  var(--deep);

  --ink:        var(--deep);
  /* Both of these carry small text, so both must clear 4.5:1 on white.
     An earlier pass pointed --ink-quiet at --n-40 (1.97:1) and --ink-mid at
     the old --n-60 (4.48:1); nine text pairs failed on that alone. Hierarchy
     is carried by size and weight instead of by illegible contrast. */
  --ink-mid:    var(--n-60);
  --ink-quiet:  var(--n-50);
  --ink-invert: var(--white);

  /* On the dark footer the ratios invert, and sage finally becomes legal for
     text: measured on --deep it is 8.03:1, against 2.04:1 on white. These are
     opaque on purpose — a translucent white would depend on whatever sits
     behind it, which is exactly how contrast bugs get missed. */
  --on-deep:     var(--white);   /* 16.36:1 on --deep */
  --on-deep-mid: #A9B4B0;        /*  7.66:1 on --deep */
  --on-deep-key: var(--sage);    /*  8.03:1 on --deep */
  --rule-invert: #24403F;        /* hairline on dark — graphic only */

  /* The rating gold. Outside the brand palette on purpose: five stars are a
     convention people read at a glance, and a sage star would not be one.
     Graphic only — it never carries type. */
  --star:        #E0A80E;

  /* Channel triplets. Every wash, shadow and gradient on the page was written
     as a raw rgba(), which is how two different darks ended up doing the same
     job — rgba(10,35,40,x) for shadows and rgba(6,23,27,x) for washes, with no
     way to see that from the declaration. Composing from these means a shadow
     is provably the same colour as the fill it belongs to. */
  --deep-rgb:  10, 35, 40;    /* == --deep  */
  --shade-rgb:  6, 23, 27;    /* the wash: a step under --deep, on purpose */
  --sage-rgb: 160, 192, 120;  /* == --sage  */
  --sage-deep-rgb: 125, 155, 71;
  --white-rgb: 255, 255, 255;
  --tint-open: #EDF3E4;       /* the open-now badge; --leaf on it is 5.71:1 */

  --rule:        var(--n-20);
  --rule-quiet:  var(--n-10);
  --graphic:     var(--sage);       /* fills, nodes, rules — never text */
  --accent-text: var(--leaf);       /* links, small accent copy         */
  --focus:       var(--leaf);

  /* =======================================================================
     2. TYPE — one family, full weight range.

     Everything is Plus Jakarta Sans. Scale, weight and tracking carry the
     hierarchy instead of a second typeface, which is what keeps a page this
     large feeling like one object.
     ======================================================================= */
  --font: 'Plus Jakarta Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-display: var(--font);
  --font-ui:      var(--font);

  /* The scale below --fs-body is where the drift was: twenty-two different
     literal sizes between 0.55rem and 1.24rem, in clusters four wide doing
     one job each — 0.55/0.56/0.58 all labelling a definition list, 0.9/0.92/
     0.95/0.98 all setting a card title. These nine steps absorb all of them,
     and no element moves by more than 0.04rem. */
  --fs-nano:    0.58rem;   /* dt labels, in-card meta          */
  --fs-micro:   0.68rem;   /* eyebrows, uppercase micro        */
  --fs-xs:      0.76rem;   /* link lines, chips, captions      */
  --fs-sm:      0.84rem;   /* the workhorse small text         */
  --fs-md:      0.94rem;   /* card titles, names               */
  --fs-body:    1rem;
  --fs-lg:      1.06rem;   /* sub-headings, standfirsts        */
  --fs-lead:    1.12rem;
  --fs-xl:      1.24rem;   /* the largest non-display size     */
  /* One fluid size for a card title. It was two near-identical ramps — the
     treatments card climbed at 1.5vw and the life-stage band at 1.8vw, same
     floor and same ceiling — so the two read as different sizes only in the
     middle of the range, which is the worst place for them to disagree. */
  --fs-card-t:  clamp(1.15rem, 1.6vw, 1.42rem);
  /* the hero word on a narrow screen, where --fs-hero's vw multiplier
     overshoots.

     The vw term is 9, not the 7.2 it started at: the headline was sitting
     at its 1.9rem floor on every phone from 320 to 480, so a 430px handset
     rendered it at the same size as a 320px one and it read small for the
     page's opening line.

     9vw is the largest multiplier that still keeps "Where Great Smiles" on
     ONE line — measured, not guessed. Line one needs 268px at 30.4px, so
     the wrap ceiling works out at ~9.9vw across 320-430px; 9vw leaves
     roughly 11% in hand for a fallback face rendering wider than the
     webfont. Above 480px the 2.7rem cap is reached exactly as before, so
     tablets and desktop are untouched. */
  --fs-hero-sm: clamp(1.9rem, 9vw, 2.7rem);

  --fs-d1: clamp(1.3rem,  1.1rem + 0.8vw, 1.6rem);
  --fs-d2: clamp(1.7rem,  1.3rem + 1.6vw, 2.4rem);
  --fs-d3: clamp(2.1rem,  1.4rem + 2.8vw, 3.4rem);
  /* d4 IS d3 now, deliberately, and this is an alias rather than a second
     clamp so the two can never drift apart again.

     They were two sizes doing one job. Measured across the homepage at
     1400px, fold-level h2s came out at three different sizes — 83.2px (d4)
     on five of them, 54.4px (d3) on three, 38.4px (d2) on one — for
     headings that are all the same thing: the title of a section. Worse,
     the split is not even per-page: the reviews and visit folds are shared
     markup pasted into eleven templates, so "What patients enjoy about
     their experience" rendered at d4 while the CTA heading directly above
     it rendered at d3 on every one of those pages.

     Collapsing onto d3's ramp rather than d4's, because 83.2px was also
     crowding the hero — --fs-hero tops out around 127px, and a section
     head at two thirds of the page's own headline reads as competing with
     it rather than sitting under it. At 54.4px the order is unambiguous.

     The token is kept (not deleted) because `display d4` appears in eleven
     templates' markup; aliasing fixes every one of them without touching
     a single template file. */
  --fs-d4: var(--fs-d3);
  /* the hero word: sized to span the page, not the column.
     "Where Great Smiles Take Shape." now renders as two independently
     positioned lines (.hero-word-line--top/--bottom in folds.css), not one
     nowrap string, so width is sized against the LONGER of the two —
     "Where Great Smiles" — rather than the full phrase.

     The binding constraint turned out not to be width at all: it's the
     vertical gap between the fixed header and the specimen's own top edge
     (and the matching gap below the specimen before .hero-foot). Each line
     sits mostly OUTSIDE the specimen — only --word-bite of it is allowed to
     overlap — so this had to be sized against that gap, measured directly
     rather than derived (--tooth-h, the header's clamp() and this font's
     clamp() all move at different rates, so hand arithmetic kept being wrong
     by exactly the margin that mattered). See --fs-hero's max-height:900px
     override below for the short-viewport case, sized the same way. */
  --fs-hero: clamp(2.2rem, 9.9vw, 9.15rem);

  --track-display: -0.03em;
  --track-hero:    -0.045em;
  /* between display and body: names, card titles, the wordmark */
  --track-tight:   -0.015em;
  --track-micro:   0.19em;   /* eyebrows — the widest, and the loudest */
  --track-label:   0.15em;   /* uppercase labels inside a card         */

  --lh-display: 1.04;
  --lh-tight:   1.18;
  --lh-body:    1.68;

  --measure: 62ch;

  /* =======================================================================
     3. SPACE — 8px baseline
     ======================================================================= */
  --sp-1: 0.5rem;  --sp-2: 1rem;   --sp-3: 1.5rem;  --sp-4: 2rem;
  --sp-5: 3rem;    --sp-6: 4rem;   --sp-7: 6rem;    --sp-8: 8rem;

  --fold:      clamp(5rem, 9vw, 9rem);
  --fold-wide: clamp(7rem, 13vw, 13rem);

  --page:  1360px;
  --gutter: clamp(1.25rem, 4vw, 4.5rem);

  /* =======================================================================
     4. MOTION — one curve, three speeds. Every fold moves the same way,
     which is what makes separate sections read as one film.
     ======================================================================= */
  --ease:      cubic-bezier(0.16, 1, 0.3, 1);
  --ease-soft: cubic-bezier(0.33, 0, 0.15, 1);
  --t-1: 0.32s;
  --t-2: 0.62s;
  --t-3: 0.95s;
  /* the reveal speed. Longer than --t-3 on purpose: a fold arriving after the
     stage hands over needs to settle, not snap into place. */
  --t-4: 1.35s;

  /* Nine radii were in use — 2, 3, 4, 10, 12, 14, 16, 999 and 50%. Three
     shapes is the whole vocabulary: an almost-square edge, a card, a pill. */
  --r-sm:   3px;
  --r-md:   14px;
  --r-pill: 999px;

  --hair: 1px;
}

@media (prefers-reduced-motion: reduce) {
  :root { --t-1: 1ms; --t-2: 1ms; --t-3: 1ms; }
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
}
