/* 123Chair design tokens — two skins.
   Onyx (dark): landing + public booking pages. Ivory (light): owner dashboard.
   --brand is the tenant accent; defaults to 123Chair blue.

   The default is YInMn — the pigment discovered at Oregon State in 2009, the
   first new inorganic blue in about two centuries. It is a DEEP colour: it
   scores 6.3:1 on the light skin and only 2.4:1 on near-black, which fails.
   So the two skins carry two tones of the same hue, each used where it passes:
   #2E5894 true on ivory, lifted to #5288D8 on onyx. Verified, not eyeballed.

   Green and orange are SEMANTIC, not decoration. Green is money that arrived —
   paid, collected, a free slot. Orange is something wanting attention — owed,
   waiting, late, unpaid. A shop owner should be able to read the day by colour
   alone before reading a single word. Both tones are per-skin for the same
   reason blue is: bright enough on near-black, deep enough on white. */

/* Motion. Four curves, each with a job — naming them by job is what stops the
   next person reaching for whichever one is nearest.

   These are Hustler's Mansion's curves, restored. 123Chair inherited the system
   but two of the three had drifted and a fourth was missing, which is most of
   why the same durations felt flatter here:

     out-smooth  was (0.22, 0.61, 0.36, 1) — a generic ease-out. The real curve
                 decelerates far harder and is why an arrival lands instead of
                 drifting in. Compared side by side over the same distance and
                 duration, it is not a subtle difference.
     snap        was (0.2, 0, 0, 1), which eases IN — the wrong shape entirely
                 for a press, where the response has to leave immediately.
     in-out      was absent, so expand/collapse borrowed a curve built for
                 arrivals and read soft at both ends. */
:root {
  /* Depth tokens get a SAFE DEFAULT here because only onyx/ivory define
     their own — on the nine custom skins `var(--lift)` and friends were
     undefined, and the timeline card (among others) rendered with no surface
     at all. Every skin still overrides what it cares to. */
  --lift: linear-gradient(180deg, var(--surface, transparent) 0%, var(--surface-2, var(--surface, transparent)) 160%);
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.10), 0 8px 28px rgba(0, 0, 0, 0.12);
  --glass: blur(20px) saturate(180%);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);   /* arrivals — settles with weight */
  --ease-out-smooth: cubic-bezier(0.16, 1, 0.3, 1);   /* cascades, exits — lands with authority */
  --ease-in-out-smooth: cubic-bezier(0.4, 0, 0.2, 1); /* expand/collapse, knobs — balanced */
  --ease-snap: cubic-bezier(0.2, 0.8, 0.2, 1);        /* presses, chips — sharp, mechanical */
  --dur-snap: 140ms;
  --dur-swift: 180ms;
  --dur-std: 240ms;
  --dur-deliberate: 280ms;
  /* Hustler's Mansion runs three faces, and 123Chair was running two of them
     wrong. Playfair Display carries the headlines — but at 900, not 700; the
     weight is most of what makes HM read like a statement rather than a page.
     The UI face is Libre Franklin, not Inter: Inter is the default of every
     dashboard on the internet, which is exactly the feel being avoided.
     Cormorant Garamond italic is the quiet voice — HM uses it for taglines and
     nothing else, and it only works because it is used that sparingly. */
  --font-display: 'Playfair Display', Georgia, serif;
  --font-ui: 'Libre Franklin', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-quote: 'Cormorant Garamond', Georgia, serif;
  --r-sm: 10px;
  --r-md: 14px;
  --r-lg: 20px;
  --r-pill: 999px;
}

