﻿/**
 * One palette for every page, in three skins.
 *
 * The tokens used to be pasted into each page's own <style>, which meant six
 * copies to keep in step and, worse, a few dozen colours written straight into
 * the rules as rgba(255,255,255,.05). Those only work over a dark background:
 * the moment a light theme exists they turn cards invisible. So every surface,
 * line and shadow now has a name, and each theme says what that name means.
 *
 * Adding a theme means filling in the same list of names. Nothing else.
 */

/* ------------------------------------------------------------------ tokens */

/*
 * Parlour. A barber's back room: walnut, brass and cream.
 *
 * Brass is the accent, so amber cannot also mean "no-show" - that warning is
 * burnt orange here, which reads as a problem next to gold rather than as more
 * gold. Text on a brass button is near-black, because cream on brass is barely
 * four points of contrast and unreadable at a glance.
 */
:root,
[data-theme="parlour"] {
  color-scheme: dark;

  --bg: #15100c;
  --panel: rgba(38, 29, 22, .74);
  --popup: #221a13;

  --ink: #f4ece0;
  --ink-dim: #c7b6a2;
  --ink-faint: #9a8b78;

  --accent: #c8963e;
  --accent-2: #8f6420;
  --on-accent: #1e1509;

  --good: #6fbf8b;
  --warn: #e0653c;
  --bad: #d9544a;

  --line: rgba(240, 220, 190, .14);
  --line-soft: rgba(240, 220, 190, .09);
  --line-strong: rgba(240, 220, 190, .30);

  --surface: rgba(255, 240, 220, .035);
  --surface-2: rgba(255, 240, 220, .018);
  --surface-hover: rgba(255, 240, 220, .09);
  --surface-strong: rgba(255, 240, 220, .12);
  --field: rgba(255, 240, 220, .05);

  --shadow: rgba(0, 0, 0, .55);
  --glow: rgba(200, 150, 62, .10);

  /* One hue per barber, carried through every view. Amber and green are
     deliberately absent: those two mean no-show and completed. */
  --barber-1: #7fa8d4;
  --barber-2: #a98bd4;
  --barber-3: #5fb8b0;
  --barber-4: #d98fa8;
  --barber-5: #8f96d9;
  --barber-6: #cf9070;

  --font-display: Georgia, 'Iowan Old Style', 'Palatino Linotype', ui-serif, serif;
  --font-body: Inter, system-ui, sans-serif;
  /* The three the shopfront uses, and only the shopfront.
     A face chosen to look like a barbershop above the door is not one anybody
     can read a diary in all day, so these are kept out of --font-display
     deliberately: sign is the shop's name, quote is its tagline, label is the
     small upper-case headings over each section. */
  --font-sign: 'Playfair Display', Georgia, ui-serif, serif;
  --font-quote: 'Playfair Display', Georgia, ui-serif, serif;
  --font-label: Inter, system-ui, sans-serif;
}

/*
 * Linen. Warm paper and a deep green, for a shop that wants daylight.
 *
 * The overlays invert in role rather than in value: a raised card on cream is
 * whiter than its background, while a hover is a green tint pressed into it.
 * Reusing the dark theme's arithmetic here would produce white-on-white.
 */
[data-theme="linen"] {
  color-scheme: light;

  --bg: #f2efe6;
  --panel: rgba(253, 251, 244, .90);
  --popup: #fffdf8;

  --ink: #2a2620;
  --ink-dim: #55503f;
  /* Darker than the dark themes' equivalent. The same lightness that reads as
     "quiet" against walnut is simply hard to read against paper, and this tone
     carries phone numbers and buffer times that people actually need. */
  /* Nudged until it reads: at #756e60 this was 4.40:1 on linen's paper, just
     under the 4.5:1 floor, and these are the labels telling somebody what a
     field is for. `npm run check:contrast` holds every theme to it. */
  --ink-faint: #696255;

  --accent: #2f5d4a;
  --accent-2: #24483a;
  --on-accent: #f7f5ee;

  --good: #3f7d52;
  --warn: #b06a1f;
  --bad: #a83f39;

  --line: rgba(62, 54, 40, .16);
  --line-soft: rgba(62, 54, 40, .09);
  --line-strong: rgba(62, 54, 40, .34);

  --surface: rgba(255, 255, 255, .72);
  --surface-2: rgba(255, 255, 255, .42);
  --surface-hover: rgba(47, 93, 74, .09);
  --surface-strong: rgba(47, 93, 74, .14);
  --field: #fffdf8;

  --shadow: rgba(60, 50, 35, .18);
  --glow: rgba(47, 93, 74, .07);

  --barber-1: #3a6ea8;
  --barber-2: #6b4fa0;
  --barber-3: #2f7f78;
  --barber-4: #a8496b;
  --barber-5: #4a5aa0;
  --barber-6: #9c5a34;

  --font-display: Georgia, 'Iowan Old Style', 'Palatino Linotype', ui-serif, serif;
  --font-body: Inter, system-ui, sans-serif;
  /* Daylight wants the shop's name set enormous and plain, with the tagline
     carrying the character instead. */
  --font-sign: Inter, system-ui, sans-serif;
  --font-quote: 'Instrument Serif', Georgia, ui-serif, serif;
  --font-label: Inter, system-ui, sans-serif;
}

