/* ==========================================================================
   Melbourne Echo Clinic - Design tokens
   --------------------------------------------------------------------------
   Single source of colour and font-family truth for the whole site.
   Derived from design-system.md. Do not hard-code hex values or font stacks
   anywhere else - reference these custom properties by name.

   If a component needs a value that isn't here, pause and ask before adding.
   ========================================================================== */

/* ==========================================================================
   Self-hosted webfonts
   --------------------------------------------------------------------------
   THESE FILES ARE SERVED FROM OUR OWN DOMAIN ON PURPOSE. Until 2026-08-23 the
   same two families came from Google Fonts via a <link> in every page's <head>,
   which sent every visitor's IP address, user-agent and current page URL to a
   third party before a single word rendered. A privacy audit on 2026-08-23
   found it was the largest disclosure the site made and the only one present on
   all 15 pages. The site's privacy policy makes a factual claim about this.

   DO NOT REPLACE THIS WITH A GOOGLE FONTS <link>. A build guard in build.js
   fails the build if an external font URL reappears in dist/. Provenance,
   licensing and the re-download procedure are in assets/fonts/README.txt.

   ONE FILE PER FAMILY PER SUBSET, NOT ONE PER WEIGHT. Both families are
   VARIABLE fonts spanning 400-700 in a single file, so `font-weight: 400 700`
   below covers every weight the site uses (Instrument Sans at 600 and 700,
   Inter at 400, 500, 600 and 700). Adding a weight costs nothing and needs no
   new file.

   NO ITALIC FACE IS LOADED, deliberately. Every <em> on the site renders
   upright - a serif or italic emphasis tier has been tried and withdrawn three
   times (see base.css) and .display em sets font-style: normal. Verified
   2026-08-23 by computing the style of all 43 <em> elements across all 15
   pages: none italic. A browser asked for italic here now synthesises a slant
   rather than loading a real one, so nothing breaks; but if a genuine italic is
   ever wanted it is a new file, not a CSS change.

   THE latin-ext FACES COST NOTHING UNTIL THEY ARE NEEDED. unicode-range means
   a browser downloads a subset only if the page actually contains a character
   in it. Every character on the site today is inside latin, so visitors fetch
   78KB, not 174KB. latin-ext is insurance for a future patient name, suburb or
   host practice with an accent, which would otherwise silently render in a
   fallback face. The ranges below are Google's own, copied verbatim - do not
   hand-trim them.

   font-display: swap IS LOAD-BEARING. main.js corrects deep-link scroll
   position off document.fonts.ready; `block` or `optional` changes when that
   promise settles relative to first paint. Leave it alone.
   ========================================================================== */

