/* OWNER: Charlie. Design system, tokens, layout. --brand holds the product name color. */
/* Lume, built by Ronnie Solomon with Sophie, September 2026. */
/* Built to DESIGN.md (Sophie, September 13 2026), which is binding and overrides
   any earlier taste call here. Ink and paper, one oxblood accent, system serif
   for the display line only, everything else system sans with tabular numbers. */

/* ---------------------------------------------------------------- TOKENS
   Contrast, measured, 4.5:1 floor for every text color on its background:
     light  --muted on --surface 6.3:1, on --bg 5.8:1
            --accent as text on --surface 9.4:1, --on-brand on --accent 9.4:1
     dark   --muted on --surface 7.2:1, --accent on --bg 9.0:1,
            --on-brand on --accent 8.6:1
     --on-tint on every sample stylist color 5.7:1 or better (avatar initials). */
:root {
  --brand: #7C2A2E;
  --accent: #7C2A2E;
  --on-brand: #FFFFFF;
  --bg: #F5F4F4;
  --surface: #FFFFFF;
  --fg: #17151A;
  --muted: #625E66;
  --line: #E4E2E2;
  --ok: #1C6B4B;
  --warn: #8A5A0B;
  --danger: #A8201A;

  /* Initials sit on a solid stylist color, which is data and does not follow
     the theme, so their ink does not follow the theme either. */
  --on-tint: #17151A;
  --logo: #10305A; /* the wordmark's navy, Ronnie's Sep 25 mark */
  --spark: #EEC3CB; /* the wordmark's star; dark and marshmallow keep this pale pink, the light theme sets a deeper one */

  --radius: 12px;
  --space: 8px;
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-display: ui-serif, "New York", "Iowan Old Style", Georgia, "Times New Roman", serif;

  /* One fixed ramp. 12 chips, 13 meta, 15 body, 17 card titles, 20 screen titles. */
  --fs-chip: 12px;
  --fs-meta: 13px;
  --fs-body: 15px;
  --fs-card: 17px;
  --fs-screen: 20px;
  --fs-display: 28px;
  /* kept so any lane written against the first pass still resolves */
  --t1: var(--fs-screen); --t2: var(--fs-card); --t3: var(--fs-body); --t4: var(--fs-meta);

  --tint: 14%;       /* service color into --surface, card and picker fills */
  --tint-line: 35%;  /* service color into --line, card borders */
  --shadow-sheet: 0 -2px 8px rgba(16, 14, 18, .06), 0 -18px 48px rgba(16, 14, 18, .14);
  --shadow-lift: 0 2px 6px rgba(16, 14, 18, .10), 0 12px 28px rgba(16, 14, 18, .14);

  /* book knobs. ponytail: 24px per 15 minutes is the density calibration knob.
     WCAG 2.5.8 floor is 24px, so a slot stays a legal target and a nine hour
     day still fits one screen. Raise it if the book ever feels cramped. */
  --slot: 24px;
  --book-gutter: 56px;
  --book-col: 168px;
  --chart-bar: #D9D4D6;

  /* Sophie, Sep 25: fill tokens. Defaults alias existing values so Light and Dark
     stay pixel identical. Marshmallow overrides these in its block below. */
  --nav-bg: var(--surface);    /* tab bar and rail background */
  --nav-line: var(--line);     /* nav border */
  --fill: var(--accent);       /* solid primary fill: btn-primary, fab, marks, dots */
  --on-fill: var(--on-brand);  /* ink on --fill */
  --fill-line: var(--accent);  /* border of a --fill element */
  --select-bg: var(--fg);      /* pressed filter chips, toast */
  --on-select: var(--bg);      /* ink on --select-bg */
  --chip-bg: var(--bg);        /* resting chip background */
  --chip-fg: var(--muted);     /* resting chip ink */
  --seg-on: var(--surface);    /* pressed segment in .theme-seg (.theme-btn only; .book-seg scoped below) */
}

/* ----------------------------------------------------------- LIGHT, Oct 3 2026
   Ronnie: deeper colors, a creamier page, the David James Salon OS look. The light theme is a STRUCTURE (a deep frame
   around the paper, white cards with outlines, a jewel cap on each stat tile, a dark pill for the selected chip) that is
   filled by a PALETTE. The default palette is David James. Three more are swap options, picked in Settings or More and
   stored per device (localStorage glamapp.light = a, b or c; no attribute on <html> is the default):
     default  David James            aubergine frame, ivory paper, white cards, lilac outlines, teal actions
     a        Parchment and wine     wine frame, cream paper, wine actions
     b        Ivory and plum         plum frame, ivory paper, plum actions, gold bars
     c        Primary colors on cream  navy frame, cream paper, cobalt actions, yellow bars, true red
   Dark and marshmallow never read this section: marshmallow inherits from the plain :root above. Contrast is computed from this
   CSS by tests/light-palette.html (text 4.5:1, graphics 3:1; inside the frame fg, muted and the current item 4.5:1).
   Every palette fills the same tokens: the page (bg surface fg muted line), the actions (accent brand on-brand), the
   status colors (ok warn danger), the logo star (spark), the bars (chart-bar), the field border (control-line), the frame
   (nav-bg nav-line nav-fg nav-muted nav-pill nav-accent nav-spark) and the four stat caps (cap-1 to cap-4). */