/* What the product looked like before it had a barber in mind. Kept so the
   choice is a choice, and so nothing that was tuned against it is lost. */
[data-theme="midnight"] {
  color-scheme: dark;

  --bg: #101522;
  --panel: rgba(28, 36, 54, .74);
  --popup: #1b2333;

  --ink: #f4f6fb;
  --ink-dim: #b4bccf;
  --ink-faint: #8a93a8;

  --accent: #6b98ff;
  --accent-2: #8a7bff;
  /* Was white, which against this blue is 2.6:1 - under the 4.5:1 floor and
     visibly soft on a button. Found by deriving the same palette
     arithmetically in src/core/palette.mjs and comparing. */
  --on-accent: #0d111c;

  --good: #3ddc97;
  --warn: #ffb45c;
  --bad: #ff6b81;

  --line: rgba(210, 220, 255, .14);
  --line-soft: rgba(210, 220, 255, .09);
  --line-strong: rgba(210, 220, 255, .30);

  --surface: rgba(255, 255, 255, .035);
  --surface-2: rgba(255, 255, 255, .018);
  --surface-hover: rgba(255, 255, 255, .09);
  --surface-strong: rgba(255, 255, 255, .12);
  --field: rgba(255, 255, 255, .05);

  --shadow: rgba(0, 0, 0, .55);
  --glow: rgba(107, 152, 255, .10);

  --barber-1: #6b98ff;
  --barber-2: #a78bff;
  --barber-3: #4fd1c5;
  --barber-4: #ff9ec4;
  --barber-5: #f5c750;
  --barber-6: #74e0a0;

  --font-display: Inter, system-ui, sans-serif;
  --font-body: Inter, system-ui, sans-serif;
  /* A tube-bent face, for the neon sign over the shop's own page. */
  --font-sign: Monoton, 'Bebas Neue', Impact, sans-serif;
  --font-quote: Inter, system-ui, sans-serif;
  --font-label: 'Bebas Neue', Impact, sans-serif;
}

/*
 * Chrome. Black, acid yellow, and nothing held back.
 *
 * The only theme whose accent is brighter than its ink, which is why
 * --on-accent is near-black here: white on this yellow is about 1.3 to 1 and
 * simply not there. Its warn and bad had to move too - a burnt orange next to
 * this yellow reads as more yellow rather than as a problem.
 */
[data-theme="chrome"] {
  color-scheme: dark;

  --bg: #0b0b0b;
  --panel: rgba(21, 21, 21, .82);
  --popup: #161616;

  --ink: #ffffff;
  --ink-dim: #b4b4b4;
  --ink-faint: #919191;

  --accent: #e8ff3d;
  --accent-2: #b6cc22;
  --on-accent: #0b0b0b;

  --good: #4fe08a;
  --warn: #ff8a3d;
  --bad: #ff4d4d;

  --line: rgba(255, 255, 255, .22);
  --line-soft: rgba(255, 255, 255, .12);
  --line-strong: rgba(255, 255, 255, .45);

  --surface: rgba(255, 255, 255, .05);
  --surface-2: rgba(255, 255, 255, .025);
  --surface-hover: rgba(255, 255, 255, .12);
  --surface-strong: rgba(255, 255, 255, .17);
  --field: rgba(255, 255, 255, .06);

  --shadow: rgba(0, 0, 0, .7);
  --glow: rgba(232, 255, 61, .12);

  /* Yellow is the accent here, so it cannot also be a barber. */
  --barber-1: #6bb8ff;
  --barber-2: #c08bff;
  --barber-3: #4fd1c5;
  --barber-4: #ff8fb4;
  --barber-5: #9aa0ff;
  --barber-6: #ff9d6b;

  --font-display: Inter, system-ui, sans-serif;
  --font-body: Inter, system-ui, sans-serif;
  --font-sign: Anton, Impact, sans-serif;
  --font-quote: Inter, system-ui, sans-serif;
  --font-label: Anton, Impact, sans-serif;
}