/* IVORY IS WARM AGAIN — 2026-08-05, Keyno's call, made knowingly.
   The note that stood here said neutrals had to be cool because warm creams
   "read muddy" next to blue. That was reasoned from a gold-era palette being
   dragged across, not from warm-and-navy being tried on its own terms. Cream
   paper with navy ink is an old pairing and it holds: the ground is warm, the
   ink is cool, and the temperature gap does work no single-hue scheme can.
   The brand tone did not move — #2E5894 scores 6.33 on this ground, the same
   as it did on the cool one.

   Everything below is verified, not eyeballed:

     brand  #2E5894 on bg   6.33      text  #1A1A1A on bg  15.43
     brand  on white card   7.14      muted #5F5A4C white   6.88
     white  on brand        7.14      faint #7A745E white   4.68

   `faint` is NOT Hustler's Mansion's #A29E90. That value scores 2.68 on white
   — it fails AA outright, and it is used there for small labels. It was
   inherited once already; it is not being inherited again. `muted` was also
   darkened to keep a real gap between the two rather than two greys that only
   differ on paper. */
[data-skin="onyx"] {
  --bg: #0B0D11;
  --surface: #14171D;
  --surface-2: #1A1E26;
  --border: #262C36;
  --line-soft: rgba(255, 255, 255, 0.08);
  --text: #E9ECF1;
  --muted: #97A0AD;
  --faint: #626B79;
  --brand: #5288D8;          /* 5.43 on the onyx bg */
  --brand-weak: #16202E;
  --on-brand: #0C1420;       /* 5.17 — white would be 3.58 and fail */
  --green: #34D399;          /* 10.1 — money in, paid, free */
  --green-weak: #0E2620;
  --red: #F98B8B;
  --red-weak: #2A1618;
  --amber: #FB923C;          /* 8.6 — needs a look, waiting, owed */
  --amber-weak: #2A1C0E;

  /* Same four roles as ivory so nothing has to branch on skin. Dark surfaces
     get almost nothing from a drop shadow — the lift here is the gradient and
     the border doing the work, and the shadow is only deep enough to separate
     a floating element from what is behind it. */
  --border-2: #333B47;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.5), 0 10px 32px rgba(0, 0, 0, 0.45);
  --lift: linear-gradient(180deg, var(--surface) 0%, var(--surface-2) 160%);
  --glass: blur(20px) saturate(180%);
  color-scheme: dark;
}

[data-skin="ivory"] {
  --bg: #F4F1EA;             /* warm ground — cream paper */
  --surface: #FFFFFF;
  --surface-2: #FAF6EC;      /* the far end of the card gradient; see --lift */
  --border: #E8E2D4;
  --border-2: #D9D2C0;       /* second tier — hover, and anything that must read heavier */
  --line-soft: rgba(60, 50, 20, 0.07);
  --text: #1A1A1A;           /* 15.43 on bg */
  --muted: #5F5A4C;          /* 6.88 on white */
  --faint: #7A745E;          /* 4.68 on white — NOT HM's #A29E90, which fails at 2.68 */
  --brand: #2E5894;          /* true YInMn — 6.33 on this ground, unchanged */
  --brand-weak: #E8EEF7;
  --on-brand: #FFFFFF;       /* 7.14 */
  --green: #157A40;          /* 5.40 — money in, paid, free */
  --green-weak: #E4F2E9;
  --red: #B4433A;            /* 5.52 */
  --red-weak: #FBE9E7;
  --amber: #8A5C00;          /* 5.81 — needs a look, waiting, owed */
  --amber-weak: #F7EDD8;

  /* Depth is warm, and it is the whole reason this reads as lit rather than
     flat. The shadow is brown-tinted, not grey — a neutral shadow on a cream
     ground looks like dirt. Two layers: a tight contact shadow that sits the
     card down, and a broad ambient one that lifts it. */
  --shadow: 0 1px 2px rgba(60, 50, 20, 0.06), 0 8px 28px rgba(60, 50, 20, 0.07);
  /* The card lift. Barely visible on purpose — you should not be able to name
     it, only notice its absence. */
  --lift: linear-gradient(180deg, var(--surface) 0%, var(--surface-2) 160%);
  --glass: blur(20px) saturate(180%);
  color-scheme: light;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html { overflow-x: clip; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-ui);
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: none;
}

/* Somebody who has asked their phone to stop moving things has asked once, for
   every app. app.html, shop.html and book.html each carry this rule already;
   putting it here means the next surface inherits it instead of being the one
   that forgot. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
