/* Graham Piano Tuning — brand tokens. One-file rebrand: every page reads these.
   Drop into the scaffold as public/css/tokens.css and link before styles.css. */
/* TWO FAMILIES, THREE JOBS. The Libre pair were drawn to sit together, so
   the pairing does most of the work on its own.
     Libre Baskerville   headings and prices. A sturdy text Baskerville with
                         a large x-height, which is why it stays readable at
                         sizes where a display serif would start to thin out.
                         It is WIDE: headings run longer than they used to,
                         and the type scale below is cut to allow for it.
     Libre Franklin      everything else. Body, buttons, forms, and the small
                         capital labels at 600 with wide letterspacing. One
                         family doing two jobs, separated by weight and size
                         rather than by a third typeface.
   Swapping either is this line plus its --font-* token below. Nothing else
   in the codebase names a typeface, and a test fails if that changes. */
@import url('https://fonts.googleapis.com/css2?family=Libre+Baskerville:wght@400;700&family=Libre+Franklin:wght@400;500;600;700&display=swap');

:root {
  /* ── Colour ───────────────────────────────────────────────────────────────
     NAVY AND TAN. Six colours Michael picked, plus a ground, because a page
     has to sit on something and the six did not include one: Fog lifted
     almost to white on the same hue, so it belongs to the set rather than
     being borrowed.

         navy  #071739   the ink, and the dark bands
         slate #4b6382   the accent: kickers, links, quiet borders
         mist  #a4b5c4   dividers, and body text on navy (8.4:1 there)
         fog   #cdd5db   surfaces, and the text of any dark band (11.9:1)
         tan   #a68868   a FILL, never small text on light (3.08:1)
         sand  #e3c39d   the warm note inside a dark band (10.6:1 on navy)

     THE RULE THAT MATTERS: only navy and slate can carry small text on a
     light ground. Tan, mist, fog and sand are fills here and text on navy.
     Putting a price in tan on the ivory would be 3:1 and unreadable in a
     car, which is where a lot of this gets read. */
  --color-bg: #f4f7fa;
  --color-surface: #e9eef1;
  --color-text: #071739;
  --color-accent: #4b6382;
  --color-divider: color-mix(in srgb, #071739 18%, transparent);

  /* The palette by name, for the few places that want the colour itself
     rather than a step on a ramp. */
  /* The one secondary-text colour. Slate rather than a neutral grey, because
     a grey is where Windows subpixel fringing shows worst; see .text-muted
     in style.css. 6.2:1 on the page ground. */
  --color-muted: #425e82;
  --color-navy: #071739; --color-slate: #4b6382; --color-mist: #a4b5c4;
  --color-fog: #cdd5db;  --color-tan: #a68868;   --color-sand: #e3c39d;

  /* The one button that has to win. Navy, because at 16:1 nothing else on
     the page can shout louder than it. */
  --color-cta: #071739; --color-cta-hover: #132a56;

  /* Cool neutrals, cut on Fog's hue: a generic grey beside a navy reads
     dirty, and these do not. */
  --color-neutral-100: #f1f4f6; --color-neutral-200: #e0e3e6; --color-neutral-300: #c8cdd0;
  --color-neutral-400: #abb0b4; --color-neutral-500: #888f93; --color-neutral-600: #70777c;
  --color-neutral-700: #575d62; --color-neutral-800: #3f4448; --color-neutral-900: #292d30;

  /* Accent ramp, built on slate. 700 is 6.2:1 on the ground, so it is the
     lowest step that may carry small text. */
  --color-accent-100: #e7f5ff; --color-accent-200: #d4e5fb; --color-accent-300: #bacee9;
  --color-accent-400: #99b2d1; --color-accent-500: #7390b5; --color-accent-600: #5878a1;
  --color-accent-700: #425e82; --color-accent-800: #2e4562; --color-accent-900: #1c2d44;

  /* Warm ramp, built on tan. Same rule: 700 and darker for text. */
  --color-warm-100: #fff1e0; --color-warm-200: #f3dfcc; --color-warm-300: #dfc8b0;
  --color-warm-400: #c6aa8d; --color-warm-500: #a78764; --color-warm-600: #926e47;
  --color-warm-700: #745533; --color-warm-800: #573e21; --color-warm-900: #3c2811;

  /* ── One accent per service tile ──────────────────────────────────────────
     Five colours, none chosen by eye: each sits at the same lightness and
     chroma as the slate accent with only the hue moved, which is why no
     tile shouts louder than the one beside it. Every -deep clears 8:1 on
     the ground, so a price or a kicker set in one is readable anywhere.

     GREEN IS DELIBERATELY ABSENT. It means "Michael is already near you" on
     the booking calendar, and a green service tile would make the calendar
     stop meaning anything.

     -base  the top border and the tick boxes
     -deep  the kicker and the price
     -tint  the wash behind a card's list */
  --tile-1: #4d6b91; --tile-1-deep: #2e496b; --tile-1-tint: #e7f1ff; --tile-1-900: #0d2139;   /* slate */
  --tile-2: #84613b; --tile-2-deep: #5f401c; --tile-2-tint: #faeee2; --tile-2-900: #311b00;   /* tan   */
  --tile-3: #2f757c; --tile-3-deep: #055259; --tile-3-tint: #e1f5f7; --tile-3-900: #00272c;   /* teal  */
  --tile-4: #8b5b49; --tile-4-deep: #663b2a; --tile-4-tint: #fdece5; --tile-4-900: #35170a;   /* clay  */
  --tile-5: #88586d; --tile-5-deep: #63384b; --tile-5-tint: #fcebf1; --tile-5-900: #331523;   /* plum  */

  /* "Michael is already near you" on the booking calendar. Re-cut cool for
     this palette; the old one was mixed against brass and read sour here.
     Deliberately outside the tile accents: if a service tile were green too,
     the calendar would stop meaning anything. */
  --color-near: #457650; --color-near-100: #e3f6e6; --color-near-800: #245330;

  /* type — thick classical serif headings, readable sans body, 18px preferred */
  --font-heading: "Libre Baskerville", Georgia, "Times New Roman", serif;
  --font-heading-weight: 700;
  --font-body: "Libre Franklin", system-ui, -apple-system, sans-serif;
  /* Same family as the body, held apart by weight, size and letterspacing.
     A label is a role, not a typeface. */
  --font-label: "Libre Franklin", system-ui, -apple-system, sans-serif;
  --font-label-weight: 600;
  --font-size-body: 18px;
  --font-size-min: 16px;

  /* spacing (1.15x density) */
  --space-1: 4.6px; --space-2: 9.2px; --space-3: 13.8px;
  --space-4: 18.4px; --space-5: 23px; --space-6: 27.6px; --space-8: 36.8px;
  /* --space-5 WAS MISSING, and three rules asked for it anyway. A var() that
     names a token that does not exist does not fall back to anything sensible:
     it makes the whole declaration invalid, so padding: var(--space-4)
     var(--space-5) was computed as no padding at all. That is why the
     "this opens Google in a new tab" box had its text touching its edges.
     test/site.test.js now fails if style.css names a token nobody defined. */

  /* radius + elevation */
  --radius-sm: 2px; --radius-md: 4px; --radius-lg: 7px;
  /* SHADOWS ARE TINTED NAVY, NOT GREY. A grey shadow under a navy-and-tan
     card is the difference between cheap and considered: light in a room
     with navy in it does not cast a neutral shadow, and the eye knows.
     Two layers each, a tight one for the edge and a wide one for the lift,
     which is what stops a shadow looking like a smudge. */
  --shadow-sm: 0 1px 2px color-mix(in srgb, #071739 10%, transparent),
               0 2px 6px  color-mix(in srgb, #071739 6%,  transparent);
  --shadow-md: 0 1px 2px color-mix(in srgb, #071739 8%,  transparent),
               0 6px 18px color-mix(in srgb, #071739 12%, transparent);
  --shadow-lg: 0 2px 4px  color-mix(in srgb, #071739 8%,  transparent),
               0 18px 44px color-mix(in srgb, #071739 18%, transparent);

  /* accessibility floors */
  --tap-target-min: 48px;
}