/*
 * Sage - the modern unisex salon.
 *
 * Linen is the other light theme and it is warm paper: cream, serif, a shop
 * that has been there sixty years. This is the opposite kind of light - cool,
 * planted, a lot of white space - which is what the newer places look like
 * and what the existing four had no answer for.
 */
[data-theme="sage"] {
  color-scheme: light;

  --bg: #f4f6f3;
  --panel: rgba(255, 255, 255, .78);
  --popup: #ffffff;

  --ink: #23302a;
  --ink-dim: #566257;
  /* Was #8a958a, which is 2.86:1 on sage's near-white and the worst of the
     seven. Sage is the airiest theme and a grey-green caption disappeared into
     it completely. */
  --ink-faint: #616b62;

  --accent: #4a6b55;
  --accent-2: #88a890;
  --on-accent: #f7faf6;

  --good: #4e8f62;
  --warn: #c07b35;
  --bad: #b4453f;

  --line: rgba(35, 48, 42, .14);
  --line-soft: rgba(35, 48, 42, .08);
  --line-strong: rgba(35, 48, 42, .3);

  --surface: #ffffff;
  --surface-2: #eef1ed;
  --surface-hover: #e7ece6;
  --surface-strong: #dde4dc;
  --field: #ffffff;

  --shadow: rgba(35, 48, 42, .1);
  --glow: rgba(136, 168, 144, .18);

  --barber-1: #4a7fb5;
  --barber-2: #8268ad;
  --barber-3: #3f8f86;
  --barber-4: #b85f82;
  --barber-5: #6b73b8;
  --barber-6: #b8783f;

  --font-display: "DM Sans", Inter, system-ui, sans-serif;
  --font-body: "DM Sans", Inter, system-ui, sans-serif;
  --font-sign: "DM Serif Display", Georgia, serif;
  --font-quote: "DM Sans", Inter, system-ui, sans-serif;
  --font-label: "DM Sans", Inter, system-ui, sans-serif;
}

/*
 * Pomade - the 1950s barbershop.
 *
 * The one look the trade is actually famous for and the one none of the four
 * had: cream, a deep red, a script sign over the door. Parlour is the quiet
 * version of old; this is the loud one.
 */
[data-theme="pomade"] {
  color-scheme: light;

  --bg: #f7f1e4;
  --panel: rgba(255, 252, 245, .85);
  --popup: #fffdf7;

  --ink: #2a1f1a;
  --ink-dim: #6b5a4e;
  /* Was #9c8a7c, 2.94:1 against pomade's cream. The hue is kept so it still
     reads as warm stone rather than grey. */
  --ink-faint: #6f6157;

  --accent: #a8322c;
  --accent-2: #1f4b6b;
  --on-accent: #fff8ec;

  --good: #4a7a3f;
  --warn: #c2762a;
  --bad: #a8322c;

  --line: rgba(42, 31, 26, .16);
  --line-soft: rgba(42, 31, 26, .09);
  --line-strong: rgba(42, 31, 26, .34);

  --surface: #fffcf5;
  --surface-2: #f1e9d9;
  --surface-hover: #ece2cf;
  --surface-strong: #e2d5bd;
  --field: #fffcf5;

  --shadow: rgba(42, 31, 26, .14);
  --glow: rgba(168, 50, 44, .1);

  /* Red is the accent, so no barber may be red. */
  --barber-1: #1f4b6b;
  --barber-2: #6b4b8f;
  --barber-3: #2f7d70;
  --barber-4: #a85f2c;
  --barber-5: #4a5b9c;
  --barber-6: #7d6a2f;

  --font-display: "Libre Franklin", Inter, system-ui, sans-serif;
  --font-body: "Libre Franklin", Inter, system-ui, sans-serif;
  --font-sign: "Alfa Slab One", Georgia, serif;
  --font-quote: "Libre Franklin", Inter, system-ui, sans-serif;
  --font-label: "Libre Franklin", Inter, system-ui, sans-serif;
}