:root[data-theme="light"] {
  --brand: #1F6F5E;
  --accent: #1F6F5E;
  --on-brand: #FFFFFF;
  --bg: #F8F5F0;
  --surface: #FFFFFF;
  --fg: #241B29;
  --muted: #514956;
  --line: #D8C6DE;
  --ok: #1F6F5E;
  --warn: #7B5718;
  --danger: #AC3F47;
  --spark: #E24A86;
  --chart-bar: #2A8A74;
  --control-line: #9887A6;
  --nav-bg: #24152C;
  --nav-line: #3A2748;
  --nav-fg: #F8F5F0;
  --nav-muted: #C9BDD0;
  --nav-pill: #3A2748;
  --nav-accent: #E3B556;
  --nav-spark: #F26BA3;
  --cap-1: #257567;
  --cap-2: #D3A34D;
  --cap-3: #AC3F47;
  --cap-4: #67458C;
  --scrim: rgba(36, 27, 41, .42);
  --shadow-sheet: 0 -2px 8px rgba(36, 21, 44, .07), 0 -18px 48px rgba(36, 21, 44, .17);
  --shadow-lift: 0 2px 6px rgba(36, 21, 44, .10), 0 12px 28px rgba(36, 21, 44, .16);
}
:root[data-theme="light"][data-light="a"] {
  --brand: #6A1B3A;
  --accent: #6A1B3A;
  --bg: #F3ECDD;
  --surface: #FFFCF6;
  --fg: #1F1824;
  --muted: #54495A;
  --line: #D9CBB4;
  --ok: #17624A;
  --warn: #7A4F08;
  --danger: #A01D1D;
  --spark: #D93F78;
  --chart-bar: #A68B66;
  --control-line: #9C8B77;
  --nav-bg: #2B1020;
  --nav-line: #4A2236;
  --nav-fg: #F3ECDD;
  --nav-muted: #D6C3C8;
  --nav-pill: #4A2236;
  --nav-accent: #E3B556;
  --nav-spark: #F26BA3;
  --cap-1: #6A1B3A;
  --cap-2: #B98A2E;
  --cap-3: #17624A;
  --cap-4: #5B3A6E;
  --scrim: rgba(31, 24, 36, .38);
  --shadow-sheet: 0 -2px 8px rgba(31, 24, 36, .07), 0 -18px 48px rgba(31, 24, 36, .16);
  --shadow-lift: 0 2px 6px rgba(31, 24, 36, .10), 0 12px 28px rgba(31, 24, 36, .15);
}
:root[data-theme="light"][data-light="b"] {
  --brand: #4F2E70;
  --accent: #4F2E70;
  --bg: #F5F0E8;
  --surface: #FFFDF9;
  --fg: #241B29;
  --muted: #514956;
  --line: #D8C6DE;
  --ok: #1D6B5C;
  --warn: #7B5718;
  --danger: #9A2F3A;
  --spark: #D4558A;
  --chart-bar: #B08A2E;
  --control-line: #9887A6;
  --nav-bg: #2A1B38;
  --nav-line: #43305A;
  --nav-fg: #F5F0E8;
  --nav-muted: #CFC3DA;
  --nav-pill: #43305A;
  --nav-accent: #E0B85A;
  --nav-spark: #F26BA3;
  --cap-1: #4F2E70;
  --cap-2: #B08A2E;
  --cap-3: #1D6B5C;
  --cap-4: #9A2F3A;
  --scrim: rgba(36, 27, 41, .38);
  --shadow-sheet: 0 -2px 8px rgba(36, 27, 41, .07), 0 -18px 48px rgba(36, 27, 41, .16);
  --shadow-lift: 0 2px 6px rgba(36, 27, 41, .10), 0 12px 28px rgba(36, 27, 41, .15);
}
:root[data-theme="light"][data-light="c"] {
  --brand: #1D45C4;
  --accent: #1D45C4;
  --bg: #F7F0DF;
  --surface: #FFFDF6;
  --fg: #14182E;
  --muted: #464B66;
  --line: #DCD2B8;
  --ok: #0E7A46;
  --warn: #8A5A00;
  --danger: #C8102E;
  --spark: #E5336F;
  --chart-bar: #B98300;
  --control-line: #8C8A96;
  --nav-bg: #14182E;
  --nav-line: #26305A;
  --nav-fg: #F7F0DF;
  --nav-muted: #BFC4DC;
  --nav-pill: #26305A;
  --nav-accent: #F2B705;
  --nav-spark: #FF5C93;
  --cap-1: #1D45C4;
  --cap-2: #C48A00;
  --cap-3: #C8102E;
  --cap-4: #0E7A46;
  --scrim: rgba(20, 24, 46, .38);
  --shadow-sheet: 0 -2px 8px rgba(20, 24, 46, .07), 0 -18px 48px rgba(20, 24, 46, .16);
  --shadow-lift: 0 2px 6px rgba(20, 24, 46, .10), 0 12px 28px rgba(20, 24, 46, .15);
}
/* The frame: the rail and the tab bar take the palette's frame colors, and everything inside them is re themed the way dark
   mode does it, by handing the nav its own tokens. The wordmark goes light and its star a brighter pink; the current item is the
   accent on the phone tab bar and a lifted pill on the rail. */
:root[data-theme="light"] .nav {
  background: var(--nav-bg);
  --fg: var(--nav-fg); --muted: var(--nav-muted); --line: var(--nav-line); --surface: var(--nav-pill); --bg: var(--nav-bg);
  --accent: var(--nav-accent); --logo: var(--nav-fg); --spark: var(--nav-spark); --seg-on: var(--nav-pill);
  --select-bg: var(--nav-pill); --on-select: var(--nav-fg);
}
/* A jewel cap on each stat tile, as on the David James owner dashboard. */
:root[data-theme="light"] .td-stat { border-top: 3px solid var(--cap-1); }
:root[data-theme="light"] .td-stat:nth-child(4n+2) { border-top-color: var(--cap-2); }
:root[data-theme="light"] .td-stat:nth-child(4n+3) { border-top-color: var(--cap-3); }
:root[data-theme="light"] .td-stat:nth-child(4n+4) { border-top-color: var(--cap-4); }
/* The few light rules that are not a plain token: fields, the scrim behind a sheet, the install tile. */
:root[data-theme="light"] :is(.input, .select):not(:focus) { border-color: var(--control-line); }
:root[data-theme="light"] .sheet-scrim { background: var(--scrim); }
:root[data-theme="light"] .install-icon { background: var(--bg); }

:root[data-theme="dark"] {
  --brand: #E4A3A6;
  --accent: #E4A3A6;
  --on-brand: #2B0F11;
  --bg: #121114;
  --surface: #1B1A1E;
  --fg: #F3F1F4;
  --muted: #A9A5AF;
  --line: #2B292F;
  --ok: #5CCF9E;
  --warn: #E5B65C;
  --danger: #FF8E86;
  --shadow-sheet: 0 -2px 8px rgba(0, 0, 0, .5), 0 -18px 48px rgba(0, 0, 0, .55);
  --shadow-lift: 0 2px 6px rgba(0, 0, 0, .5), 0 12px 28px rgba(0, 0, 0, .5);
  --chart-bar: #3A363F;
  --logo: #F3F1F4;
}

/* Marshmallow, Sophie, Sep 25 2026, Ronnie's pick from pastelcolorpalettes.com/marshmallow.
   sky C0E6F0: nav background and selected states (filter chips, toast, scoped nav rule below).
   pink F9DEE5: primary fills (btn-primary, fab, nav-mark, nowdot, pin-dot, chip bg, seg pressed).
   off white FBFBFB: cards and surfaces.
   cream F1EEDD: page background.
   Rose 9E355C text only: accent, brand, focus rings, today borders, active nav item.
   Ink 2A2330 on pink 12.0:1; 2A2330 on sky 11.4:1; muted 655A63 on pink 4.8:1, on sky 4.9:1; rose on sky 5.1:1.
   ok, warn and danger inherit the light values, 5.1:1 or better on the cream. */