/* Instrument Sans - display */
@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/instrument-sans-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/instrument-sans-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Inter - body */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* ---------------------------------------------------------------------
     Primary blues
     --------------------------------------------------------------------- */

  /* Primary brand colour - logo, links, section accents, non-hero CTAs.

     Was #4A82AA until 2026-08-11. Changed on request: the old value was a
     dusty mid-blue that read as washed out beside the black headline text.

     Both values below are the LIVE SITE'S, read out of the CSS served by
     melbourneechoclinic.com.au/for-practices rather than sampled from a
     screenshot, so there is no JPEG or colour-profile drift in them.

     The swap also fixes an accessibility defect rather than just a taste one:
       #4A82AA on --paper = 3.97:1  → FAILS WCAG AA for normal text (needs 4.5)
       #006EDF on --paper = 4.67:1  → passes for normal and large text
     base.css used to carry a caveat that the old blue was "safe here solely
     because .display is large". That caveat is gone; this blue is safe at
     body size too.

     Worth knowing if you ever revisit this: against --ink the new blue has
     LESS luminance separation than the old one (3.46 vs 4.08). What makes it
     read as brighter is saturation, not lightness. Don't "improve" it by
     lightening - that trades the chroma away and lands back at #4A82AA. */
  --mec-blue: #006EDF;

  /* Hover/pressed states, dark UI elements, deeper blue backgrounds.
     Was #2A5A80. #0056AE is the live site's deeper step and performs almost
     identically on contrast (6.83:1 vs 6.99:1 on --paper) while staying in
     the same hue family as --mec-blue, which #2A5A80 did not. */
  --mec-blue-deep: #0056AE;

  /* Dark editorial backgrounds (Heart Week campaign aesthetic), footer,
     link hover.

     Was #1F3A52 until 2026-08-11, from the same pre-live-site guesswork as the
     old blues. #002244 is the live site's navy, and it sits at hue 210° at full
     saturation - the SAME hue as --mec-blue, where #1F3A52 was 208° at 45%.
     That is what turns four separate blues into one ramp:
       --mec-blue-soft  h210 l95%
       --mec-blue       h210 l44%
       --mec-blue-deep  h210 l34%
       --mec-navy       h210 l13%
     White on it improves from 11.76:1 to 16.00:1. */
  --mec-navy: #002244;

  /* Very light blue backgrounds and panels; also the footer's body text colour.

     DERIVED, not a literal, since 2026-08-11. Was #E8F0F5 - hue 203° at 39%
     saturation, which read grey rather than blue once --mec-blue became vivid.

     Mixing from --mec-blue rather than hard-coding the result means this tint
     can never drift out of family again: change the blue and the tint follows.
     The computed value is ~#E6F1FC (hue 210°, 79% saturation).

     Worth recording, because it is the reason this is not simply the live
     site's own tint: melbourneechoclinic.com.au uses #EAF5FA, which measures
     hue 199° - FURTHER from the primary than the value being replaced. The
     live site is authoritative for brand colours, not for derived tints.

     Both of this token's roles were checked before the change, not just the
     obvious one. As a panel background: ink 14.78:1, links 6.24:1. As footer
     text on --mec-navy: 13.99:1, up from 10.20:1.

     One trap: --mec-blue as TEXT on this tint is only 4.27:1, under the 4.5
     floor. Panels on this background use --mec-blue-deep (6.24:1) for links.
     Don't put the primary blue on it at body size. */
  --mec-blue-soft: color-mix(in srgb, var(--mec-blue) 10%, var(--white));

  /* Pattern A's emphasis colour. Confirmed 2026-08-10 from the live site's
     CSS (/about → .blue-line { color: #006EDF }), superseding the #2551E0
     placeholder in design-system.md.

     ALIASED, NOT DUPLICATED, since 2026-08-11. Pattern A and Pattern B used
     to take deliberately different blues, and base.css carried a guard rail
     to stop Pattern B's blue leaking into a Pattern A headline. Now that
     --mec-blue IS #006EDF that distinction has nothing left to express: the
     live site uses one blue, and two blues this close apart were a difference
     only we could see. Kept as a name because "signal" still describes the
     Pattern A role, and because the token is referenced in five places.
     Write it as an alias so the two can never silently drift apart. */
  --signal-blue: var(--mec-blue);

  /* ---------------------------------------------------------------------
     Neutrals
     --------------------------------------------------------------------- */

  /* Default page background. Third value; the history matters.

     #FAFAF7 until 2026-08-12 - hue 60°, a warm off-white, while every brand
     colour here is hue 210. That mismatch was the single reason the palette read
     as "not cohesive": the blue was a guest on a faintly beige page.

     #F8FBFF until 2026-08-13 - hue 214°, the prototype's own --surface. It fixed
     the hue clash, but at 1.04:1 from white it was doing no visible work. A tint
     that cannot be seen is not a tint; it is just a number that constrains
     everything layered on top of it.

     #FFFFFF now, on request. The reasoning holds either way: the page is the
     neutral ground and the blue belongs to the SECTIONS - navy bands,
     --band-tint alternates, --mec-blue-soft panels - which is where it can
     actually be seen. Going to true white makes each of those read slightly
     stronger, not weaker, because each one now has a fraction more separation
     to work against.

     Contrast: everything improves, nothing regresses.
       ink 16.30 -> 16.91   ink-soft 8.06 -> 8.37    ink-mute 3.14 -> 3.26
       blue 4.71 -> 4.89    blue-deep 6.88 -> 7.14   navy 15.42 -> 16.00
     ink-mute stays large-text-only, exactly as before.

     THE ONE THING THAT LOSES: a --white card on this background is now 1.00:1,
     i.e. the fill separates it from the page not at all. .location-card and
     .nav-card survive that only because they carry a --rule border AND
     --shadow-sm (added 2026-08-13). Do not strip either from a white surface
     sitting on the page - the fill is no longer a fallback. Any NEW white card
     needs the same two properties or it will be invisible. */
  --paper: #FFFFFF;


  /* Alternate section background.

     REJECTED 2026-08-12: this was --cream #F5F1EA, a warm oat tone, and it was
     used for exactly one thing - the alternating bands on For Patients - for
     about a day before being pulled. The objection was that it broke the
     palette: every other colour on this site is hue 210, and dropping a hue-38
     warm neutral next to them made the blue read as a stray accent on a beige
     page rather than as the brand.

     The replacement is derived from --mec-blue at 6%, so it can never drift out
     of family. It computes to ~#F0F6FD, which is within a point of the
     prototype's own --blue-pale #F0F7FF.

     Know what this token can and cannot do. Every light blue in the range
     #FFFFFF–#E6F1FC sits within 1.10:1 of every other one, so band-on-band
     alternation is inherently a WHISPER, not a statement - it separates
     sections but it will never be the thing that makes a page look designed.
     If more impact is wanted, the answer is a dark navy band, not a stronger
     tint: pushing this token darker only starts eating the contrast that
     --mec-blue-soft panels need to stay visible on top of it. */
  --band-tint: color-mix(in srgb, var(--mec-blue) 6%, var(--white));

  --ink: #1A1D21;        /* Primary body text */
  --ink-soft: #4A4E54;   /* Secondary text, captions */
  --ink-mute: #8A8F96;   /* Tertiary text, disabled states, eyebrow labels */
  /* Dividers, card borders, hairline separators.

     Was #E5E3DC, hue 47° - a warm grey. Same problem as --paper, and more
     visible, because a hairline sits directly against blue-tinted surfaces in
     twelve places. #D4E9F7 is hue 204° and is the prototype's --border.

     Hairline visibility is essentially unchanged: 1.23 -> 1.20 against --paper
     and 1.28 -> 1.25 against a white card. Both are still above the ~1.2 needed
     for a 1px edge to be perceptible. Do not push this darker to "fix" a border
     that looks faint - a faint border is the intent, and 1.4.11's 3.0 floor
     does not apply to decorative dividers. */
  --rule: #D4E9F7;
  --white: #FFFFFF;      /* Card interiors, form backgrounds */

  /* ---------------------------------------------------------------------
     Accents
     --------------------------------------------------------------------- */

  /* Small dot bullets, eyebrow labels for emphasis, urgent callouts */
  --accent-red: #C93C3C;

  /* Occasional use - anatomical illustration warmth, feature graphics */
  --accent-warm: #E88860;

  /* Second accent, added 2026-08-13 with the navy sections. The prototype's
     --teal. Hue 191° - the only token outside the 210° family, and deliberately
     so: it is what stops a navy section reading as one flat wash of blue.

     STRICTLY DECORATIVE ON NAVY, and this is measured, not cautious. Against the
     lightest point of a .band--navy (the ramp's #003A7A midpoint under the blue
     radial glow) it is 2.69:1 - below the 4.5 text floor AND below the 3.0
     non-text floor of WCAG 1.4.11. So on navy it may be a glow, a gradient stop
     or a hairline connector, but never a link, a label, an icon that carries
     meaning, or a focus ring. Text and UI on navy use --white (8.77:1 worst
     case) or --mec-blue-soft (7.67:1).

     It behaves completely differently on light backgrounds - as a button fill it
     takes --ink at 5.18:1 - but it does NOT take white (3.27:1). If you reach
     for it, check which side of that line you are on. */
  --sky: #0099CC;

  /* The accent when it has to be READ on navy - eyebrow labels, small captions.
     Exists because the rule above was broken within an hour of being written:
     --sky went straight onto a .band--navy eyebrow, which is text, at 2.69:1.

     50% is not a round number picked for tidiness, it is the first step that
     clears AA. Measured against the band's worst-case point (#004996, the ramp
     midpoint under the blue glow):
       100% #0099CC  2.69  fail      60% #66C2E0  4.33  fail (close, still no)
        80% #33ADD6  3.38  fail      50% #80CCE6  4.89  PASS
        70% #4DB8DB  3.84  fail      40% #99D6EB  5.50  PASS
     Computes to ~#80CCE6, hue 195° - still visibly the teal accent rather than
     another 210° blue, which is the entire reason for not just using
     --mec-blue-soft (7.67:1) and dropping the accent.

     Mixed rather than hard-coded so it tracks --sky if that ever changes.
     ONLY valid on navy. On light backgrounds it is far too pale to be text. */
  --sky-on-navy: color-mix(in srgb, var(--sky) 50%, var(--white));

  /* ---------------------------------------------------------------------
     Elevation
     ---------------------------------------------------------------------
     Tinted with --mec-navy rgb(0,34,68) rather than pure black. A neutral-black
     shadow on a blue-tinted surface greys the surface underneath it; a navy one
     reads as depth in the same hue family. Same reasoning as the neutrals.
     --------------------------------------------------------------------- */

  --shadow-sm: 0 2px 16px rgba(0, 34, 68, 0.07);
  --shadow-md: 0 4px 24px rgba(0, 34, 68, 0.10);
  --shadow-lg: 0 8px 28px rgba(0, 34, 68, 0.14);

  /* ---------------------------------------------------------------------
     Blue glow - the site-wide card and framed-media edge
     ---------------------------------------------------------------------
     THIS IS NOT ELEVATION AND MUST NOT BE MERGED WITH --shadow-*. The
     --shadow-* set above is navy depth: it says "this object is above the
     page". This is a blue lift: it says "this object belongs to the brand".
     They are different jobs and the note above --shadow-sm about sharing a
     token between two roles applies exactly here - if these ever collapse
     into one token, one of the two uses is wrong.

     Adopted broadly on 2026-08-15 by request, replacing the
     `1px solid var(--rule)` + `var(--shadow-sm)` pairing most cards carried.
     It descends from .team-member__media, which was lifted verbatim from the
     live site's .echo-box-prominent - so the value is the live site's own,
     not a new invention.

     IT IS NOT ON EVERYTHING, and that is settled rather than pending. Later the
     same day .check-list li, .table-scroll and .arrow-link were reverted to the
     old pairing on request. Each keeps a note saying why. Do not "finish the
     rollout" by giving them the tokens - the rollout is finished. Current
     consumers: .pillar, .loc-chip, .location-card, .nav-card, .dl-card,
     .map-frame, .about-hero__media, .location-hero__media, .team-member__media.

     TOKENS RATHER THAN ONE SHARED :is() RULE, deliberately. An :is() list takes
     the specificity of its most specific argument, so a single rule covering
     every card would have inherited the highest one in the list and started
     beating rules it has no business beating. Tokens change no specificity
     anywhere - each component keeps the exact cascade position it already had,
     which is also why pulling three components back out was a three-line edit.

     The shadow's first layer is zero-offset and zero-spread: diffuse, so it
     reaches all four edges of a wide element, and with no edge of its own. A
     hard spread ring was tried and rejected - see .map-frame in styles.css.

     color-mix of --signal-blue, so no new hex enters the palette. If
     color-mix is unsupported both declarations drop and cards render flat,
     which is a degradation and not a break. */
  --glow-border: color-mix(in srgb, var(--signal-blue) 25%, transparent);
  --glow-shadow:
    0 0 24px color-mix(in srgb, var(--signal-blue) 14%, transparent),
    0 12px 30px color-mix(in srgb, var(--signal-blue) 12%, transparent);

  /* ---------------------------------------------------------------------
     Semantic
     --------------------------------------------------------------------- */

  --success: #3A8A5F;    /* Confirmation messages, form success */
  --warning: #C68B2E;    /* Warnings, non-critical notices */

  /* Errors, form validation failures - deliberately aliased rather than
     duplicated, so the two can never drift apart */
  --error: var(--accent-red);

  /* ---------------------------------------------------------------------
     Font families
     --------------------------------------------------------------------- */

  /* Display - hero headlines and section titles, weight 700 */
  --font-display: 'Instrument Sans', system-ui, sans-serif;

  /* Instrument Serif. CURRENTLY UNUSED - nothing references this token.

     It has now been tried three times and withdrawn three times, for the same
     reason each time: it reads as a second voice rather than as the same brand
     speaking louder.

       - Until 2026-08-10 it was Pattern B's italic emphasis face. Removed
         because an italic phrase mid-sentence read as a different voice rather
         than as emphasis. Reasoning is in base.css under Pattern B.
       - On 2026-08-13 it came back as a large-display tier via a
         --font-display-lg alias, covering hero titles, section titles and the
         CTA panel title. Withdrawn the same day on request: headings are to
         match the rest of the site.
       - On 2026-08-15 it returned as .display--editorial ("Pattern C") on the
         /for-patients h1. Withdrawn the same day when that headline went back
         to Pattern B.

     The alias token is gone with it rather than left dangling at zero
     references. THE FAMILY IS NO LONGER DOWNLOADED AT ALL: since 2026-08-23 the
     fonts are self-hosted (see the @font-face block at the top of this file) and
     Instrument Serif was deliberately not among the files brought across, since
     shipping it would mean serving a font that renders nothing. Re-trying a
     serif display face now costs a font file as well as a token and a rule -
     read the three paragraphs above, and design-system.md, before you do.

     Do not reintroduce it as an inline emphasis face. That use is settled. */
  --font-serif: 'Instrument Serif', Georgia, serif;

  /* Body - body copy, UI text, form labels, navigation */
  --font-body: 'Inter', system-ui, sans-serif;

  /* ---------------------------------------------------------------------
     Spacing
     ---------------------------------------------------------------------
     4px base step. design-system.md specifies section padding of 80–120px
     on desktop but no scale; --space-section sits mid-range at 96px and
     drops to 56px on mobile (see base.css media query).
     --------------------------------------------------------------------- */

  --space-3xs: 0.25rem;  /*  4px */
  --space-2xs: 0.5rem;   /*  8px */
  --space-xs: 0.75rem;   /* 12px */
  --space-sm: 1rem;      /* 16px */
  --space-md: 1.5rem;    /* 24px */
  --space-lg: 2rem;      /* 32px */
  --space-xl: 3rem;      /* 48px */
  --space-2xl: 4rem;     /* 64px */
  --space-3xl: 6rem;     /* 96px */

  --space-section: var(--space-3xl);

  /* Layout */
  --container-max: 1180px;
  --radius: 10px;
  --radius-lg: 16px;
}