/*
 * Noir - black, white, and one line of colour.
 *
 * For the shops that photograph their work and want nothing competing with
 * it. Chrome is also black but it shouts; this one is a magazine page, and a
 * gallery of cuts is the whole point of it.
 */
[data-theme="noir"] {
  color-scheme: dark;

  --bg: #121212;
  --panel: rgba(26, 26, 26, .85);
  --popup: #1c1c1c;

  --ink: #f5f5f5;
  --ink-dim: #a8a8a8;
  /* Was #767676, 4.12:1. Noir is deliberately the plainest of the seven, which
     is no reason for its captions to be the hardest to read. */
  --ink-faint: #8e8e8e;

  --accent: #d6c4a8;
  --accent-2: #8f8578;
  --on-accent: #141414;

  --good: #6fbf87;
  --warn: #d9a05b;
  --bad: #d96b6b;

  --line: rgba(245, 245, 245, .16);
  --line-soft: rgba(245, 245, 245, .08);
  --line-strong: rgba(245, 245, 245, .38);

  --surface: rgba(245, 245, 245, .04);
  --surface-2: rgba(245, 245, 245, .02);
  --surface-hover: rgba(245, 245, 245, .09);
  --surface-strong: rgba(245, 245, 245, .14);
  --field: rgba(245, 245, 245, .05);

  --shadow: rgba(0, 0, 0, .65);
  --glow: rgba(214, 196, 168, .07);

  --barber-1: #7fa8d4;
  --barber-2: #a98bd4;
  --barber-3: #5fb8b0;
  --barber-4: #d48ba8;
  --barber-5: #8f96d4;
  --barber-6: #d4a06b;

  --font-display: Inter, system-ui, sans-serif;
  --font-body: Inter, system-ui, sans-serif;
  --font-sign: "Cormorant Garamond", Georgia, serif;
  --font-quote: "Cormorant Garamond", Georgia, serif;
  --font-label: Inter, system-ui, sans-serif;
}

/*
 * Buzz - paper, barber red and navy, lettered in capitals.
 *
 * Issam's home page, made into a theme: the cream of a price card, the two
 * colours of a barber's pole, and names set in a condensed face as tall as a
 * sign. It is the house look, so the public site and every new shop start on
 * it.
 *
 * Red is the accent, so "bad" is a brighter red than the brand and a refusal
 * never reads as the logo. The raised surfaces are solid white rather than
 * tinted: the whole look is white cards laid on paper, and a card you can see
 * the paper through is not one.
 */
[data-theme="buzz"] {
  color-scheme: light;

  --bg: #f4f1ea;
  --panel: #ffffff;
  --popup: #ffffff;

  --ink: #16181d;
  --ink-dim: #4a4d55;
  --ink-faint: #5a5d65;

  --accent: #8c2a2a;
  --accent-2: #1f3a5f;
  --on-accent: #ffffff;

  --good: #2f6b4a;
  --warn: #b05a17;
  --bad: #c0392b;

  --line: #d9d4c7;
  --line-soft: #e6e1d6;
  --line-strong: #c9c3b4;

  --surface: #ffffff;
  --surface-2: #ede8dd;
  --surface-hover: #e9e4d8;
  --surface-strong: #e3ded2;
  --field: #ffffff;

  --shadow: rgba(22, 24, 29, .14);
  --glow: rgba(140, 42, 42, .04);

  /* Red is the accent, so no barber may be red. Navy is the pole's other
     colour and the first chair's. */
  --barber-1: #1f3a5f;
  --barber-2: #6b4b8f;
  --barber-3: #2f7d70;
  --barber-4: #a8662c;
  --barber-5: #4a5b9c;
  --barber-6: #6e6a2f;

  /* The capitals are for signs and headlines only. A diary set in a
     condensed display face is not somewhere anybody can work a Saturday,
     so the staff screens keep reading in Inter. */
  --font-display: Inter, system-ui, sans-serif;
  --font-body: Inter, system-ui, sans-serif;
  --font-sign: "Big Shoulders Display", Impact, "Arial Narrow", sans-serif;
  --font-quote: Inter, system-ui, sans-serif;
  --font-label: "Big Shoulders Display", Impact, "Arial Narrow", sans-serif;
}