:root[data-theme="marshmallow"] {
  --brand: #9E355C;
  --accent: #9E355C;
  --on-brand: #FFFFFF;
  --bg: #F1EEDD;
  --surface: #FBFBFB;
  --fg: #2A2330;
  --muted: #655A63;
  --line: #EAD3DA;
  --chart-bar: #C0E6F0;
  /* fill tokens: Sophie, Sep 25 */
  --nav-bg: #C0E6F0;
  --nav-line: #A6D3E1;
  --fill: #F9DEE5;
  --on-fill: #2A2330;
  --fill-line: #E9B9C8;
  --select-bg: #C0E6F0;
  --on-select: #2A2330;
  --chip-bg: #F9DEE5;
  --chip-fg: #655A63;
  --seg-on: #F9DEE5;
}
/* Sophie, Sep 25: these two base rules use --bg, not --surface, so the token default
   (--surface) does not alias them. Scoped overrides apply marshmallow values without
   touching Light or Dark. */
:root[data-theme="marshmallow"] .nav { background: var(--nav-bg); }
:root[data-theme="marshmallow"] .book-seg .btn[aria-pressed="true"] { background: var(--seg-on); }
:root[data-theme="marshmallow"] .btn[aria-pressed="true"] { background: var(--select-bg); border-color: var(--select-bg); color: var(--on-select); box-shadow: none; } /* Sophie, Sep 25: every other pressed button is a sky fill, the rose ring is Light only */

/* Marshmallow, second round (Ronnie: the calendar does not change, and it needs cloudiness).
   The page carries soft pink and sky washes, blended, never drawn clouds; the Book sits on a
   frosted white so they show through. The calendar follows the palette: a service color survives
   only as the avatar's pastel and a soft left edge, the fill says where the client is.
   Unconfirmed white, confirmed sky, in the salon pink, done cream, processing sky, blocks pink. */
:root[data-theme="marshmallow"] #app {
  background:
    radial-gradient(70% 55% at 12% 6%, rgba(249, 222, 229, .85) 0%, rgba(249, 222, 229, 0) 70%),
    radial-gradient(55% 50% at 90% 16%, rgba(192, 230, 240, .8) 0%, rgba(192, 230, 240, 0) 70%),
    radial-gradient(60% 45% at 28% 96%, rgba(192, 230, 240, .55) 0%, rgba(192, 230, 240, 0) 70%),
    radial-gradient(50% 45% at 86% 88%, rgba(249, 222, 229, .7) 0%, rgba(249, 222, 229, 0) 70%),
    radial-gradient(40% 35% at 55% 48%, rgba(251, 251, 251, .6) 0%, rgba(251, 251, 251, 0) 70%),
    #F1EEDD;
}
:root[data-theme="marshmallow"] :is(.book-head, .book-chips, .pin) { background: transparent; }
:root[data-theme="marshmallow"] .book-scroll { background: rgba(251, 251, 251, .8); }
:root[data-theme="marshmallow"] .book-colhead { background: rgba(251, 251, 251, .92); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }
:root[data-theme="marshmallow"] :is(.book-corner, .book-times) { background: rgba(241, 238, 221, .9); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }
:root[data-theme="marshmallow"] :is(.book-card, .book-item) {
  background: color-mix(in srgb, var(--c, var(--muted)) 6%, #FBFBFB);
  border-color: #EAD3DA;
  box-shadow: inset 3px 0 0 color-mix(in srgb, var(--c, var(--muted)) 55%, #FBFBFB);
}
:root[data-theme="marshmallow"] :is(.book-card, .book-item):hover { border-color: #E9B9C8; }
:root[data-theme="marshmallow"] :is(.book-card, .book-item):has(.book-confirmation[data-confirmed="true"]) { background: color-mix(in srgb, #C0E6F0 55%, #FBFBFB); }
:root[data-theme="marshmallow"] :is(.book-card, .book-item):is([data-status="arrived"], [data-status="in_chair"]) { background: #F9DEE5; }
:root[data-theme="marshmallow"] :is(.book-card, .book-item)[data-status="done"] { background: #F1EEDD; }
:root[data-theme="marshmallow"] :is(.book-card, .book-item)[data-status="no_show"] { background: #FBFBFB; box-shadow: none; }
:root[data-theme="marshmallow"] .book-av { background: color-mix(in srgb, var(--c, var(--line)) 45%, #FBFBFB); }
:root[data-theme="marshmallow"] .book-processing { background: color-mix(in srgb, #C0E6F0 45%, #FBFBFB); border-color: #A6D3E1; }
:root[data-theme="marshmallow"] .book-processing-label { background: color-mix(in srgb, #C0E6F0 45%, #FBFBFB); color: var(--fg); }
:root[data-theme="marshmallow"] .book-block { background: repeating-linear-gradient(135deg, #FBFBFB, #FBFBFB 6px, #F9DEE5 6px, #F9DEE5 8px); }

/* ------------------------------------------------------------------ BASE */
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; }
body {
  font-family: var(--font);
  font-size: var(--fs-body);
  line-height: 1.45;
  color: var(--fg);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: none;
}
/* V3, Oct 3: Light only. Measured on macOS Chrome (light theme), antialiased drops the stem darkening and thins every glyph: mean edge
   gradient .243 against .257 at DPR 1, hard edge share .483 against .542. iOS and Android ignore the property. Dark and marshmallow are
   approved as they are and keep antialiased; extending this to them needs its own dark measurement first. */
:root[data-theme="light"] body { -webkit-font-smoothing: auto; }
p { margin: 0; }
/* The display voice, and the only place it appears: a screen's own title. */
h1 {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--fs-display);
  font-weight: 500;
  letter-spacing: -.01em;
  line-height: 1.15;
}
h1 em { font-style: italic; }
h2 { margin: 0; font-size: var(--fs-screen); font-weight: 600; letter-spacing: -.01em; }
h3 { margin: 0; font-size: var(--fs-card); font-weight: 600; }
.num, .book-time, .book-tick span, .book-title p { font-variant-numeric: tabular-nums; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 8px; }
::selection { background: color-mix(in srgb, var(--accent) 20%, transparent); }
@media (min-width: 768px) { :root { --fs-display: 34px; --slot: 32px; } }
@media (min-width: 1280px) { :root { --fs-display: 40px; } }

/* ----------------------------------------------------------------- SHELL
   Nav first in the DOM, painted at the bottom on a phone by column-reverse,
   painted as a left rail from 768 up. min-width:0 on the main column is what
   keeps a wide day grid from ever pushing the page sideways. */
#app { display: flex; flex-direction: column-reverse; height: 100dvh; background: var(--bg); }
.nav {
  display: flex; align-items: stretch; gap: 2px; flex-wrap: nowrap;
  background: var(--nav-bg); /* Sophie, Sep 25 */
  border-top: 1px solid var(--nav-line); /* Sophie, Sep 25 */
  padding: 0 4px calc(env(safe-area-inset-bottom, 0px) + 4px);
  flex: 0 0 auto;
}
.nav-brand { display: none; }
.nav-brand b { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; } /* the name stays readable, the wordmark carries the look */
.nav-logo, .pin-logo, .more-logo { display: block; color: var(--logo); }
.nav-logo-g { width: 44px; height: 44px; } /* Oct 3, Ronnie: the logo gets larger, about 45 percent */
.nav-logo-word { display: none; width: 190px; height: 36px; }
.pin-logo { width: 220px; height: 41px; margin: 0 auto; }
.more-logo { width: 170px; height: 32px; margin: 4px auto 0; }
/* On a phone the credit rides above the tab row rather than disappearing. */
/* on a phone both of these live on the More screen, never in the tab bar */
.nav-credit { display: none; text-align: center; font-size: 11px; color: var(--muted); }
.nav-theme { display: none; }
.theme-seg { display: flex; gap: 2px; padding: 3px; border-radius: 9px; background: var(--bg); border: 1px solid var(--line); }
.theme-btn {
  display: flex; align-items: center; justify-content: center;
  min-width: 34px; height: 30px; padding: 0 6px;
  border: 1px solid transparent; border-radius: 7px; background: none;
  color: var(--muted); cursor: pointer; font: inherit; font-size: 12px; font-weight: 600;
}
.theme-btn svg { width: 16px; height: 16px; }
.theme-btn[aria-pressed="true"] { background: var(--seg-on); color: var(--fg); border-color: var(--line); /* Sophie, Sep 25 */ }
.nav-items { display: flex; flex: 1 1 auto; min-width: 0; }
.nav-item {
  flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  min-height: 48px; padding: 5px 2px;
  border: 1px solid transparent; border-radius: 10px; background: none;
  color: var(--muted); font: inherit; font-size: 11px; font-weight: 500;
  cursor: pointer; text-decoration: none;
}
.nav-long { display: none; }
.nav-item span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-item svg { width: 20px; height: 20px; }
.nav-item[aria-current="page"] { color: var(--accent); font-weight: 600; }

.main { flex: 1 1 auto; min-height: 0; min-width: 0; display: flex; flex-direction: column; overflow: hidden; }
.screen { flex: 1 1 auto; min-height: 0; min-width: 0; display: flex; flex-direction: column; overflow: hidden; width: 100%; max-width: 1680px; margin: 0 auto; } /* Sophie, Sep 25: an ultrawide monitor no longer stretches a screen edge to edge, the rail stays docked and the content centers */
.screen[data-route="book"] { max-width: none; } /* Sophie, Sep 26: Ronnie wants the Book to fill an ultrawide; forms and lists keep the cap */

@media (min-width: 768px) {
  #app { flex-direction: row; }
  /* 768 to 1279 is the front desk iPad, where every pixel belongs to the
     chairs, so the rail collapses to icons only. flex-wrap must be reset:
     inherited from the phone tab bar it would wrap the rail into a second
     column and push the book sideways. */
  .nav {
    flex-direction: column; align-items: stretch; flex-wrap: nowrap; gap: 2px;
    width: 72px; flex: 0 0 72px;
    background: var(--bg);
    border-top: 0; border-right: 1px solid var(--nav-line); /* Sophie, Sep 25 */
    padding: 22px 10px 14px;
    overflow-y: auto;
  }
  .nav-brand {
    display: flex; align-items: center; justify-content: center;
    font-size: 0; padding: 0 0 20px;
  }
  .nav-mark { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 10px; background: var(--accent); /* Sophie, Sep 25: rose, so the brand dot reads on the sky nav */ }
  .nav-items { flex-direction: column; flex: 0 0 auto; gap: 2px; }
  .nav-item {
    flex: 0 0 auto; flex-direction: row; justify-content: center; gap: 0;
    min-height: 44px; padding: 0; font-size: var(--fs-body); font-weight: 500;
  }
  .nav-long, .nav-short { display: none; }
  .nav-item[aria-current="page"] {
    color: var(--fg); font-weight: 600;
    background: var(--surface); border-color: var(--line);
  }
  .nav-credit { display: none; order: 0; flex: 0 0 auto; }
  .nav-theme { display: block; order: 0; flex: 0 0 auto; margin-top: auto; padding: 10px 0 0; }
  .nav-theme .theme-seg { flex-direction: column; } /* Sophie, Sep 25: only the rail stacks, the Settings row stays a row at every width */
}

@media (min-width: 1280px) {
  .nav { width: 232px; flex: 0 0 232px; padding: 22px 12px 14px; }
  .nav-logo-g { display: none; }
  .nav-logo-word { display: block; }
  .nav-brand {
    justify-content: flex-start; gap: 9px; padding: 0 8px 20px;
    font-family: var(--font-display); font-size: 22px; font-weight: 500;
    letter-spacing: -.01em; color: var(--fg);
  }
  .nav-item { justify-content: flex-start; gap: 11px; padding: 0 12px; }
  .nav-long { display: block; }
  .nav-credit {
    display: block; text-align: left;
    padding: 12px 8px 0; font-size: var(--fs-chip); color: var(--muted);
  }
  .nav-theme { padding: 10px 0 0; }
  .nav-theme .theme-seg { flex-direction: row; }
}

/* ------------------------------------------------------------ COMPONENTS */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 44px; padding: 0 15px;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--surface); color: var(--fg);
  font: inherit; font-size: var(--fs-body); font-weight: 500; line-height: 1;
  cursor: pointer; white-space: nowrap; text-decoration: none;
}
.btn:hover { border-color: color-mix(in srgb, var(--fg) 22%, var(--line)); }
.btn[disabled] { opacity: .4; cursor: not-allowed; }
.btn[disabled]:hover { border-color: var(--line); }
.btn-primary { background: var(--fill); border-color: var(--fill-line); color: var(--on-fill); font-weight: 600; /* Sophie, Sep 25 */ }
.btn-primary:hover { border-color: var(--fill-line); filter: brightness(1.1); }
.btn-quiet { background: none; border-color: transparent; color: var(--muted); }
.btn-quiet:hover { background: color-mix(in srgb, var(--fg) 5%, transparent); border-color: transparent; color: var(--fg); }
.btn-danger { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 28%, var(--line)); }
.btn-danger:hover { border-color: var(--danger); }
.btn[aria-pressed="true"] { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }

.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: calc(var(--space) * 2);
  min-width: 0;
}

/* 16px is the floor on form controls: anything smaller makes iOS Safari zoom
   the page on focus and leaves it scrolled sideways. */
.input, .select {
  width: 100%; min-width: 0; height: 48px;
  padding: 0 13px;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--surface); color: var(--fg);
  font: inherit; font-size: 16px;
}
.input:focus, .select:focus { border-color: var(--accent); outline: none; box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 16%, transparent); }
.select { appearance: none; padding-right: 34px;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 17px) 50%, calc(100% - 12px) 50%;
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; }

.chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 8px; border-radius: 999px;
  background: var(--chip-bg); color: var(--chip-fg); /* Sophie, Sep 25 */
  border: 1px solid var(--line);
  font-family: var(--font); font-size: var(--fs-chip); font-weight: 500; font-style: normal;
  white-space: nowrap; line-height: 1.5;
}
.chip-quiet { background: none; border-color: transparent; padding-left: 0; padding-right: 0; }
.chip-ok { background: color-mix(in srgb, var(--ok) 12%, var(--surface)); border-color: color-mix(in srgb, var(--ok) 30%, var(--line)); color: var(--ok); }
.chip-warn { background: color-mix(in srgb, var(--warn) 14%, var(--surface)); border-color: color-mix(in srgb, var(--warn) 32%, var(--line)); color: var(--warn); }

.row { display: flex; align-items: center; gap: var(--space); min-width: 0; flex-wrap: wrap; }
.stack { display: flex; flex-direction: column; gap: var(--space); min-width: 0; }
.grid { display: grid; gap: var(--space); grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }

.empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  padding: calc(var(--space) * 6) calc(var(--space) * 2);
  text-align: center; color: var(--muted);
}
.empty h2 { color: var(--fg); }
.empty p { max-width: 38ch; }

.label { font-size: var(--fs-chip); font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .07em; }

.kbd {
  display: inline-block; padding: 1px 6px; border-radius: 6px;
  border: 1px solid var(--line); border-bottom-width: 2px;
  background: var(--bg); font-size: var(--fs-chip); font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* Shared, any lane may call window.toast(text). One at a time, about 2.5s. */
.toast {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(env(safe-area-inset-bottom, 0px) + 88px);
  z-index: 60; max-width: calc(100% - 32px);
  padding: 11px 16px; border-radius: 999px;
  background: var(--select-bg); color: var(--on-select); /* Sophie, Sep 25 */
  font-size: var(--fs-body); font-weight: 500; box-shadow: var(--shadow-lift);
}
@media (min-width: 768px) { .toast { bottom: 24px; } }

/* Shared sheet. Always bottom anchored, never a modal in the middle.
   .sheet IS the panel, because css/motion.css slides .sheet up and the scrim
   must not slide with it. Markup a lane should use:
   <div class="sheet-wrap" role="dialog" aria-modal="true" aria-label="...">
     <div class="sheet-scrim" data-act="close"></div>
     <div class="sheet"><div class="sheet-grab"></div>
       <header class="sheet-head"><h2>..</h2></header>
       <div class="sheet-body">..</div><div class="sheet-foot">..</div></div></div>
   The owning screen closes it on Escape and on a scrim click. */
.sheet-wrap { position: fixed; inset: 0; z-index: 50; }
.sheet-scrim { position: absolute; inset: 0; background: rgba(14, 12, 16, .38); }
.sheet {
  position: absolute; left: 0; right: 0; bottom: 0; margin: 0 auto;
  width: 100%; max-width: 560px;
  max-height: 90dvh; display: flex; flex-direction: column;
  background: var(--surface); color: var(--fg);
  border: 1px solid var(--line); border-bottom: 0;
  border-radius: 20px 20px 0 0;
  box-shadow: var(--shadow-sheet);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
/* A centered dialog: the same sheet, floated to the middle of the screen. The converter uses it (Ronnie, September 21 2026);
   any sheet may opt in with the sheet-center class. Under 640 it keeps a phone margin and never touches the edges. */
.sheet-wrap.sheet-center { display: flex; align-items: center; justify-content: center; padding: 16px; }
.sheet-wrap.sheet-center .sheet { position: relative; inset: auto; bottom: auto; margin: 0; width: min(100%, 560px); max-height: min(86dvh, 100%); border-bottom: 1px solid var(--line); border-radius: 20px; padding-bottom: 0; }
.sheet-wrap.sheet-center .sheet-grab { display: none; }
.sheet-wrap.sheet-center .sheet-head { padding-top: 22px; }
.sheet-grab { width: 36px; height: 4px; border-radius: 2px; background: var(--line); margin: 8px auto 0; flex: 0 0 auto; }
.sheet-head { display: flex; align-items: center; gap: var(--space); padding: 14px 18px 12px; }
.sheet-head h2 { flex: 1; min-width: 0; font-size: var(--fs-screen); font-weight: 600; }
.sheet-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 2px 18px 18px; display: flex; flex-direction: column; gap: 16px; }
.sheet-foot { padding: 12px 18px calc(var(--space) * 2); border-top: 1px solid var(--line); display: flex; flex-direction: column; gap: 8px; }
.sheet-foot .btn-primary { width: 100%; min-height: 52px; font-size: var(--fs-card); }
.sheet-foot .btn-quiet { width: 100%; }
.sheet-note { font-size: var(--fs-meta); color: var(--muted); }

/* ------------------------------------------------------------- BOOK (.book-) */
.book { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; min-width: 0; }
.book-main { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; min-width: 0; }

.book-head {
  display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap;
  padding: 24px 16px 14px;
  background: var(--bg);
}
.book-title { flex: 1 1 240px; min-width: 0; }
.book-title p { font-size: var(--fs-meta); color: var(--muted); margin-top: 5px; }
.book-title p b { font-weight: 600; color: var(--fg); }
.book-meta-link {
  color: var(--accent); text-decoration: none; padding: 3px 0;
  border-bottom: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
}
.book-meta-link:hover { border-bottom-color: var(--accent); }
.book-title .chip { vertical-align: middle; margin-right: 6px; }
.book-tools { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; min-width: 0; max-width: 100%; } /* Sophie, Sep 25: lets a wide segment shrink instead of pushing the screen sideways */
.book-icon { min-width: 44px; width: 44px; padding: 0; }
.book-icon svg { width: 18px; height: 18px; }
.book-seg { display: inline-flex; padding: 3px; gap: 2px; border-radius: 10px; background: var(--surface); border: 1px solid var(--line); max-width: 100%; min-width: 0; overflow-x: auto; scrollbar-width: none; } /* Sophie, Sep 25: five Settings tabs overflowed a 390 phone and dragged the whole screen sideways; the strip scrolls inside itself instead */
.book-seg::-webkit-scrollbar { display: none; }
.book-seg .btn { flex: 0 0 auto; }
.book-seg .btn { min-height: 36px; border: 1px solid transparent; background: none; padding: 0 13px; color: var(--muted); box-shadow: none; }
.book-seg .btn[aria-pressed="true"] { background: var(--bg); color: var(--fg); font-weight: 600; border-color: var(--line); box-shadow: none; }
@media (min-width: 768px) {
  .book-head { padding: 32px 28px 18px; flex-wrap: nowrap; }
  .book-tools { flex-wrap: nowrap; }
}

/* the avatar, used in column heads, agenda rows and filter chips */
.book-av {
  width: 28px; height: 28px; flex: 0 0 28px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--c, var(--line)); color: var(--on-tint);
  font-size: 11px; font-weight: 600; letter-spacing: .02em;
}

/* ---- 640 and up, the grid. The only scroller that may move sideways. */
.book-scroll { flex: 1 1 auto; min-height: 0; min-width: 0; overflow: auto; background: var(--surface); border-top: 1px solid var(--line); }
.book-grid {
  display: grid;
  grid-template-columns: var(--book-gutter) repeat(var(--cols, 1), minmax(var(--book-col), 1fr));
  min-width: min-content;
}
.book-corner { position: sticky; top: 0; left: 0; z-index: 3; background: var(--bg); border-bottom: 1px solid var(--line); }
.book-colhead {
  position: sticky; top: 0; z-index: 2;
  background: var(--surface); border-bottom: 1px solid var(--line);
  padding: 12px 12px 11px; min-width: 0;
  display: flex; align-items: center; gap: 9px;
}
.book-colhead .book-who { min-width: 0; }
.book-colhead strong { display: block; font-size: var(--fs-body); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* scoped to the role, not to every span: a bare .book-colhead span also caught
   the avatar and the name parts and outranked the compact rules below. */
.book-colhead .book-role { display: block; font-size: var(--fs-meta); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.book-times { position: sticky; left: 0; z-index: 1; background: var(--bg); }
.book-tick { height: calc(var(--slot) * 4); position: relative; border-top: 1px solid var(--line); }
.book-tick:first-child { border-top: 0; }
.book-tick span { position: absolute; top: 5px; right: 10px; font-size: var(--fs-meta); color: var(--muted); }

.book-col { position: relative; border-left: 1px solid var(--line); }
.book-slot { position: absolute; left: 0; right: 0; height: var(--slot); border: 0; padding: 0; background: none; cursor: pointer; }
.book-slot[data-hour="1"] { border-top: 1px solid var(--line); }
/* the column head already draws the line at the top of the day */
.book-col .book-slot:first-child { border-top: 0; }
.book-slot::after {
  content: "+"; position: absolute; inset: 1px 4px; border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  color: var(--muted); font-size: var(--fs-body); opacity: 0;
  background: color-mix(in srgb, var(--fg) 4%, transparent);
}
.book-slot:hover::after { opacity: 1; }

.book-card {
  position: absolute; left: 4px; right: 4px;
  top: calc(var(--top) * var(--slot)); height: calc(var(--len) * var(--slot) - 3px);
  display: flex; flex-direction: column; gap: 1px; overflow: hidden;
  width: auto; text-align: left;
  padding: 8px 10px; border-radius: 10px; cursor: pointer; font: inherit; color: var(--fg);
  background: color-mix(in srgb, var(--c, var(--muted)) var(--tint), var(--surface));
  border: 1px solid color-mix(in srgb, var(--c, var(--muted)) var(--tint-line), var(--line));
}
.book-card:hover { border-color: color-mix(in srgb, var(--c, var(--muted)) 60%, var(--line)); }
.book-card > * { flex: 0 0 auto; line-height: 1.2; }
.book-card b { font-size: var(--fs-body); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.book-card i { font-style: normal; font-size: var(--fs-meta); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.book-card .book-time { font-size: var(--fs-meta); color: var(--muted); }
.book-card .chip { align-self: flex-end; margin-top: auto; }
/* A card is only as tall as its booking: 24px per fifteen minutes. It drops a
   line and tightens its padding at each step down, and the client name is the
   last thing to go. The numbers are chosen so nothing is ever clipped, which
   tests/charlie-book.html checks by scrollHeight on every card. */
.book-card[data-tier="min"]  { padding: 2px 10px; }
.book-card[data-tier="min"] b { font-size: var(--fs-meta); }
.book-card[data-tier="mid"]  { padding: 5px 10px; }
.book-card[data-tier="tall"] { padding: 6px 10px; }
.book-card[data-status="done"] { opacity: .6; }
.book-card[data-status="no_show"] { background: var(--surface); border-style: dashed; }

.book-now { position: absolute; left: 0; right: 0; top: calc(var(--top) * var(--slot)); height: 0; z-index: 4; pointer-events: none; border-top: 1.5px solid var(--accent); }
.book-nowdot { position: absolute; left: 0; right: 6px; top: calc(var(--top) * var(--slot)); height: 0; z-index: 4; pointer-events: none; }
.book-nowdot::before { content: ""; position: absolute; right: 0; top: -3.5px; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); /* Sophie: matches the now line, stays visible on white */ /* Sophie, Sep 25 */ }

/* ---- under 640, the agenda. A page, not a squeezed grid. */
.book-agenda { flex: 1 1 auto; min-height: 0; min-width: 0; display: flex; flex-direction: column; }
.book-chips {
  display: flex; flex: 0 0 auto; gap: 6px; overflow-x: auto; scroll-snap-type: x proximity;
  padding: 2px 16px 14px; background: var(--bg);
  scrollbar-width: none;
}
.book-chips::-webkit-scrollbar { display: none; }
.book-chips .btn {
  scroll-snap-align: start; flex: 0 0 auto; min-height: 38px; padding: 0 13px;
  gap: 7px; font-size: var(--fs-meta); border-radius: 999px;
}
.book-chips .btn[aria-pressed="true"] { background: var(--select-bg); border-color: var(--select-bg); color: var(--on-select); box-shadow: none; /* Sophie, Sep 25 */ }
.book-chips .book-av { width: 22px; height: 22px; flex-basis: 22px; font-size: 10px; margin-left: -5px; }

.book-list { flex: 1 1 auto; min-height: 0; min-width: 0; overflow-y: auto; padding: 0 16px calc(env(safe-area-inset-bottom, 0px) + 104px); background: var(--surface); border-top: 1px solid var(--line); }
.book-hour { display: grid; grid-template-columns: 52px minmax(0, 1fr); gap: 0 10px; padding: 13px 0 3px; border-top: 1px solid var(--line); }
.book-hour:first-child { border-top: 0; }
.book-hourlab { font-size: var(--fs-meta); color: var(--muted); padding-top: 13px; font-variant-numeric: tabular-nums; }
.book-hourcol { display: flex; flex-direction: column; gap: 8px; min-width: 0; }

.book-item {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  padding: 12px; border-radius: var(--radius); cursor: pointer; font: inherit; color: var(--fg);
  background: color-mix(in srgb, var(--c, var(--muted)) var(--tint), var(--surface));
  border: 1px solid color-mix(in srgb, var(--c, var(--muted)) var(--tint-line), var(--line));
}
.book-itemtext { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.book-item b { font-size: var(--fs-card); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.book-item i { font-style: normal; font-size: var(--fs-meta); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.book-item .book-time { font-size: var(--fs-meta); color: var(--muted); }
.book-item[data-status="done"] { opacity: .6; }
.book-item[data-status="no_show"] { background: var(--surface); border-style: dashed; }
.book-open {
  display: flex; align-items: center; justify-content: space-between; width: 100%; text-align: left;
  padding: 11px 12px; border-radius: var(--radius); cursor: pointer; font: inherit;
  color: var(--muted); font-size: var(--fs-meta);
  background: none; border: 1px dashed var(--line);
}
.book-open:hover { color: var(--fg); border-color: color-mix(in srgb, var(--fg) 24%, var(--line)); }

.book-fab {
  position: fixed; right: 16px; z-index: 40;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 78px);
  display: inline-flex; align-items: center; gap: 8px;
  height: 56px; padding: 0 22px; border: 0; border-radius: 28px;
  background: var(--fill); color: var(--on-fill); /* Sophie, Sep 25 */
  font: inherit; font-size: var(--fs-card); font-weight: 600; cursor: pointer;
  box-shadow: var(--shadow-lift);
}
.book-fab svg { width: 20px; height: 20px; }

/* ---- week */
.book-week { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: grid; align-content: start;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px; padding: 16px; }
.book-day {
  display: flex; flex-direction: column; gap: 5px; align-items: flex-start;
  min-height: 124px; padding: 13px 14px; cursor: pointer; font: inherit; text-align: left;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); color: var(--fg);
}
.book-day:hover { border-color: color-mix(in srgb, var(--fg) 24%, var(--line)); }
.book-day small { font-size: var(--fs-chip); color: var(--muted); text-transform: uppercase; letter-spacing: .07em; font-weight: 600; }
.book-day b { font-family: var(--font-display); font-size: 26px; font-weight: 500; line-height: 1.05; }
.book-dots { display: flex; gap: 4px; margin-top: 2px; min-height: 7px; }
.book-dots i { width: 7px; height: 7px; border-radius: 50%; background: var(--c, var(--line)); }
.book-count { margin-top: auto; font-size: var(--fs-meta); color: var(--muted); }
.book-day[data-today="1"] { border-color: var(--accent); }
.book-day[data-today="1"] b { color: var(--accent); }

/* ---- the book's sheet internals */
.book-sum { font-size: var(--fs-body); color: var(--muted); }
.book-sum b { color: var(--fg); font-weight: 600; }
.book-field { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.book-two { display: grid; grid-template-columns: repeat(auto-fit, minmax(136px, 1fr)); gap: 10px; }
.book-pick { display: flex; flex-wrap: wrap; gap: 7px; }
.book-pick .btn {
  flex-direction: column; align-items: flex-start; justify-content: center; gap: 2px;
  min-height: 54px; padding: 8px 12px; font-size: var(--fs-body);
  background: color-mix(in srgb, var(--c, var(--muted)) 7%, var(--surface));
  border-color: color-mix(in srgb, var(--c, var(--muted)) 24%, var(--line));
}
.book-pick .btn small { font-size: var(--fs-meta); color: var(--muted); font-weight: 500; }
.book-pick .btn[aria-pressed="true"] {
  background: color-mix(in srgb, var(--c, var(--muted)) var(--tint), var(--surface));
  border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent);
}
.book-results { display: flex; flex-direction: column; gap: 5px; max-height: 216px; overflow-y: auto; }
.book-result { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 1px; min-height: 48px; padding: 7px 12px; text-align: left; }
.book-result small { font-size: var(--fs-meta); color: var(--muted); font-weight: 500; }

/* Compact calendar until eight 168px chairs, gutter and full rail fit. */
@media (min-width: 640px) and (max-width: 1631px) {
  /* 56, not 44: "10 am" and "12 pm" wrap onto two lines in 44. Eight chairs
     still fit, 952 minus 56 leaves exactly 112 a column, and nothing here
     locks to min-content anyway. */
  :root { --book-gutter: 56px; }
  /* Nothing locks to min-content here, so eight chairs share the pane instead
     of scrolling off it. The 168px minimum returns at 1632, once the full rail and 1400px calendar fit. */
  .book-grid { grid-template-columns: var(--book-gutter) repeat(var(--cols, 1), minmax(0, 1fr)); min-width: 100%; }
  /* avatar over a first name, centred, so a 112px column still reads */
  .book-colhead { flex-direction: column; align-items: center; gap: 5px; padding: 10px 4px; text-align: center; }
  .book-colhead .book-who { width: 100%; }
  /* first name only on the head and on the card; the role stays, a colorist
     and a stylist are not the same chair and the desk needs to see it */
  .book-colhead .book-n1, .book-card .book-c1 { display: none; }
  .book-card { padding-left: 8px; padding-right: 8px; }
  .book-card b { padding-right: 12px; }
  .book-card i, .book-card .book-t1 { display: none; }
  /* the status becomes a small tinted dot in the corner, and Booked, which is
     the resting state and carries chip-quiet, shows nothing at all */
  .book-card .chip {
    position: absolute; top: 5px; right: 5px; margin: 0;
    width: 8px; height: 8px; min-width: 0; padding: 0; border-radius: 50%;
    font-size: 0; line-height: 0; overflow: hidden;
  }
}

/* ------------------------------------------------ the phone tab bar (four)
   Ten screens do not fit a phone tab bar, so everything outside the four tabs
   is reachable from More. The rail from 768 up still lists every screen. */
@media (max-width: 767px) {
  .nav-item:not([data-tab]) { display: none; }
  /* four independent targets, each at least 64 wide and 48 tall even at 320 */
  .nav-item[data-tab] { flex: 1 1 0; min-width: 64px; min-height: 48px; }
}

/* -------------------------------------------------------------- PIN gate */
.pin, .login { flex: 1 1 auto; width: 100%; min-height: 100dvh; display: flex; align-items: center; justify-content: center; padding: 24px; background: var(--bg); }
.pin-card { width: 100%; max-width: 320px; display: flex; flex-direction: column; align-items: center; gap: 14px; }
.pin-card h1 { text-align: center; }
.pin-note { font-size: var(--fs-meta); color: var(--muted); text-align: center; min-height: 19px; }
.pin-dots { display: flex; gap: 12px; padding: 4px 0 10px; }
.pin-dot { width: 13px; height: 13px; border-radius: 50%; border: 1.5px solid var(--line); }
.pin-dot[data-on="1"] { background: var(--fill); border-color: var(--fill-line); /* Sophie, Sep 25 */ }
.pin-keys { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; width: 100%; }
.pin-key {
  min-height: 60px; border: 1px solid var(--line); border-radius: 12px;
  background: var(--surface); color: var(--fg);
  font: inherit; font-size: 22px; font-weight: 500; font-variant-numeric: tabular-nums; cursor: pointer;
}
.pin-key[data-key="clear"], .pin-key[data-key="back"] { font-size: var(--fs-meta); color: var(--muted); background: none; border-color: transparent; }
.pin-key:active { background: var(--bg); }

/* ------------------------------------------------------- the More screen */
.more { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; min-width: 0; }
.more-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 0 16px calc(env(safe-area-inset-bottom, 0px) + 24px); }
.more-group { padding: 6px 0 18px; }
.more-group .label { padding: 0 2px 8px; display: block; font-size: 11px; }
.more-row {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  padding: 12px 14px; margin-top: -1px;
  border: 1px solid var(--line); background: var(--surface); color: var(--fg);
  font: inherit; cursor: pointer; text-decoration: none;
}
.more-row:first-of-type { border-radius: var(--radius) var(--radius) 0 0; }
.more-row:last-of-type { border-radius: 0 0 var(--radius) var(--radius); }
.more-row:only-of-type { border-radius: var(--radius); }
.more-row:hover { background: color-mix(in srgb, var(--fg) 3%, var(--surface)); }
.more-static { cursor: default; }
.more-ico { display: flex; flex: 0 0 20px; color: var(--muted); }
.more-ico svg { width: 20px; height: 20px; }
.more-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.more-text b { font-size: var(--fs-body); font-weight: 600; }
.more-text i { font-style: normal; font-size: var(--fs-meta); color: var(--muted); }
.more-go { color: var(--muted); font-size: 20px; line-height: 1; }

/* -------------------------------------------------- TODAY, the owner (.td-) */
.td { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; min-width: 0; }
.td-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 0 16px calc(env(safe-area-inset-bottom, 0px) + 24px); }
@media (min-width: 768px) { .td-scroll { padding: 0 28px 28px; } }

.td-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
.td-stat {
  display: flex; flex-direction: column; gap: 3px; min-width: 0;
  padding: 14px 16px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface);
}
.td-k { font-size: var(--fs-chip); font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .07em; }
.td-stat b { font-size: 26px; font-weight: 600; letter-spacing: -.02em; line-height: 1.15; }
.td-sub { font-size: var(--fs-meta); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.td-card { margin-top: 10px; padding: 14px 16px 16px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); min-width: 0; }
.td-card h2 { font-size: var(--fs-body); font-weight: 600; padding-bottom: 10px; }
.td-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 10px; align-items: start; }
.td-cols .td-card { margin-top: 10px; }

.td-svg { width: 100%; height: auto; display: block; }
.td-bd { fill: var(--muted); font-size: 15px; font-family: var(--font); }
.td-bv { fill: var(--fg); font-size: 15px; font-weight: 600; font-family: var(--font); font-variant-numeric: tabular-nums; }

.td-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.td-list li { display: flex; align-items: center; gap: 11px; padding: 9px 0; border-top: 1px solid var(--line); min-width: 0; }
.td-list li:first-child { border-top: 0; padding-top: 0; }
.td-lt { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.td-lt b { font-size: var(--fs-body); font-weight: 600; overflow: hidden; text-overflow: ellipsis; }
.td-lt i { font-style: normal; font-size: var(--fs-meta); color: var(--muted); overflow: hidden; text-overflow: ellipsis; }
.td-when { font-size: var(--fs-body); font-weight: 600; white-space: nowrap; }
.td-attn li { align-items: center; gap: 10px; }
.td-attn .btn { min-height: 38px; padding: 0 12px; font-size: var(--fs-meta); }
.td-none { font-size: var(--fs-meta); color: var(--muted); }
.td-note { margin-top: 12px; font-size: var(--fs-meta); color: var(--muted); }
.more-credit { padding: 16px 2px 0; font-size: var(--fs-chip); color: var(--muted); }

/* ------------------------------------------------------- SETTINGS (.set-) */
.set { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; min-width: 0; }
.set-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 4px 16px calc(env(safe-area-inset-bottom, 0px) + 24px); }
@media (min-width: 768px) { .set-scroll { padding: 4px 28px 28px; } }
.set-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px; }
.set-f { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.set-hint { font-style: normal; font-size: var(--fs-meta); color: var(--muted); }
.set-rows { display: flex; flex-direction: column; gap: 10px; }
.set-row {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap; min-width: 0;
  padding: 11px 14px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface);
}
.set-day { flex: 1 1 130px; min-width: 0; font-size: var(--fs-body); font-weight: 600; }
.set-open { display: flex; align-items: center; gap: 6px; font-size: var(--fs-meta); color: var(--muted); }
.set-time { width: 116px; flex: 0 0 auto; }
.set-to { font-size: var(--fs-meta); color: var(--muted); }
.set-sm { width: 116px; flex: 0 0 auto; }
.set-staff .set-sm:last-of-type { width: 88px; font-variant-numeric: tabular-nums; }
.set-svc { padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); min-width: 0; }
.set-svcline { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.set-svcline .input:first-child { flex: 1 1 180px; width: auto; }
.set-color { width: 48px; height: 48px; padding: 2px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); cursor: pointer; }
.set-steps { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; padding-top: 11px; }
.set-steps .btn { min-height: 36px; padding: 0 11px; font-size: var(--fs-meta); }
.set-x { border: 0; background: none; color: inherit; cursor: pointer; font: inherit; font-size: 14px; line-height: 1; padding: 0 0 0 4px; }
.theme-btn.set-theme { min-width: 72px; }

/* Phase 2 live mode, Sophie: the Live mark on the rail and the sign in card */
.nav-live { display: inline-flex; align-items: center; margin-left: 8px; padding: 2px 8px; border-radius: 999px; background: var(--select-bg); color: var(--on-select); font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; }
.login .pin-card { gap: 10px; }
.login .input { width: 100%; }

/* The sign-in wordmark has its own space; the compact form and other app logos stay unchanged. */
.login.login-branded { flex-direction: column; gap: 28px; overflow-y: auto; padding-top: max(40px, env(safe-area-inset-top, 0px)); padding-bottom: max(40px, env(safe-area-inset-bottom, 0px)); }
.login-branded .login-brand { width: min(100%, 440px); height: auto; aspect-ratio: 744 / 140; flex: 0 0 auto; }
@media (max-height: 520px) {
  .login.login-branded { justify-content: flex-start; gap: 20px; }
}

/* The public booking link (?book=online), Sophie Sep 29 2026: a Glamaroo header and the salon's name over the booking steps. */
.public-booking { min-height: 100dvh; display: flex; flex-direction: column; }
.pb-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 20px; border-bottom: 1px solid var(--line); background: var(--surface); }
.pb-logo { width: 170px; height: 32px; flex: 0 0 auto; color: var(--logo); }
.pb-sub { font-size: var(--fs-meta); color: var(--muted); }
.ob-salon { font-family: var(--font-display); font-size: 24px; font-weight: 500; margin: 4px 0 12px; color: var(--fg); }