/* -------------------------------------------------------------------- base */

* { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  background:
    radial-gradient(ellipse 60% 40% at 20% 0%, var(--glow), transparent 60%),
    var(--bg);
  color: var(--ink);
  font: 15px/1.5 var(--font-body);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { font-family: var(--font-display); font-weight: 600; }

a { color: var(--accent); }

/* ---------------------------------------------------------- native controls */

/*
 * Why a dropdown was unreadable.
 *
 * A <select>'s open list is drawn by the browser, not by the page. With no
 * colour-scheme declared it used the operating system's white panel while the
 * options inherited the page's near-white text, so every choice but the
 * highlighted one vanished. Declaring the scheme per theme - dark for Parlour
 * and Midnight, light for Linen - makes the browser draw the list, the date
 * and time pickers, and the scrollbars to match.
 *
 * The explicit option colours below are belt and braces for anything that
 * ignores colour-scheme, and cost nothing where it is honoured.
 */
select, option, input, textarea, button { font-family: inherit; }

select {
  background: var(--field);
  color: var(--ink);
  border: 1px solid var(--line);
}

option {
  background: var(--popup);
  color: var(--ink);
}

/* Chrome draws these glyphs in a fixed near-black that disappears on a dark
   field. Inverting on the dark themes is the only way to reach them. */
[data-theme="parlour"] ::-webkit-calendar-picker-indicator,
[data-theme="midnight"] ::-webkit-calendar-picker-indicator,
:root:not([data-theme]) ::-webkit-calendar-picker-indicator {
  filter: invert(1) opacity(.65);
  cursor: pointer;
}
::-webkit-calendar-picker-indicator:hover { opacity: 1; }

:where(input, select, textarea):focus-visible {
  outline: 2px solid color-mix(in srgb, var(--accent) 70%, transparent);
  outline-offset: 1px;
}

/*
 * The example text inside an empty box.
 *
 * Never themed until now, so every placeholder in the product was the
 * browser's own grey - #757575, which is 3.29:1 against these backgrounds and
 * fails the readability standard the rest of the palette is held to. The
 * contrast checker did not catch it because it reads the tokens, and this was
 * not one.
 *
 * `--ink-faint` is the token for text that is meant to be quiet, and it is
 * checked on every surface in every theme.
 */
::placeholder { color: var(--ink-faint); opacity: 1; }

/* --------------------------------------------------------------- problems */

/* An error about one box, shown under that box. The outline is what the eye
   finds; the words are what it reads once it is there.

   Meant for the input itself. Putting it on a wrapper draws this outline
   around everything inside, square-cornered, which is how the sign-up form's
   first draft ended up boxing each label, input and hint together in red. */
.wrong,
.wrong:focus {
  border-color: var(--bad) !important;
  outline: 2px solid color-mix(in srgb, var(--bad) 35%, transparent);
  outline-offset: 1px;
}

.why {
  margin: 6px 0 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--bad);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 3px 10px;
}

/* Why the box exists, which is usually the real confusion. Quieter than the
   error, because it is context rather than the thing that went wrong. */
.why small {
  display: block;
  width: 100%;
  font-size: 12.5px;
  color: var(--ink-faint);
}

/* A value that would work. A button, because reading a suggestion and then
   typing it out is a chore the page can do instead. */
.why .fix {
  font: inherit;
  font-size: 12.5px;
  cursor: pointer;
  padding: 3px 10px;
  border-radius: 20px;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--ink);
  transition: .16s;
}

.why .fix:hover {
  border-color: var(--accent);
  color: var(--accent);
}

/* ------------------------------------------------------------------- flags */

/* Drawn rather than typed, because the emoji ones render as the letters "CA"
   on a Windows desktop. Sized in ems so one rule serves every place a flag
   appears beside text; the hairline stops a white flag dissolving into a
   light page. */
.flag {
  width: 1.25em;
  height: auto;
  border-radius: 2px;
  vertical-align: -.16em;
  margin-right: .45em;
  box-shadow: 0 0 0 1px var(--line-soft);
}

/* ------------------------------------------------------------------ motion */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}
